Python/OpenCV:将捕获的图像转换为其他格式

3 投票
2 回答
11658 浏览
提问于 2025-04-15 16:26

我正在尝试把从摄像头拍的图片转换成其他格式,并用OpenCV对它们进行处理,但遇到了一些困难。

当我试图把图片转换成灰度图时,程序就崩溃了。(Python.exe停止工作)

这是我代码的主要部分:

newFrameImageGS = cv.CreateImage ((320, 240), cv.IPL_DEPTH_8U, 1)

for i in range(0,5):
    newFrameImage = cv.QueryFrame(ps3eye)
    cv.CvtColor(newFrameImage,newFrameImageGS,cv.CV_BGR2GRAY)
    golfSwing.append(newFrameImageGS)

我用cvConvertScale的时候,出现了一个断言错误:

src.size() == dst.size() && src.channels() == dst.channels()

这个错误是有道理的,但我对如何把摄像头输入的图片转换成可以被像cvUpdateMotionHistory()和cvCalcOpticalFlowLK()这样的函数使用的格式感到很困惑。

有没有什么建议?谢谢。

更新:

我手动把图片转换成灰度图,使用了这个方法:

for row in range(0,newFrameImage.height):
            for col in range(0,newFrameImage.width):
                newFrameImageGS[row,col] = (newFrameImage8U[row,col][0] * 0.114 + # B
                                            newFrameImage8U[row,col][1] * 0.587 + # G
                                            newFrameImage8U[row,col][2] * 0.299)  # R

但是这个过程花了很长时间……而且我还是搞不清楚为什么cvCvtColor会导致程序崩溃。

2 个回答

1

这里有一个常见的错误:

你在循环之前就创建了一个单独的图像,保存在 newFrameImageGS 这个变量里,然后在循环中不断覆盖它的内容,最后把它添加到一个列表里。这样做的结果可能和你预期的不一样。最终这个列表里会有五个指向同一个图像的引用,因为你只是把对象的引用添加到列表里,并没有复制这个对象。这样的话,列表里的图像只会包含最后一帧的内容,所以你得到的结果是五个相同的帧,这可能不是你想要的。如果你不太明白,可以看看Python的教程。你可以通过把上面代码的第一行移动到for循环的内部来解决这个问题。

如果修复上面的错误仍然没有帮助,还有其他可能性:

CvtColor 函数似乎是正确的选择,用于转换为灰度图像,因为它可以转换成不同数量的通道。

根据这个手册CvtColor 函数需要一个与源图像数据类型相同的目标图像。请仔细检查一下 newFrameImage 是否是 IPL_DEPTH_8U 类型的图像。

4

出于某种原因,当图像的深度是8位时,CvtColor这个函数让程序崩溃了。但是当我把它们转换成32位后,程序就不再崩溃了,一切看起来都正常。我也不知道为什么会这样,但至少现在可以用了。

newFrameImage = cv.QueryFrame(ps3eye)

newFrameImage32F = cv.CreateImage((320, 240), cv.IPL_DEPTH_32F, 3)
cv.ConvertScale(newFrameImage,newFrameImage32F)

newFrameImageGS_32F = cv.CreateImage ((320,240), cv.IPL_DEPTH_32F, 1)
cv.CvtColor(newFrameImage32F,newFrameImageGS_32F,cv.CV_RGB2GRAY)

newFrameImageGS = cv.CreateImage ((320,240), cv.IPL_DEPTH_8U, 1)
cv.ConvertScale(newFrameImageGS_32F,newFrameImageGS)

撰写回答