![]() |
|
![]() |
|
|
Thread Tools | Display Modes |
|
|
#21 |
|
Resident Grouch
![]() ![]() ![]() ![]() ![]() ![]() Join Date: Jun 2005
Posts: 6,453
Rep Power: 10
![]() |
Just to let you know: this is abominably slow, about 5 seconds for 128x128. (I've downloaded Psyco, but not applied it, yet.) Admittedly, much of that is because of the image objects available in the Python port of wxWidgets. As mentioned earlier, there's not direct access to data on a pixel-by-pixel basis. The procedure is this:
1. For each pixel in the image (other than edge pixels, which are set to black), get a 3x3 sub image. 2. Get the data (pixels) associated with the image. These come in a string, which obviates the necessity of flattening. 3. Remove g and b components, using only the red (it's a grayscale image) 3. Convert the characters to ordinals. 4. Approximate a gradient measurement with Sobel x and y grids (which are now flat, to begin with). This includes applying a gain factor (currently 1), taking the absolute value of negative pixels, and limiting the value to 255. 5. Convert back to characters and replicate for the g and b components. 6. Construct a new wxImage using the string. The inset on the image shows the output from the old C++ version, which is essentially identical to what one gets with "Find all edges" in Paintshop Pro. I'm not sure, yet, why it's different from the new version. The processing algorithm is identical.
__________________
Abstraction doesn't make it impossible to write bad code; it makes it possible to write superior code. Contributor's Corner: Grumpy on C++ Exceptions DaWei on Pointers |
|
|
|
|
|
#22 | |
|
Programming Guru
![]() Join Date: Aug 2005
Location: England
Posts: 1,499
Rep Power: 5
![]() |
Quote:
import Image
import wx
image = Image.open("foobar.png")
width, height = image.size
wx.Image(width, height, image.tostring())I believe it also has some image filters, though I suspect using a prewritten filter wouldn't teach you much ![]() Your application looks pretty good, though. Unfortunately, I know very little about image manipulation, so I couldn't hazard a guess as to why it isn't outputting the same results as your equivalent C++ program. |
|
|
|
|
|
|
#23 |
|
Resident Grouch
![]() ![]() ![]() ![]() ![]() ![]() Join Date: Jun 2005
Posts: 6,453
Rep Power: 10
![]() |
LOL! I just downloaded PIL. First thing in the tutorial is an example, "open (lena.ppm)". Lena is quite popular in image processing circles, and is, in fact, the lady in the above illustration.
__________________
Abstraction doesn't make it impossible to write bad code; it makes it possible to write superior code. Contributor's Corner: Grumpy on C++ Exceptions DaWei on Pointers |
|
|
|
|
|
#24 |
|
Programming Guru
![]() Join Date: Apr 2005
Posts: 1,827
Rep Power: 5
![]() |
@DaWei, your intended result almost looks like it could be shifted and overlayed 1 or 2 pixel(s) to the right, and end up looking like what your application outputs.
Perhaps you missed something simple and are using your indexes incorrectly. I think some libraries also consider the first pixel the zero'eth, and some the first. Things to consider. ![]() |
|
|
|
|
|
#25 |
|
Resident Grouch
![]() ![]() ![]() ![]() ![]() ![]() Join Date: Jun 2005
Posts: 6,453
Rep Power: 10
![]() |
It hasn't anything to do with position. It's the grayscale. Examination of the histogram shows a dark shift. It's possible I normalized the old image before saving it; I haven't added that transform in this new code.
The PIL offers several advantages. There are a number of transforms/filters available that I've always written myself. It also allows me direct access to the pixels. The GetData function returns a list of numbers, rather than a string of characters, so that precludes having to make a conversion on the way in and another on the way out. I had to import ImageWin to get Windows bitmap/display capabilities. It wants an HDC, whereas wxWidgets encapsulates that as an object. Fortunately, one of the object's methods returns the HDC. As soon as I've rewritten some more code, I'll make a comment on the (subjective) timing.
__________________
Abstraction doesn't make it impossible to write bad code; it makes it possible to write superior code. Contributor's Corner: Grumpy on C++ Exceptions DaWei on Pointers |
|
|
|
|
|
#26 |
|
Resident Grouch
![]() ![]() ![]() ![]() ![]() ![]() Join Date: Jun 2005
Posts: 6,453
Rep Power: 10
![]() |
In case you're interested. Treat the times as relative, as the transform takes about 2 seconds. This is 2 to 2.5 times as fast as working with the wxWidget image (because of the lack of direct access and the conversions).
Note that the gradient calculation is about 20 to 30 percent of the time; the rest is spent in the image library functions. The gradient calculation is made using flat lists. The code is: def gradient (self, map, gain):
a = b = 0
for i in range (9):
a += self.xGrid [i] * map [i]
b += self.yGrid [i] * map [i]
n = 255 - int ((math.sqrt (a**2 + b**2) * gain))
if n < 0: n = -n
if n > 255: n = 255
return n ncalls tottime percall cumtime percall filename:lineno(function)
1 1.307 1.307 7.334 7.334 Filter.py:369(SobelEdge)
15876 1.390 0.000 1.966 0.000 Filter.py:38(gradient)
15876 0.988 0.000 2.694 0.000 PIL\Image.py:670(crop)
15880 0.616 0.000 0.773 0.000 PIL\ImageFile.py:115(load)
15876 0.602 0.000 0.934 0.000 PIL\Image.py:1546(__init__)
15876 0.509 0.000 0.990 0.000 PIL\Image.py:1563(load)
15876 0.481 0.000 0.481 0.000 :0(crop)
15876 0.374 0.000 1.364 0.000 PIL\Image.py:793(getdata)
15879 0.355 0.000 0.355 0.000 :0(range)
15895 0.333 0.000 0.333 0.000 PIL\Image.py:392(__init__)
15876 0.220 0.000 0.220 0.000 :0(sqrt)
1 1.572 1.572 8.833 8.833 Filter.py:351(SobelEdge2)
15876 1.343 0.000 1.964 0.000 Filter.py:38(gradient)
15876 1.015 0.000 2.789 0.000 PIL\Image.py:670(crop)
15880 0.656 0.000 0.805 0.000 PIL\ImageFile.py:115(load)
16384 0.648 0.000 1.069 0.000 PIL\Image.py:1161(putpixel)
15876 0.639 0.000 0.969 0.000 PIL\Image.py:1546(__init__)
15876 0.504 0.000 0.504 0.000 :0(crop)
15876 0.504 0.000 1.007 0.000 PIL\Image.py:1563(load)
15876 0.430 0.000 1.438 0.000 PIL\Image.py:793(getdata)
32275 0.335 0.000 0.335 0.000 PIL\Image.py:525(load)
15894 0.331 0.000 0.331 0.000 PIL\Image.py:392(__init__)
15879 0.318 0.000 0.318 0.000 :0(range)
15876 0.303 0.000 0.303 0.000 :0(sqrt)
16384 0.236 0.000 0.236 0.000 :0(putpixel)
1 1.691 1.691 11.567 11.567 Filter.py:332(SobelEdge3)
15876 1.562 0.000 2.268 0.000 Filter.py:38(gradient)
15876 1.035 0.000 2.978 0.000 Image.py:670(crop)
16384 0.775 0.000 2.009 0.000 ImageDraw.py:133(_getink)
16384 0.747 0.000 3.138 0.000 ImageDraw.py:226(point)
15880 0.732 0.000 0.943 0.000 ImageFile.py:115(load)
15876 0.701 0.000 1.001 0.000 Image.py:1546(__init__)
15876 0.546 0.000 0.546 0.000 :0(crop)
16390 0.524 0.000 0.923 0.000 Image.py:79(isStringType)
15876 0.488 0.000 1.490 0.000 Image.py:793(getdata)
15876 0.456 0.000 1.002 0.000 Image.py:1563(load)
15879 0.407 0.000 0.407 0.000 :0(range)
32788 0.399 0.000 0.399 0.000 :0(isinstance)
16384 0.381 0.000 0.381 0.000 :0(draw_points)
16385 0.312 0.000 0.312 0.000 :0(draw_ink)
15894 0.301 0.000 0.301 0.000 Image.py:392(__init__)
15876 0.300 0.000 0.300 0.000 :0(sqrt)
15892 0.211 0.000 0.211 0.000 Image.py:525(load)
__________________
Abstraction doesn't make it impossible to write bad code; it makes it possible to write superior code. Contributor's Corner: Grumpy on C++ Exceptions DaWei on Pointers |
|
|
|
|
|
#27 |
|
Resident Grouch
![]() ![]() ![]() ![]() ![]() ![]() Join Date: Jun 2005
Posts: 6,453
Rep Power: 10
![]() |
Heh. My own BitList class.
1 1.021 1.021 3.630 3.630 Filter.py:348(SobelEdge4)
15876 1.310 0.000 1.935 0.000 Filter.py:54(gradient)
15876 0.671 0.000 0.671 0.000 Filter.py:38(getMap)
15879 0.360 0.000 0.360 0.000 :0(range)
15876 0.265 0.000 0.265 0.000 :0(sqrt)
__________________
Abstraction doesn't make it impossible to write bad code; it makes it possible to write superior code. Contributor's Corner: Grumpy on C++ Exceptions DaWei on Pointers |
|
|
|
![]() |
| Bookmarks |
| Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
| Thread Tools | |
| Display Modes | |
|
|