|
From: Travis O. <oli...@ie...> - 2006-07-11 19:37:21
|
Here is a simple approach to allowing the PIL to export the array
interface.
This allows NumPy to create a suitable array from a PIL image very easily:
At the top of Image.py add the following
if sys.byteorder == 'little':
_ENDIAN = '<'
else:
_ENDIAN = '>'
_MODE_CONV = {
# official modes
"1": ('|b1', None),
"L": ('|u1', None),
"I": ('%si4' % _ENDIAN, None),
"F": ('%sf4' % _ENDIAN, None),
"P": ('|u1', None),
"RGB": ('|u1', 3),
"RGBX": ('|u1', 4),
"RGBA": ('|u1', 4),
"CMYK": ('|u1', 4),
"YCbCr": ('|u1', 4),
# Experimental modes include I;16, I;16B, RGBa, BGR;15,
# and BGR;24. Use these modes only if you know exactly
# what you're doing...
}
def _conv_type_shape(im):
shape = im.size
typ, extra = _MODE_CONV[im.mode]
if extra is None:
return shape, typ
shape += (extra,)
return shape, typ
In the Image class structure add
def __get_array_interface__(self):
new = {}
shape, typestr = _conv_type_shape(self)
new['shape'] = shape
new['typestr'] = typestr
new['data'] = self.tostring()
return new
__array_interface__ = property(__get_array_interface__, None,
doc="array interface")
With this addition you can then do
import Image, numpy
im = Image.open('lena.jpg')
a = numpy.asarray(im)
and you will get a suitable read-only array pointing to the string
produced by tostring.
This would be a nice thing to add to the PIL.
-Travis Oliphant
|
|
From: <ke...@ca...> - 2006-07-11 20:10:49
Attachments:
PILusm.cpp
|
Although I'm not really up to speed on the array interface, accessing the
pixel data in a PIL image isn't really that difficult in C/C++... the only
challenge I would see (besides tracking the channels/padding correctly...
trivial) would be getting the pointer into Python to pass it to NumPy. I've
written a few modules in C that directly modify the PIL buffer data, with
simple code such as attached (lines 186-214 show it clearly).
(This is a module that does unsharp-masking and gaussian blur on PIL
images... Fredrik is welcome to include this directly into the PIL library
if he sees fit, for which I'll gladly remove ANY licensing restrictions)
Kevin.
----- Original Message -----
From: "Travis Oliphant" <oli...@ie...>
To: <ima...@py...>
Cc: "numpy-discussion" <num...@li...>
Sent: Tuesday, July 11, 2006 9:37 PM
Subject: Re: [Image-SIG] Quicker image transfer, tobuffer?
>
> Here is a simple approach to allowing the PIL to export the array
> interface.
>
> This allows NumPy to create a suitable array from a PIL image very easily:
>
>
> At the top of Image.py add the following
>
> if sys.byteorder == 'little':
> _ENDIAN = '<'
> else:
> _ENDIAN = '>'
>
> _MODE_CONV = {
>
> # official modes
> "1": ('|b1', None),
> "L": ('|u1', None),
> "I": ('%si4' % _ENDIAN, None),
> "F": ('%sf4' % _ENDIAN, None),
> "P": ('|u1', None),
> "RGB": ('|u1', 3),
> "RGBX": ('|u1', 4),
> "RGBA": ('|u1', 4),
> "CMYK": ('|u1', 4),
> "YCbCr": ('|u1', 4),
>
> # Experimental modes include I;16, I;16B, RGBa, BGR;15,
> # and BGR;24. Use these modes only if you know exactly
> # what you're doing...
>
> }
>
> def _conv_type_shape(im):
> shape = im.size
> typ, extra = _MODE_CONV[im.mode]
> if extra is None:
> return shape, typ
> shape += (extra,)
> return shape, typ
>
>
>
> In the Image class structure add
>
> def __get_array_interface__(self):
> new = {}
> shape, typestr = _conv_type_shape(self)
> new['shape'] = shape
> new['typestr'] = typestr
> new['data'] = self.tostring()
> return new
>
> __array_interface__ = property(__get_array_interface__, None,
> doc="array interface")
>
>
>
> With this addition you can then do
>
> import Image, numpy
>
> im = Image.open('lena.jpg')
> a = numpy.asarray(im)
>
> and you will get a suitable read-only array pointing to the string
> produced by tostring.
>
>
> This would be a nice thing to add to the PIL.
>
> -Travis Oliphant
>
>
> _______________________________________________
> Image-SIG maillist - Ima...@py...
> http://mail.python.org/mailman/listinfo/image-sig
>
|
|
From: Filip W. <fi...@ft...> - 2006-07-11 21:32:13
|
Hi Travis,
this is a great example of the __array_interface__ usage.
I have spotted some problems after patching the Image.py module and
trying to display an array created from Image in matplotlib.
First issue is a minor one. There is a difference in axis order between
ndarray and PIL:
def _conv_type_shape(im):
shape = im.size[::-1]
typ, extra = _MODE_CONV[im.mode]
if extra is None:
return shape, typ
shape += (extra,)
return shape, typ
The second seems to be more complex and may be a more general. The
memory of string created by self.tostring() seems to be deallocated
before array is created (v 0.9.9.2788, win).
Everything works fine after storing the reference to data, but this
probably should be done somewhere else:
def __get_array_interface__(self):
new = {}
shape, typestr = _conv_type_shape(self)
new['shape'] = shape
new['typestr'] = typestr
new['data'] = self.tostring()
self._str_data = new['data'] # a dirty hack
return new
best,
fw
|
|
From: Travis O. <oli...@ee...> - 2006-07-11 22:02:20
|
Filip Wasilewski wrote:
>Hi Travis,
>
>this is a great example of the __array_interface__ usage.
>
>
>
>The second seems to be more complex and may be a more general. The
>memory of string created by self.tostring() seems to be deallocated
>before array is created (v 0.9.9.2788, win).
>Everything works fine after storing the reference to data, but this
>probably should be done somewhere else:
>
> def __get_array_interface__(self):
> new = {}
> shape, typestr = _conv_type_shape(self)
> new['shape'] = shape
> new['typestr'] = typestr
> new['data'] = self.tostring()
> self._str_data = new['data'] # a dirty hack
> return new
>
>
>
This is now fixed in NumPy. The problem was that when the "buffer"
interface was used a reference to the object was kept (but not the
buffer). In this case it's the reference to the buffer that is needed.
-Travis
|
|
From: Eric F. <ef...@ha...> - 2006-07-11 22:38:32
|
Andrew Straw wrote: > Actually, this has been in MPL for a while. For example, see the > image_demo3.py example. You don't need the __array_interface__ for this > bit of functionality. It's broken. The first problem is that the kw "aspect = 'preserve'" is no longer needed or supported. Removing that (as I will do in svn shortly), I get a somewhat scrambled image. Eric |
|
From: Eric F. <ef...@ha...> - 2006-07-11 22:56:04
|
Eric Firing wrote: > Andrew Straw wrote: > > >>Actually, this has been in MPL for a while. For example, see the >>image_demo3.py example. You don't need the __array_interface__ for this >>bit of functionality. > > > It's broken. > > The first problem is that the kw "aspect = 'preserve'" is no longer > needed or supported. Removing that (as I will do in svn shortly), I get > a somewhat scrambled image. Correction: I did fix the first problem, and the second problem is not at all what I thought. Instead, the examples/data/lena.jpg file in my svn mpl directory is corrupted. I have no idea why. Looking directly at the version on svn via the svn browser, I see that it is corrupted also. Eric |
|
From: John H. <jdh...@ac...> - 2006-07-11 23:05:19
|
>>>>> "Eric" == Eric Firing <ef...@ha...> writes:
Eric> Correction: I did fix the first problem, and the second
Eric> problem is not at all what I thought. Instead, the
Eric> examples/data/lena.jpg file in my svn mpl directory is
Eric> corrupted. I have no idea why. Looking directly at the
This usually happens whenever Andrew commits -- don't know why
(platform dependent new line problem, perhaps?)
peds-pc311:~/mpl> svn log | grep astraw|head
r2480 | astraw | 2006-06-15 06:33:07 -0500 (Thu, 15 Jun 2006) | 1 line
r2430 | astraw | 2006-06-06 15:12:33 -0500 (Tue, 06 Jun 2006) | 1 line
r2279 | astraw | 2006-04-10 10:35:31 -0500 (Mon, 10 Apr 2006) | 3
lines
r2180 | astraw | 2006-03-20 15:38:12 -0600 (Mon, 20 Mar 2006) | 1 line
JDH
|
|
From: Fernando P. <fpe...@gm...> - 2006-07-11 23:19:22
|
On 7/11/06, John Hunter <jdh...@ac...> wrote: > >>>>> "Eric" == Eric Firing <ef...@ha...> writes: > > Eric> Correction: I did fix the first problem, and the second > Eric> problem is not at all what I thought. Instead, the > Eric> examples/data/lena.jpg file in my svn mpl directory is > Eric> corrupted. I have no idea why. Looking directly at the > > This usually happens whenever Andrew commits -- don't know why > (platform dependent new line problem, perhaps?) Is that file tagged as binary in the repo? If it is, it should be impervious to OS-dependent EOL conventions... Cheers, f |
|
From: Andrew S. <str...@as...> - 2006-07-11 23:38:53
|
John Hunter wrote: >>>>>>"Eric" == Eric Firing <ef...@ha...> writes: >>>>>> >>>>>> > > Eric> Correction: I did fix the first problem, and the second > Eric> problem is not at all what I thought. Instead, the > Eric> examples/data/lena.jpg file in my svn mpl directory is > Eric> corrupted. I have no idea why. Looking directly at the > >This usually happens whenever Andrew commits -- don't know why >(platform dependent new line problem, perhaps?) > >peds-pc311:~/mpl> svn log | grep astraw|head >r2480 | astraw | 2006-06-15 06:33:07 -0500 (Thu, 15 Jun 2006) | 1 line >r2430 | astraw | 2006-06-06 15:12:33 -0500 (Tue, 06 Jun 2006) | 1 line >r2279 | astraw | 2006-04-10 10:35:31 -0500 (Mon, 10 Apr 2006) | 3 >lines >r2180 | astraw | 2006-03-20 15:38:12 -0600 (Mon, 20 Mar 2006) | 1 line > > > Hmm -- "usually happens"? I never noticed that. And I'm mystified as to whether the output of svn log shows that. Let me know if I play any more evil-line-ending tricks. Anyhow, I think I fixed the corrupted file issue. I changed the deleted the svn:eol-style property and added the set svn:mime-type property to image/jpg and re-uploaded lena.jpg. I suspect this may have been a victim of the cvs2svn switch, or perhaps I never checked it into cvs properly. Cheers! Andrew |
|
From: Travis O. <oli...@ee...> - 2006-07-11 22:02:05
|
Filip Wasilewski wrote:
>Hi Travis,
>
>this is a great example of the __array_interface__ usage.
>
>
>
Just to complete the example:
With the Image.py patch that adds the __array_interface__
you can do
import Image, pylab
im = Image.open('somefile.jpg')
pylab.imshow(im, origin='lower')
and get a nice picture in the matplotlib window (at least if you are
running NumPy).
-Travis
|
|
From: Andrew S. <str...@as...> - 2006-07-11 22:25:52
|
Travis Oliphant wrote:
>Filip Wasilewski wrote:
>
>
>
>>Hi Travis,
>>
>>this is a great example of the __array_interface__ usage.
>>
>>
>>
>>
>>
>
>Just to complete the example:
>
>With the Image.py patch that adds the __array_interface__
>
>you can do
>
>import Image, pylab
>
>im = Image.open('somefile.jpg')
>pylab.imshow(im, origin='lower')
>
>and get a nice picture in the matplotlib window (at least if you are
>running NumPy).
>
>
Actually, this has been in MPL for a while. For example, see the
image_demo3.py example. You don't need the __array_interface__ for this
bit of functionality.
|