Reputation: 41
I am working in an application which (among other things) need to read a satellite image (with only one band per image) and process the pixel data.
The format is JPEG-2000 and therefore I cannot use the PIL library (which simplifies everything). I have found the PythonMagick library and I can perfectly read the image and extract the value of the pixel. But only for one pixel!
im=PythonMagick.Image(dirimage) # (This is very slow....)
a=im.pixelColor(j-1,i-1).intensity() # the value intensity is extracted for one pixel
a=a/int(XML_var[37][2]) # the reflectance values are normalised to the range [0,1]
Therefore, I need a for-loop to get all the pixel values (the images are very large). I tried with Blob function to get the data but it crashes.
Are there any better options? How could I quickly get the pixel data of a JPEG2000 image and save it into an array?
Upvotes: 1
Views: 2503
Reputation: 412
I downloaded Kakadu (free software for non commercial purposes) and I use the module kdu_expand.
os.system('kdu_expand -i image.jp2 -o temp_image.tif')
Slight off-topic comment for those running the Kakadu (KDU) demo. Would like to add that if running kdu_expand, like above: os.system('kdu_expand -i image.jp2 -o temp_image.tif') and this gives you an error:
dyld: Library not loaded: /usr/local/lib/libkdu_v78R.dylib
Referenced from: /usr/local/bin/kdu_expand
Reason: no suitable image found. Did find:
/usr/local/lib/libkdu_v78R.dylib: open() failed with errno=13
/usr/local/lib/libkdu_v78R.dylib: open() failed with errno=13
Trace/BPT trap: 5
Check the permissions of libkdu_v78R.dylib and change them to 644 or 666, or something with read/write access.
Upvotes: 0
Reputation: 41
The answer you gave me is great and extract perfectly the pixel information (changing uint8 to uint16). However, the values I obtain are higher than the real ones. There is an offset and because of the LOSSY compression in JPEG2000 there is a little error of 1 or 2 in the value.
I don't like to use external calls but in this case I found this as a better and faster solution:
I downloaded Kakadu (free software for non commercial purposes) and I use the module kdu_expand.
os.system('kdu_expand -i image.jp2 -o temp_image.tif')
im=PIL.Image.open('temp_image.tif')
pixels=array(im.getdata()).reshape((im.size[0], im.size[1]))
I convert the image from JPEG2000 to TIF but it is quick and the static memory is not usually a limitation (nowadays) in a computer. Then, the PIL library perfectly manages to extarct the data.
Note: I tried the conversion straight with PythonMagick but it gives me the same offset as before
Note 2: I found another interesting library in OpenCV but the result is incorrect
pixels_cv2=cv2.imread('image.jp2',0)
Note3: The images I used are satellite images codified with 12 bites. Possibly in other type of data the PythonMagick behaves better.
Upvotes: 2
Reputation: 9437
Using a Blob should work:
import numpy
from PythonMagick import Image, Blob
i = Image('http://www.microimages.com/gallery/jp2/potholes2.jp2')
b = Blob()
i.write(b, 'GRAY')
a = numpy.fromstring(b.data, 'uint8').reshape((i.rows(), i.columns()))
Upvotes: 2