Изтичане на памет с 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. 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