Reputation: 14379
I have a webcam that is capable of 1080p 30fps which I have confirmed by using VirtualDub to preview and save a video from the webcam itself.
For some reason OpenCV will only give me around 4FPS, the CPU isn't maxing out any of the cores so I can't see why? (This is without actually outputting the feed by the way, just fetching the frames).
Does anyone with experience of OpenCV know why? Could it be that OpenCV is not using DirectShow to read from the webcam (assuming DirectShow is what you need for 30fps/1080p - i believe that's what virtualdub uses). Could the fact that OpenCV reads the image into its on proprietary datatype Mat
be the bottleneck?
My camera is the Microsoft LifeCam Studio and my OS is Windows 7 with Visual Studios 2010.
Does anyone have any ideas?
Upvotes: 4
Views: 5329
Reputation: 1921
As Roman pointed out, the default mode for most webcams is MJPEG-compression, in order to reduce the data rate that needs to go over the USB connection (and possibly USB hubs etc.) and/or maximize the available frame rate / resolution.
For computer vision, this is often undesirable, since we would rather prefer to have a lower frame rate, but no compression artifacts. Indeed, it is possible in general to change the stream format (e.g. to uncompressed YUV) in much the same manner in which e.g. the resolution is changed. Whether that is actually possible for you depends on
Unfortunately, the answer for the latter is simply none. OpenCV has 18(!) different capturing backends (for various platforms, e.g. mobile phones, OS X, Windows and Linux, often several ones for different versions of underlying frameworks), and although there seems to be an API for changing the stream format [1], it does not seem to be implemented by any backend. :-(
In case you or anybody else wants to work on this, you may want to check the OpenCV issue I opened about this: http://code.opencv.org/issues/3007
In my case, I investigated this for some Logitech webcams, which even had different capabilities exposed by the Windows and Linux low-level drivers. Under Linux, I unknowingly used a GStreamer backend of OpenCV, which means another level of indirection – at the bottom level it always boils down to the V4L (video for Linux) kernel API. Using the libv4l backend improved things, as that had the nice property of defaulting to some YUV stream format (albeit at a possibly lower framerate, which might be undesirable in other contexts). (There are even different, diverging backends for direct access to the v4l kernel API or going through libv4l.)
[1] See CV_CAP_PROP_FORMAT in the API docs: http://opencv.willowgarage.com/documentation/cpp/reading_and_writing_images_and_video.html
Upvotes: 3
Reputation: 69642
30 FPS is achieved by capturing compressed video (most likely JPEG). I my so happen that OpenCV is switching to capture raw video, such as RGB, in which case the effective FPS is limited by USB bandwidth. 4 FPS is about the amount of data USB can push through in 1920x2080 24-bit RGB (25 MB/s).
The solution is to ensure that capture format (media type in DirectShow terms) is compressed video, with post-decompression in software.
Upvotes: 3