【问题标题】:Memory leak with VideoCapture in Python OpenCVPython OpenCV 中 VideoCapture 的内存泄漏
【发布时间】:2014-03-01 19:28:55
【问题描述】:

我使用 3 个网络摄像头偶尔在 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

是什么导致了这些错误,我该如何解决?

【问题讨论】:

  • 我遇到了完全相同的问题,您发现问题所在了吗?
  • 您使用的是哪个版本的 OpenCV?已经有一段时间了,但我相信在更新 OpenCV(我认为是 2.3.1)后问题就停止了。
  • 我使用的是 2.4.12,它应该是更新的。我可以尝试更新到 3 。
  • 一种可能的解决方法是在新进程中调用另一个脚本来拍摄照片并将其保存到磁盘。然后在此处的主脚本中从磁盘加载图片。这将避免一起切换 USB,并且由于外部进程是短暂的,它们不会有内存问题的危险。
  • 可能是网络摄像头质量不好的问题

标签: python opencv memory-leaks webcam v4l2


【解决方案1】:

错误信息的相关sn-p是函数cvGetMat中的Unrecognized or unsupported array type。 cvGetMat() 函数将数组转换为 Mat。 Mat 是OpenCV 在 C/C++ 世界中使用的矩阵数据类型(注意:您正在使用的 Python OpenCV 接口使用 Numpy 数组,然后在后台将其转换为 Mat 数组)。考虑到这一背景,问题似乎是您传递给cv2.imshow() 的数组格式不正确。两个想法:

  1. 这可能是由您的网络摄像头上的古怪行为引起的... 不时返回相机空帧。在你通过之前 im 数组到imshow(),尝试确保它不为空。
  2. 如果错误发生在每一帧,那么消除一些 处理您正在做的事情并立即致电cv2.imshow() 从网络摄像头抓取相框后。如果还是不行 工作,然后您就会知道这是您的网络摄像头的问题。否则,添加 逐行备份您的处理,直到您找出问题所在。为了 例如,从这个开始:

    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;
    

来源:Related Question: OpenCV C++ Video Capture does not seem to work

【讨论】:

  • 您也可以使用 BGR-picture 来解决这个问题。我的摄像头默认是 YUYV!
  • 传递格式不正确的数组会导致无法分配内存错误和/或内存泄漏吗?这似乎是我问题的根源。
猜你喜欢
  • 2015-08-12
  • 1970-01-01
  • 1970-01-01
  • 2020-08-15
  • 1970-01-01
  • 1970-01-01
  • 2022-07-27
  • 2015-10-05
  • 1970-01-01
相关资源
最近更新 更多