Hi,
I am just starting with numpy, pyhton and related others. I work on image processing basically. Now, my question is: what is the expected behaviour when slicing a view of an array? The following example might give some background on what I tried to do and the results obatined (which I don't understand):
I read an image with PIL but, for whatever reason (different conventions I suppose), it comes upside down. This doesn't change when (I don't know the exact term for this) transforming the image to ndarray with 'array(img)'. I don't feel comfortable working with upside down images, so this had to be fixed. I tried to be smart and avoid copying the whole image:
aimg = array(img)[::-1]
and it worked!, but I am interested actually in sub-regions of this image, so the next I did was:
roi = aimg[10:20,45:50,:]
And to my surprise the result was like if I was slicing the original, upside down, image instead of aimg. Can someone explain me what's going on here? I searched and looked at the documentation but I couldn't find an answer. Maybe I am not looking properly. Is the only way to turn the image to perform a copy?
Thanks,
Jorge
Hi Jorge,
roi = aimg[10:20,45:50,:]
are you working with 3-D images? I didn't know PIL was able to handle 3D images.
I wasn't able to reproduce the behavior you observed with a simple example: In [20]: base = np.arange(25).reshape((5,5))
In [21]: base Out[21]: array([[ 0, 1, 2, 3, 4], [ 5, 6, 7, 8, 9], [10, 11, 12, 13, 14], [15, 16, 17, 18, 19], [20, 21, 22, 23, 24]])
In [22]: flip = base[::-1]
In [23]: flip Out[23]: array([[20, 21, 22, 23, 24], [15, 16, 17, 18, 19], [10, 11, 12, 13, 14], [ 5, 6, 7, 8, 9], [ 0, 1, 2, 3, 4]])
In [24]: flip[2:4,2:4] Out[24]: array([[12, 13], [ 7, 8]]) which is what you expect...
I also tried the same manipulations as you do starting from a PIL image object, but I also got what I expected (and my image was not flipped vertically by PIL or when transformed into an array). It is quite weird BTW that your images are flipped. How do you visualize PIL image (Image.Image.show?)and arrays (pylab.imshow?) ?
Hope someone can help you more than I did :D
Cheers,
Emmanuelle
On Sat, May 16, 2009 at 08:42:50AM +0000, jorgesmbox-ml@yahoo.es wrote:
Hi,
I am just starting with numpy, pyhton and related others. I work on image processing basically. Now, my question is: what is the expected behaviour when slicing a view of an array? The following example might give some background on what I tried to do and the results obatined (which I don't understand):
I read an image with PIL but, for whatever reason (different conventions I suppose), it comes upside down. This doesn't change when (I don't know the exact term for this) transforming the image to ndarray with 'array(img)'. I don't feel comfortable working with upside down images, so this had to be fixed. I tried to be smart and avoid copying the whole image:
aimg = array(img)[::-1]
and it worked!, but I am interested actually in sub-regions of this image, so the next I did was:
roi = aimg[10:20,45:50,:]
And to my surprise the result was like if I was slicing the original, upside down, image instead of aimg. Can someone explain me what's going on here? I searched and looked at the documentation but I couldn't find an answer. Maybe I am not looking properly. Is the only way to turn the image to perform a copy?
Thanks,
Jorge
Numpy-discussion mailing list Numpy-discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
Emmanuelle Gouillart <emmanuelle.gouillart <at> normalesup.org> writes:
Hi Jorge,
roi = aimg[10:20,45:50,:]
are you working with 3-D images? I didn't know PIL was able to handle 3D images.
Well, if by 3D you mean color images then yes, PIL is able to handle them
I wasn't able to reproduce the behavior you observed with a simple example: In [20]: base = np.arange(25).reshape((5,5))
In [21]: base Out[21]: array([[ 0, 1, 2, 3, 4], [ 5, 6, 7, 8, 9], [10, 11, 12, 13, 14], [15, 16, 17, 18, 19], [20, 21, 22, 23, 24]])
In [22]: flip = base[::-1]
In [23]: flip Out[23]: array([[20, 21, 22, 23, 24], [15, 16, 17, 18, 19], [10, 11, 12, 13, 14], [ 5, 6, 7, 8, 9], [ 0, 1, 2, 3, 4]])
In [24]: flip[2:4,2:4] Out[24]: array([[12, 13], [ 7, 8]]) which is what you expect...
You're right. I should have done these tests myself. I apologize for jumping to the list so quickly.
I also tried the same manipulations as you do starting from a PIL image object, but I also got what I expected (and my image was not flipped vertically by PIL or when transformed into an array). It is quite weird BTW that your images are flipped. How do you visualize PIL image (Image.Image.show?)and arrays (pylab.imshow?) ?
It is weird indeed. But no so much that they appear upside down (I do use pylab.imshow() to display images), because at the end of the day it is just a convention, and different things can use different conventions, but because of the fact that the numpy array obtained from the PIL image is not.
I downloaded the scipy logo: http://docs.scipy.org/doc/_static/scipyshiny_small.png and did the following:
img = Image.open('./scipyshiny_small.png')
mpl.pylab.imshow(img) # Comes upside down
aimg = asarray(img)
mpl.pylab.imshow(aimg) # Comes OK
I guess my problem lies with PIL rather than with numpy. I am glad to find that slicing works as I would have expected it to work!
Hope someone can help you more than I did :D
You did help, thanks!
Jorge
Sat, 16 May 2009 22:05:16 +0000, Jorge Scandaliaris wrote: [clip]
I downloaded the scipy logo: http://docs.scipy.org/doc/_static/scipyshiny_small.png and did the following:
img = Image.open('./scipyshiny_small.png')
mpl.pylab.imshow(img) # Comes upside down aimg = asarray(img) mpl.pylab.imshow(aimg) # Comes OK
Ah, that was it. Apparently, matplotlib imshow uses a different conversion mechanism if the input is a Image.Image from PIL, than if it is an array. There's a dedicated function matplotlib.image.pil_to_array which seems to work differently from asarray.
This may actually be a bug in matplotlib; perhaps you should ask the people on the matplotlib lists if this is really the intended behavior.
Sat, 16 May 2009 08:42:50 +0000, jorgesmbox-ml wrote: [clip]
I don't feel comfortable working with upside down images, so this had to be fixed. I tried to be smart and avoid copying the whole image:
aimg = array(img)[::-1]
Note that here a copy is made. You can use `asarray` instead of `array` if you want to avoid making a copy.
and it worked!, but I am interested actually in sub-regions of this image, so the next I did was:
roi = aimg[10:20,45:50,:]
And to my surprise the result was like if I was slicing the original, upside down, image instead of aimg. Can someone explain me what's going on here?
Sounds impossible, and I don't see this:
In [1]: import Image In [2]: img = Image.open('foo.png') In [3]: aimg = array(img) In [4]: imshow(aimg) Out[4]: <matplotlib.image.AxesImage object at 0x9a6ecec> In [5]: imshow(aimg[10:320,5:150]) Out[5]: <matplotlib.image.AxesImage object at 0x9f1db2c>
The image is here right-side up, both in full and the slice (since imshow flips it). Also,
In [6]: aimg = array(img)[::-1] In [7]: imshow(aimg[10:320,5:150]) Out[7]: <matplotlib.image.AxesImage object at 0xa007eac>
Now, the image is upside down, both in full and in the slice.
I think you should re-check that you are doing what you think you are doing. Preparing a self-contained code example could help here, at least this would make pinpointing where the error is more easy.
Pauli Virtanen <pav <at> iki.fi> writes:
<snip>
img = array(img)[::-1]
Note that here a copy is made. You can use `asarray` instead of `array` if you want to avoid making a copy.
Thanks, that's good info!
and it worked!, but I am interested actually in sub-regions of this image, so the next I did was:
roi = aimg[10:20,45:50,:]
And to my surprise the result was like if I was slicing the original, upside down, image instead of aimg. Can someone explain me what's going on here?
Sounds impossible, and I don't see this:
In [1]: import Image In [2]: img = Image.open('foo.png') In [3]: aimg = array(img) In [4]: imshow(aimg) Out[4]: <matplotlib.image.AxesImage object at 0x9a6ecec> In [5]: imshow(aimg[10:320,5:150]) Out[5]: <matplotlib.image.AxesImage object at 0x9f1db2c>
The image is here right-side up, both in full and the slice (since imshow flips it). Also,
In [6]: aimg = array(img)[::-1] In [7]: imshow(aimg[10:320,5:150]) Out[7]: <matplotlib.image.AxesImage object at 0xa007eac>
Now, the image is upside down, both in full and in the slice.
I think you should re-check that you are doing what you think you are doing. Preparing a self-contained code example could help here, at least this would make pinpointing where the error is more easy.
You're right. I was using imshow to see img (the IPL iamge, not the numpy array), and that comes upside down, at least here. That made me think the numpy array was upside down too when in fact it wasn't, so my 'fix' actually was flipping it. I'll further investigate as why the IPL image appears upside down, but my questions about slicing are answered now. Sorry for mixing things up, and thanks for helping out.
Jorge
the reason for all this is that the bitmap image format specifies the image origin as the lower left corner. This is the convention used by PIL. The origin of a numpy array is the upper right corner. Matplot lib does not handle this discrepancy in the function pil_to_array, which is called internally when you invoke imshow(img) on a PIL image. Recently, PIL has implemented the array interface for PIL images. So if you call asarray(img) on a PIL image, you will get a (height, width, 3) array (for RGB) with the origin in the upper left corner. This is why the image appears right side up in matplotlib doing things this way.
The matplot lib code should probably be updated to make use of the array interface. It just reshapes the raw string data currently.
Chris
On Sat, May 16, 2009 at 6:42 PM, Jorge Scandaliaris jorgesmbox-ml@yahoo.eswrote:
Pauli Virtanen <pav <at> iki.fi> writes:
<snip> > > img = array(img)[::-1] > > Note that here a copy is made. You can use `asarray` instead of `array` > if you want to avoid making a copy. >
Thanks, that's good info!
and it worked!, but I am interested actually in sub-regions of this image, so the next I did was:
roi = aimg[10:20,45:50,:]
And to my surprise the result was like if I was slicing the original, upside down, image instead of aimg. Can someone explain me what's going on here?
Sounds impossible, and I don't see this:
In [1]: import Image In [2]: img = Image.open('foo.png') In [3]: aimg = array(img) In [4]: imshow(aimg) Out[4]: <matplotlib.image.AxesImage object at 0x9a6ecec> In [5]: imshow(aimg[10:320,5:150]) Out[5]: <matplotlib.image.AxesImage object at 0x9f1db2c>
The image is here right-side up, both in full and the slice (since imshow flips it). Also,
In [6]: aimg = array(img)[::-1] In [7]: imshow(aimg[10:320,5:150]) Out[7]: <matplotlib.image.AxesImage object at 0xa007eac>
Now, the image is upside down, both in full and in the slice.
I think you should re-check that you are doing what you think you are doing. Preparing a self-contained code example could help here, at least this would make pinpointing where the error is more easy.
You're right. I was using imshow to see img (the IPL iamge, not the numpy array), and that comes upside down, at least here. That made me think the numpy array was upside down too when in fact it wasn't, so my 'fix' actually was flipping it. I'll further investigate as why the IPL image appears upside down, but my questions about slicing are answered now. Sorry for mixing things up, and thanks for helping out.
Jorge
Numpy-discussion mailing list Numpy-discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion