我想用OpenCV(在Python中)做一些图像处理,但是我必须从PILImage
对象开始,所以不能使用cvLoadImage()
调用,因为这需要一个文件名。
这个配方(改编自http://opencv.willowgarage.com/wiki/PythonInterface)不起作用,因为cvSetData
抱怨argument 2 of type 'void *'
。有什么想法吗?
from opencv.cv import *
from PIL import Image
pi = Image.open('foo.png') # PIL image
ci = cvCreateImage(pi.size, IPL_DEPTH_8U, 1) # OpenCV image
data = pi.tostring()
cvSetData(ci, data, len(data))
我认为cvSetData
的最后一个参数也是错误的,但是我不确定它应该是什么。
您尝试适应的示例是OpenCV 2.0的新python接口。这可能是前缀和非前缀函数名之间混淆的原因(
cv.cvSetData()
与cv.SetData()
)。OpenCV 2.0现在提供了两组python绑定:
opencv.{cv,highgui,ml}
模块的python包cv.pyd
,它封装了所有OpenCV功能(包括highgui
和ml
模块)错误消息背后的原因是SWIG包装器不处理从python字符串到普通C缓冲区的转换。不过,SWIG包装器附带了
opencv.adaptors
模块,该模块旨在支持从numpy
和PIL
图像到OpenCV的转换。以下(测试过的)代码应该可以使用SWIG接口解决您原来的问题(从PIL转换为OpenCV):
然而,这并不能解决
cv.cvSetData()
函数总是失败的事实(使用当前的SWIG包装器实现)。 然后,您可以使用新样式的包装器,它允许您按预期使用cv.SetData()
函数:第三种方法是将OpenCV python接口切换到ctypes-based wrapper。它附带了用于在python字符串和C缓冲区之间显式数据转换的实用函数。快速查看google code search似乎表明这是一种工作方法。
关于
cvSetData()
函数的第三个参数,图像缓冲区的大小,但是图像步数。步骤是图像一行中的字节数,即pixel_depth * number_of_channels * image_width
。pixel_depth
参数是与一个通道关联的数据的字节大小。在您的示例中,它只是图像宽度(只有一个通道,每个像素一个字节)。有swig和新的python绑定真的很混乱。例如,在OpenCV 2.0中,cmake可以接受BUILD-SWIG-PYTHON-u支持和BUILD-NEW-PYTHON-u支持。但不管怎样,我发现了很多陷阱。
在使用“import cv”(新的python绑定)的情况下,还需要一个步骤。
RGB图像由于PIL和IplImage的序列不同,需要进行转换。这同样适用于Ipl到PIL。
但是如果你使用opencv.adapters,它已经被处理好了。如果您感兴趣,可以在adapters.py中查看详细信息。
我使用OpenCV2.1的python2.6绑定完成了这项工作:
字符串的图像旋转和反转是将RGB交换为BGR,这是OpenCV视频编码中使用的。我认为这对于从PIL转换为OpenCV的图像的任何其他使用也是必要的。
相关问题 更多 >
编程相关推荐