Webcam DirectShow Properties Page in Python

2019-05-24 13:11发布

问题:

I'm working on a windows Python 2.7 application that needs to communicate with many different USB webcams. I have been using OpenCV, but for some scientific webcams, the default frame rate, capture format, etc. aren't detected and I get only a blank image. An external program that can open DirectShow properties pages can fix this in my program, but I'd like to have this feature in my application.

I have tried one available Python library to do this: VideoCapture (http://videocapture.sourceforge.net/). While this opens property pages, it doesn't allow changing any device settings ("Error Connecting... This format is not currently available", but AMCAP works). I'm wondering if the underlying code is too out of date.

Playing with the C++ code in VideoCapture or videoInput (http://www.muonics.net/school/spring05/videoInput/) isn't very helpful since they both rely on old libraries spread across numerous old, specific DirectX/WindowsSDK packages. Unfortunately, I don't have the knowledge or time to start from scratch or to figure out what's wrong with VideoCapture.

Is there another already assembled Python package out there that can do this? I've been searching for a while now with little luck. I looked a little at libvlc python bindings (since VLC can access the property pages) and DirectPython, but it isn't clear to me that these have what I'm looking for.

Thanks!

回答1:

Since I've worked on this more lately, I can provide a partial answer to my own question for anyone interested:

videoInput library is included in the Direct Show implementation in OpenCV. The videoInput library can be used to open video properties page (gain, exposure, etc.), but not the video settings page (which would have capture format, image size, frame rate, etc.) since there is no code for it. Cython can be used to interface with this library in Python without too much issue.

OpenCV's Python bindings CAN be used to access the Direct Show video properties page. This requires:

  1. Using the Direct Show driver when opening the camera device, by adding the value CV_CAP_DSHOW to the index (no python constant, use value 700).
  2. Calling the window to display using the (undocumented) propID CV_CAP_PROP_SETTINGS in VideoCapture::set(int propID, ...). Again, this constant is not in the Python bindings, so use the value 37 (from highgui_c.h)

(These instructions work as of OpenCV 2.4.6, hopefully more constants will come to the Python bindings)



回答2:

I had a similar sounding problem. Basically, I accidentally fixed it by wanting to see what I captured.

cap = cv2.VideoCapture(0)
print cap.read()      #once to inialize
print cap.read()      #twice to check that it actually initialized

The first .read() returns (False, None) while the second one actually has the feed. Before I added this I would pass None to cv2.imshow('title',frame) and my program would crash.

I don't know if this solves your problem. Mine is a DinoLite USB microscope and I think I'm just accessing it through DirectX. OpenCV 2.4.8.