PythonMagick 数据提取 JPEG2000
我正在开发一个应用程序,其中需要读取卫星图像(每张图像只有一个波段)并处理像素数据。
图像的格式是JPEG-2000,因此我不能使用PIL库(这个库能让事情变得简单很多)。我找到了一种叫PythonMagick的库,能够很好地读取图像并提取像素的值。不过,我只能提取一个像素的值!
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]
所以,我需要用一个循环来获取所有的像素值(因为图像非常大)。我尝试使用Blob函数来获取数据,但程序崩溃了。
有没有更好的方法?我该如何快速获取JPEG2000图像的像素数据并保存到一个数组中呢?
3 个回答
我下载了Kakadu(这是一个用于非商业目的的免费软件),我在使用kdu_expand这个模块。
我用的命令是:os.system('kdu_expand -i image.jp2 -o temp_image.tif')
这里有个稍微偏题的评论,给那些在运行Kakadu(KDU)演示的人。如果你像上面那样运行kdu_expand:os.system('kdu_expand -i image.jp2 -o temp_image.tif'),如果出现错误:
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
请检查libkdu_v78R.dylib的权限,并将其更改为644或666,或者其他具有读/写权限的设置。
你给我的答案很好,完美提取了像素信息(把uint8改成uint16)。不过,我得到的数值比实际值要高,有一个偏差。因为JPEG2000使用的是有损压缩,所以数值上会有1或2的小误差。
我不太喜欢使用外部调用,但在这种情况下,我发现这个方法更好也更快:
我下载了Kakadu(非商业用途可以免费使用),并使用了kdu_expand这个模块。
我用这个命令:os.system('kdu_expand -i image.jp2 -o temp_image.tif')
然后用PIL库打开生成的文件:im=PIL.Image.open('temp_image.tif')
接着,我把图像的数据提取出来,像这样:pixels=array(im.getdata()).reshape((im.size[0], im.size[1]))
我把JPEG2000格式的图像转换成了TIF格式,这个过程很快,而且现在的电脑在静态内存方面通常没有太大限制。然后,PIL库能很好地提取数据。
注意:我尝试过直接用PythonMagick进行转换,但结果和之前一样有偏差。
注意2:我还发现了OpenCV这个有趣的库,但结果不正确。
我用这个命令读取图像:pixels_cv2=cv2.imread('image.jp2',0)
注意3:我使用的图像是用12位编码的卫星图像。可能在其他类型的数据上,PythonMagick的表现会更好。
使用 Blob 应该可以正常工作:
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()))