Ark*_*ady 12 python opencv image-processing python-imaging-library
我想用OpenCV(在Python中)进行一些图像处理,但我必须从一个PIL Image
对象开始,所以我不能使用该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))
Run Code Online (Sandbox Code Playgroud)
我认为最后一个论点cvSetData
也是错误的,但我不确定它应该是什么.
您尝试适应的示例是针对OpenCV 2.0的新python接口.这可能是前缀和非前缀函数名称(cv.cvSetData()
对比cv.SetData()
)之间混淆的根源.
OpenCV 2.0现在附带两组python绑定:
opencv.{cv,highgui,ml}
模块cv.pyd
),它包装所有OpenCV的官能团(包括highgui
和ml
模块).错误消息背后的原因是SWIG包装器不处理从python字符串到普通C缓冲区的转换.但是,SWIG包装器附带opencv.adaptors
模块,该模块旨在支持OpenCV的转换numpy
和PIL
图像转换.
以下(已测试)代码应使用SWIG接口解决您的原始问题(从PIL转换为OpenCV):
# PIL to OpenCV using the SWIG wrapper
from opencv import cv, adaptors, highgui
import PIL
pil_img = PIL.Image.open(filename)
cv_img = adaptors.PIL2Ipl(pil_img)
highgui.cvNamedWindow("pil2ipl")
highgui.cvShowImage("pil2ipl", cv_img)
Run Code Online (Sandbox Code Playgroud)
但是,这并不能解决cv.cvSetData()
函数始终失败的问题(使用当前的SWIG包装器实现).然后,您可以使用新式包装器,它允许您按cv.SetData()
预期使用该功能:
# PIL to OpenCV using the new wrapper
import cv
import PIL
pil_img = PIL.Image.open(filename)
cv_img = cv.CreateImageHeader(pil_img.size, cv.IPL_DEPTH_8U, 3) # RGB image
cv.SetData(cv_img, pil_img.tostring(), pil_img.size[0]*3)
cv.NamedWindow("pil2ipl")
cv.ShowImage("pil2ipl", cv_img)
Run Code Online (Sandbox Code Playgroud)
第三种方法是将OpenCV python接口切换到基于ctypes的包装器.它带有实用程序函数,用于在python字符串和C缓冲区之间进行显式数据转换.快速查看谷歌代码搜索似乎表明这是一种工作方法.
关于cvSetData()
函数的第三个参数,图像缓冲区的大小,但图像步骤.步骤是图像的一行中的字节数,即pixel_depth * number_of_channels * image_width
.该pixel_depth
参数是在相关联的一个信道的数据的字节大小.在您的示例中,它只是图像宽度(只有一个通道,每个像素一个字节).
归档时间: |
|
查看次数: |
16782 次 |
最近记录: |