Утечка памяти с помощью VideoCapture в Python OpenCV

Я использую 3 веб-камеры, чтобы иногда делать снимки в OpenCV. Они подключены к одной и той же шине USB, что не позволяет использовать все 3 соединения одновременно из-за ограничений пропускной способности USB (уменьшение разрешения позволяет использовать не более 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

Что вызывает эти ошибки и как их исправить?


person RemiX    schedule 05.02.2014    source источник
comment
У меня точно такая же проблема. Вы обнаружили, в чем проблема?   -  person bakalolo    schedule 08.02.2017
comment
Какую версию OpenCV вы используете? Прошло некоторое время, но я считаю, что проблема перестала возникать после обновления OpenCV (я думаю, что это было 2.3.1).   -  person RemiX    schedule 09.02.2017
comment
Я использую версию 2.4.12, которая должна быть более поздней. Я мог бы попробовать обновить до 3.   -  person bakalolo    schedule 10.02.2017
comment
Возможным решением будет вызов другого сценария в новом процессе, чтобы сделать снимок и сохранить его на диск. Затем загрузите изображение с диска в свой основной скрипт здесь. Это позволит избежать одновременного переключения USB, а поскольку внешние процессы недолговечны, им не грозит проблема с памятью.   -  person Jon    schedule 10.02.2017
comment
может быть проблема в плохом качестве веб-камеры   -  person bob marti    schedule 13.02.2017


Ответы (1)


Соответствующий фрагмент сообщения об ошибке - Нераспознанный или неподдерживаемый тип массива в функции cvGetMat. Функция cvGetMat() преобразует массивы в мат. Mat - это матричный тип данных, который OpenCV использует в мире C / C ++ (Примечание: используемый вами интерфейс Python OpenCV использует массивы Numpy, которые затем незаметно конвертируются в массивы Mat). Учитывая это, проблема, похоже, в том, что массив im, который вы передаете 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;
    

источник: Связанный вопрос: OpenCV C ++ Video Capture не работает

person bob marti    schedule 13.02.2017
comment
Вы также можете решить эту проблему, используя BGR-картинку. тот, что с моей камеры, по умолчанию был YUYV! - person bob marti; 13.02.2017
comment
Может ли передача плохо сформированных массивов вызвать ошибку выделения памяти и / или утечку памяти? Кажется, это корень моей проблемы. - person bakalolo; 15.02.2017