Accessing a webcam from pyside / opencv

2019-08-15 06:47发布

问题:

I have problems accessing a webcam in a pyside / opencv project.

This is a stripped down example that produces the problem I face:

from PySide import QtCore, QtGui
import cv, cv2, time, ImageQt

app = QtGui.QApplication([])

while True:
    camcapture = cv.CaptureFromCAM(0)
    cv.SetCaptureProperty(camcapture,cv.CV_CAP_PROP_FRAME_WIDTH, 1280)
    cv.SetCaptureProperty(camcapture,cv.CV_CAP_PROP_FRAME_HEIGHT, 720);

    frame = cv.QueryFrame(camcapture)
    image = QtGui.QImage(frame.tostring(), frame.width, frame.height, QtGui.QImage.Format_RGB888).rgbSwapped()
    pixmap = QtGui.QPixmap.fromImage(image)

app.exec_()

I see two problems here. First: aparently I see an issue using v4l2 to access the webcam which otherwise works fine from python (using other applications):

python ./test.py 
VIDIOC_QUERYMENU: Invalid argument
[... and countless more entries which don#t worry me ...]
VIDIOC_QUERYMENU: Invalid argument
libv4l2: error setting pixformat: Device or resource busy
HIGHGUI ERROR: libv4l unable to ioctl S_FMT
libv4l2: error setting pixformat: Device or resource busy
libv4l1: error setting pixformat: Device or resource busy
HIGHGUI ERROR: libv4l unable to ioctl VIDIOCSPICT

Then there is a shutdown problem that is unclear, but not my main problem right now:

*** glibc detected *** python: double free or corruption (fasttop): 0x00000000029368f0 ***
======= Backtrace: =========
/lib64/libc.so.6(+0x78b66)[0x7f3539f06b66]
/usr/lib64/tls/libnvidia-tls.so.304.64(+0x1cc1)[0x7f352e448cc1]
======= Memory map: ========
00400000-00401000 r-xp 00000000 08:02 3937950                            /usr/bin/python2.7
00600000-00601000 r--p 00000000 08:02 3937950                            /usr/bin/python2.7
00601000-00602000 rw-p 00001000 08:02 3937950                            /usr/bin/python2.7
01631000-03cd3000 rw-p 00000000 00:00 0                                  [heap]
7f351b6dc000-7f351b6dd000 rw-p 00000000 00:00 0 
7f351b6dd000-7f351b773000 rw-s 001c2000 00:05 5759                       /dev/video0
7f351b773000-7f351b809000 rw-s 0012c000 00:05 5759                       /dev/video0
[... and so on ... and so on ... ]

My question? I fail to make sense from the output. I tried many variants of the code, but usually run into the same problem. So I guess it is not a specific code detail, but some general issue with my setup or my approach. This is the environment: - Linux OS (openSUSE-12.2) on an x86-64 platform (MacBook Pro) - opencv 2.4.3 - libqt4 4.8.4 - python 2.7.3

What's wrong here? My code is like all those examples out there in all their variants. What do I miss?

回答1:

To start with, you should not have cv.CaptureFromCAM(0) inside the while loop, as that is what is causing the "resource busy" collisions and the memory dump.

You will likely need to slow down your while loop. You can implement cv2.waitKey() or use time.sleep().

After that, you will need to finish your Qt implementation. (which seems to be a separate issue.)

Here is a bare bones re-write of your example:

import cv, cv2, time, sys

camcapture = cv.CaptureFromCAM(0)
cv.SetCaptureProperty(camcapture,cv.CV_CAP_PROP_FRAME_WIDTH, 1280)
cv.SetCaptureProperty(camcapture,cv.CV_CAP_PROP_FRAME_HEIGHT, 720)

while True:
    frame = cv.QueryFrame(camcapture)
    ... GUI stuff ...
    time.sleep(.05)

Using cv2 instead:

camcapture = cv2.VideoCapture(0)
while True:
    _, frame = camcapture.read()
    ... GUI stuff ...
    time.sleep(.05)