[Image-SIG] [SPAM] - Re: fromarray rotates image - Email found in subject

Chris Barker chris.barker at noaa.gov
Tue Jan 31 22:54:41 CET 2012


On Tue, Jan 31, 2012 at 1:15 PM, Cousoulis, Paul
<pcousoulis at meso-scale.com> wrote:
> The second image is a 32 bit tif, so you need to use something like ImageJ or Fiji.

not in the code you sent -- it was just garbage, but that wasn't the
issue you were testing here.

> Microsoft image viewer won't work.

Why in the world would I even try that?  ;-)

> I think I shouldn't have to fiddle with the row/column order,

If you use the same method to convert to/from numpy, then you don't
need to fiddle with it. You only needed to fiddle if you used one
method to go one way, and a different method to go the other.

> but I guess  it needs to stay the way it is.

I do agree that it's  not ideal like this, but not bad, once you expect it.

-Chris


 Thanks for the help.
>
> Paul
>
> -----Original Message-----
> From: Chris Barker [mailto:chris.barker at noaa.gov]
> Sent: Tuesday, January 31, 2012 1:18 PM
> To: Cousoulis, Paul; image-sig at python.org
> Subject: [SPAM] - Re: [Image-SIG] fromarray rotates image - Email found in subject
>
> <putting the image-sig list back on the thread... >
>
> On Tue, Jan 31, 2012 at 8:38 AM, Cousoulis, Paul <pcousoulis at meso-scale.com> wrote:
>> I'm sorry but I still think there is a bug.
>
> I still don't think so: explanation below.
>
> By the way, there is another problem with your example -- I get an all-black second image. I think you need to specify the image mode when you create the new image:
>
> newimage = Image.fromarray(npArray, mode=image1.mode)
>
> though that still makes a mess of it! -- more debugging to be done here -- see below
>
>> In [4]: print image1.size
>> (516, 356)
>>
>> In [5]: npArray = np.array(image1.getdata())
>>
>> In [6]: print npArray.shape
>> (183696L,)
>
> OK so far
>
>
>> In [7]: npArray.shape = image1.size
>
>> In [8]: print npArray.shape
>> (516L, 356L)
>
> here I would swap -- as numpy naturally stores data the other way:
>
> and now it works:
>
> In [8]: run pil-numpy-test.py
> <PIL.TiffImagePlugin.TiffImageFile image mode=L size=516x356 at 0x3A86468> input image size: (516, 356) numpy image shape before: (183696,) numpy image shape after: (356, 516) <PIL.Image.Image image mode=L size=516x356 at 0x176C1E8> new image size (516, 356)
>
> (though the colors are still screwed up -- I don't know what's up with that...)
>
> I can see how you'd expect it to work the way you had it, but I think the problem is that you are mixing two ways to push raw data to/froim numpy arrays:
>
> npArray = np.array(image1.getdata())
>
> is using PIL's getdata() to put the raw data in a string, then turning that into a numpy array (oh, and that may be the source of teh data mess up too...np.array is expecting a sequence of numbers or something, not raw data -- you want:
>
> OOPS, actually, getdata returns something else altogether:
>
> """
> getdata
>
> im.getdata() => sequence
>
> Returns the contents of an image as a sequence object containing pixel values. The sequence object is flattened, so that values for line one follow directly after the values of line zero, and so on.
>
> Note that the sequence object returned by this method is an internal PIL data type, which only supports certain sequence operations, including iteration and basic sequence access. To convert it to an ordinary sequence (e.g. for printing), use list(im.getdata()).
> """
> so it should be:
>
> npArray = np.fromstring(image1.tostring(), dtype=np.uint8)
>
> npArray.shape = (image1.size[1], image1.size[0] )
>
> and that now works -- correct size, and correct final image.
>
> However:
>
> newimage = Image.fromarray(npArray)
>
> is using the numpy "array protocol", which is a bit different than fromstring/tostring -- it carries shape information -- hence the need to specify the shape of the numpy array as I did.
>
> you can use that protocol both ways:
>
> npArray = np.asarray(image1)
>
> which then preserved size info.
>
> Here's my new version:
>
> from PIL import Image
> import numpy as np
>
>
> image1 = Image.open("LineGraph.tif")
> print image1
> print "input image size:", image1.size
>
> npArray = np.asarray(image1)
>
> print "numpy image shape after:", npArray.shape
>
> newimage = Image.fromarray(npArray, mode=image1.mode)
>
> print newimage
> print "new image size", newimage.size
>
> newimage.save("LineGraph2.tif")
>
>
> NOTE: if you do fromstring/tostring (or tobuffer) consistently, then it doesn't matter what shape you make the numpy array:
>
>
> image1 = Image.open("LineGraph.tif")
> print image1
> print "input image size:", image1.size
>
> npArray = np.fromstring(image1.tostring(), dtype=np.uint8)
>
> print "numpy image shape:", npArray.shape
>
> newimage = Image.fromstring(image1.mode, image1.size, npArray.tostring())
>
> print newimage
> print "new image size", newimage.size
>
> newimage.save("LineGraph2.tif")
>
> But that's less efficient, and messier.
>
> NOTE: it might have been nicer if the array protocol were used such that the array created was fortran-order, and thus (w,h) in shape, but so it goes.
>
> HTH,
>
>   -Chris
>
>
>
>
> --
>
> Christopher Barker, Ph.D.
> Oceanographer
>
> Emergency Response Division
> NOAA/NOS/OR&R            (206) 526-6959   voice
> 7600 Sand Point Way NE   (206) 526-6329   fax Seattle, WA  98115       (206) 526-6317   main reception
>
> Chris.Barker at noaa.gov



-- 

Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R            (206) 526-6959   voice
7600 Sand Point Way NE   (206) 526-6329   fax
Seattle, WA  98115       (206) 526-6317   main reception

Chris.Barker at noaa.gov


More information about the Image-SIG mailing list