fromarray rotates image

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

fromarray rotates image

Cousoulis, Paul

The fromarray method is rotating the shape of arrays when converting from numpy arrays.

 

In [56]: npArray.shape

Out[56]: (650, 670)

 

In [57]: newimage = Image.fromarray(npArray)

 

In [58]: newimage.size

Out[58]: (670, 650)

 

In [59]: Image.VERSION

Out[59]: '1.1.7'

 

Thanks

Paul

======================================================================
 This electronic message transmission and any attachments are
 confidential and/or proprietary and may constitute legally privileged
 
information of Meso Scale Diagnostics, LLC. The information is
 intended for solely the use of [hidden email] ([hidden email]).
 If you are not the intended recipient, you are hereby notified that any
 disclosure, copying, distribution or the taking of any action in
 reliance of this information is strictly prohibited. You are not
 authorized to retain it in any form nor to re-transmit it, and
 you should destroy this email immediately.

 If you have received this electronic transmission in error,
 please notify us by telephone (240-631-2522) or by electronic
 mail to the sender of this email, Cousoulis, Paul ([hidden email]),
 immediately.
 =====================================================================


_______________________________________________
Image-SIG maillist  -  [hidden email]
http://mail.python.org/mailman/listinfo/image-sig
Reply | Threaded
Open this post in threaded view
|

Re: fromarray rotates image

Chris Barker
<putting the image-sig list back on the thread... >

On Tue, Jan 31, 2012 at 8:38 AM, Cousoulis, Paul
<[hidden email]> 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

[hidden email]
_______________________________________________
Image-SIG maillist  -  [hidden email]
http://mail.python.org/mailman/listinfo/image-sig
Reply | Threaded
Open this post in threaded view
|

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

Cousoulis, Paul
The second image is a 32 bit tif, so you need to use something like ImageJ or Fiji. Microsoft image viewer won't work. I think I shouldn't have to fiddle with the row/column order, but I guess  it needs to stay the way it is. Thanks for the help.

Paul

-----Original Message-----
From: Chris Barker [mailto:[hidden email]]
Sent: Tuesday, January 31, 2012 1:18 PM
To: Cousoulis, Paul; [hidden email]
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 <[hidden email]> 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

[hidden email]


======================================================================
 This electronic message transmission and any attachments are
 confidential and/or proprietary and may constitute legally privileged information of
 Meso Scale Diagnostics, LLC. The information is intended for solely
 the use of recipient (recipient).  If you are not
 the intended recipient, you are hereby notified that any
 disclosure, copying, distribution or the taking of any action in
 reliance of this information is strictly prohibited. You are not
 authorized to retain it in any form nor to re-transmit it, and
 you should destroy this email immediately.

 If you have received this electronic transmission in error,
 please notify us by telephone (240-631-2522) or by electronic
 mail to the sender of this email, Cousoulis, Paul ([hidden email]),
 immediately.
 =====================================================================


_______________________________________________
Image-SIG maillist  -  [hidden email]
http://mail.python.org/mailman/listinfo/image-sig
Reply | Threaded
Open this post in threaded view
|

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

Chris Barker
On Tue, Jan 31, 2012 at 1:15 PM, Cousoulis, Paul
<[hidden email]> 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:[hidden email]]
> Sent: Tuesday, January 31, 2012 1:18 PM
> To: Cousoulis, Paul; [hidden email]
> 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 <[hidden email]> 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
>
> [hidden email]



--

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

[hidden email]
_______________________________________________
Image-SIG maillist  -  [hidden email]
http://mail.python.org/mailman/listinfo/image-sig