Python OpenCV中使用VideoCapture时的内存泄漏问题

14

我在OpenCV中使用三个网络摄像头偶尔拍摄快照。它们连接到同一个USB总线上,由于USB带宽限制不允许同时连接所有3个(降低分辨率最多可以允许2个同时连接,而我没有更多的USB总线)。

因此,每次我想要拍摄快照时,我必须切换网络摄像头连接,但这会导致在大约40次切换后出现内存泄漏。

这是我收到的错误:

libv4l2: error allocating conversion buffer
mmap: Cannot allocate memory
munmap: Invalid argument
munmap: Invalid argument
munmap: Invalid argument
munmap: Invalid argument

Unable to stop the stream.: Bad file descriptor
munmap: Invalid argument
munmap: Invalid argument
munmap: Invalid argument
munmap: Invalid argument
libv4l1: error allocating v4l1 buffer: Cannot allocate memory
HIGHGUI ERROR: V4L: Mapping Memmory from video source error: Invalid argument
HIGHGUI ERROR: V4L: Initial Capture Error: Unable to load initial memory buffers.
OpenCV Error: Bad flag (parameter or structure field) (Unrecognized or 
unsupported array type) in cvGetMat, file 
/build/buildd/opencv-2.3.1/modules/core/src/array.cpp, line 2482

Traceback (most recent call last):
File "/home/irobot/project/test.py", line 7, in <module>
cv2.imshow('cam', img)
cv2.error: /build/buildd/opencv-2.3.1/modules/core/src/array.cpp:2482: 
error: (-206) Unrecognized or unsupported array type in function cvGetMat

这是一个简单的代码片段,会生成以下错误:

import cv2

for i in range(0,100):
    print i
    cam = cv2.VideoCapture(0)
    success, img = cam.read()
    cv2.imshow('cam', img)
    del(cam)
    if cv2.waitKey(5) > -1:
        break

cv2.destroyAllWindows()

或许值得一提的是,每次连接相机时我都会收到VIDIOC_QUERYMENU: Invalid argument错误消息,但我仍然可以使用它。

额外提供一些信息,这是我使用v4l2-ctl -V命令获取的网络摄像头输出:

~$ v4l2-ctl -V
Format Video Capture:
Width/Height  : 640/480
Pixel Format  : 'YUYV'
Field         : None
Bytes per Line: 1280
Size Image    : 614400
Colorspace    : SRGB

这些错误是由什么引起的,我该如何修复它们?


我遇到了完全相同的问题,你找到问题所在了吗? - Lightsout
你使用的OpenCV版本是哪个?虽然已经有一段时间了,但我相信在更新OpenCV之后(我想是2.3.1),问题停止出现了。 - RemiX
我正在使用2.4.12,这应该是更加最新的版本。我可以尝试更新到3。 - Lightsout
一个可能的解决方法是调用另一个脚本,在新进程中拍照并将其保存到磁盘中。然后在主脚本中从磁盘加载图片。这将完全避免USB切换,并且由于外部进程的生命周期很短,它们不会有内存问题的危险。 - Jon
可能是摄像头质量不好的问题。 - bob marti
1个回答

1
错误信息中的相关片段是“在函数cvGetMat中,未识别或不支持的数组类型”。cvGetMat()函数将数组转换为Mat。Mat是OpenCV在C/C++世界中使用的矩阵数据类型(注意:您正在使用Python OpenCV接口,它使用Numpy数组,这些数组在背后被转换为Mat数组)。考虑到这一点,问题似乎在于您传递给cv2.imshow()的im数组格式不正确。两个想法:
  1. This could be caused by quirky behaviour on your webcam... on some cameras null frames are returned from time to time. Before you pass the im array to imshow(), try ensuring that it is not null.
  2. If the error occurs on every frame, then eliminate some of the processing that you are doing and call cv2.imshow() immediately after you grab the frame from the webcam. If that still doesn't work, then you'll know it's a problem with your webcam. Else, add back your processing line by line until you isolate the problem. For example, start with this:

    while True:
    
    
    # Grab frame from webcam
    retVal, image = capture.read(); # note: ignore retVal
    
    #   faces = cascade.detectMultiScale(image, scaleFactor=1.2, minNeighbors=2, minSize=(100,100),flags=cv.CV_HAAR_DO_CANNY_PRUNING);
    
    # Draw rectangles on image, and then show it
    #   for (x,y,w,h) in faces:
    #       cv2.rectangle(image, (x,y), (x+w,y+h), 255)
    cv2.imshow("Video", image)
    
    i += 1;
    

来源: 相关问题:OpenCV C++视频捕获似乎无法正常工作


你也可以通过使用BGR图片来解决这个问题。我的摄像头默认是YUYV格式的! - bob marti
传递格式不正确的数组会导致“无法分配内存”错误和/或内存泄漏吗?这似乎是我的问题的根源。 - Lightsout

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接