如何在Python中将字节字符串转换为OpenCV的IplImage?

3 投票
2 回答
1752 浏览
提问于 2025-04-15 23:32

我正在从一个网络摄像头获取一些数据。当我获取到一整幅图像的所有字节(保存在一个叫做 byteString 的字符串里)时,我想用 OpenCV 显示这幅图像。如果速度快的话,这样就能把摄像头的视频“流”到 OpenCV 窗口里。

这是我设置窗口的代码:

cvNamedWindow('窗口名称', CV_WINDOW_AUTOSIZE)

当字节字符串完成后,我会这样处理:

img = cvCreateImage(IMG_SIZE,PIXEL_DEPTH,CHANNELS)
buf = ctypes.create_string_buffer(byteString)
img.imageData = ctypes.cast(buf, ctypes.POINTER(ctypes.c_byte))
cvShowImage('窗口名称', img)
cvWaitKey(0)

但出了一些问题,出现了错误:

文件 "C:\Python26\lib\site-packages\ctypes_opencv\highgui_win32.py",第 226 行,执行时出错
return func(*args, **kwargs)

WindowsError: exception: access violation reading 0x015399E8

有没有人知道我在做的事情怎么解决,或者怎么修复这个奇怪的访问错误?

2 个回答

0

Tyler:

我不太确定你想做什么,不过我有几个猜测。

如果你只是想从连接到电脑的摄像头读取一张图片,那么这段代码应该能帮到你:

import cv

cv.NamedWindow("camera", 1)

capture = cv.CaptureFromCAM(0)

while True:
    img = cv.QueryFrame(capture)
    cv.ShowImage("camera", img)
    if cv.WaitKey(10) == 27:
        break

你是想从网络摄像头直播视频吗?如果是的话,你可以看看这个帖子:

opencv-with-network-cameras

如果因为某种原因你无法用这些方法做到,那么你可以尝试把图片保存到硬盘上,然后在你的opencv程序中用简单的cvLoadImage加载它(不过这种方法会慢很多)。

另一种方法是手动设置新图片的像素,通过读取每个值的字节字符串,像这样:

for(int x=0;x<640;x++){
                for(int y=0;y<480;y++){
                        uchar * pixelxy=&((uchar*) (img->imageData+img->widthStep*y))[x];
                        *pixelxy=buf[y*img->widthStep + x]; 
                }
        }

这种方法也比较慢,但比使用硬盘要快。无论如何,希望这些能帮到你,你还应该说明你使用的是哪个版本的opencv。

2

我其实已经解决了这个问题,只是忘了分享解决方案。下面是我怎么做的,虽然可能不是最完美的方法:

我分析了来自网络摄像头的MJPEG数据的头部信息,然后我就开始从数据流中一字节一字节地读取。当我发现下一个图像的头部信息也在这些字节中时,我就把最后的42个字节去掉(因为头部的长度就是42个字节)。

这样我就得到了JPEG的字节数据,然后我用open(...)方法创建了一个新的Cv图像,并把字节数据放在一个StringIO类中传给它。

撰写回答