OpenCV 2.0 Tutorial 02

Last time was just about getting your feet wet, and this time is not really all that different. OpenCV is somewhat geared towards realtime image processing, which is most evident when you use realtime image sources (duh), such as a webcam. In this tutorial I present a minimal example of how to get the video feed from a video source.

#include 
#include 
#include 

void main() {
	cv::Mat frame;
	cv::VideoCapture cap(0);

	if (!cap.isOpened()) {
		std::cout << "Failed to open video capture device 0\n";
		return;
	}

	cv::namedWindow("picture window", CV_WINDOW_AUTOSIZE);
	
	while (cv::waitKey(30) == -1) {
		cap >> frame;
		cv::imshow("picture window", frame);
	}
}

As you can see, this is really convenient. The VideoCapture object can grab frames from either a video file or a live video feed; in the example above it takes video from a live video feed. Note that there is an absence of any sort of configuration, so everything will revert to its default setting. For most uses, this is just fine.

The single wait for a key from the first tutorial has been replaced by an actual loop, and it is important to note that the waitKey function doesn’t just wait for keys, it also processes window events. So in order to achieve default window behaviour with openCV’s HighGUI, you need to make use of the namedWindow together with waitKey. In any case, this example illustrates how to import video from the first capture device available. If you want to adjust the resolution of your input images, this can be done through the VideoCapture::set function, as can be seen in the example below:

#include 
#include 
#include 

void main() {
	cv::Mat frame;
	cv::VideoCapture cap;
	
	cap.open(0);	

	if (!cap.isOpened()) {
		std::cout << "Failed to open video capture device 0\n";
		return;
	}
	
	cap.set(CV_CAP_PROP_FRAME_WIDTH, 320);
	cap.set(CV_CAP_PROP_FRAME_HEIGHT, 240);

	cv::namedWindow("picture window", CV_WINDOW_AUTOSIZE);
	
	while (cv::waitKey(30) == -1) {
		cap >> frame;
		cv::imshow("picture window", frame);
	}
}

A slight modification, and it shows that there are various properties of the capture object that can be read or written to via the get and set methods. The available properties are:

  • CV_CAP_PROP_POS_MSEC
  • CV_CAP_PROP_POS_FRAMES
  • CV_CAP_PROP_POS_AVI_RATIO
  • CV_CAP_PROP_FRAME_WIDTH
  • CV_CAP_PROP_FRAME_HEIGHT
  • CV_CAP_PROP_FPS
  • CV_CAP_PROP_FOURCC
  • CV_CAP_PROP_FRAME_COUNT
  • CV_CAP_PROP_FORMAT
  • CV_CAP_PROP_MODE
  • CV_CAP_PROP_BRIGHTNESS
  • CV_CAP_PROP_CONTRAST
  • CV_CAP_PROP_SATURATION
  • CV_CAP_PROP_HUE
  • CV_CAP_PROP_GAIN
  • CV_CAP_PROP_EXPOSURE
  • CV_CAP_PROP_CONVERT_RGB
  • CV_CAP_PROP_WHITE_BALANCE
  • CV_CAP_PROP_RECTIFICATION

Some of the properties only work with video files, and others only work with cameras. The last thing I’m going to present this time is how to open multiple cameras on the same system. This is different from using multihead cameras. On a side note – if you have a cheap setup this might not work because the webcam drivers allocate too much bandwith on the USB root hub (in which case you either need a different driver and/or camera, or you need an additional USB root hub).

#include 
#include 
#include 

void main() {
	cv::Mat frame[2];
	cv::VideoCapture cap[2];
	std::string windowNames[2];

	for (int i = 0; i < 2; ++i) {
		cap[i].open(i);

		if (!cap[i].isOpened()) {
			std::cout << "Failed to open video capture device " << i << std::endl;
			return;
		}

		cap[i].set(CV_CAP_PROP_FRAME_WIDTH, 320);
		cap[i].set(CV_CAP_PROP_FRAME_HEIGHT, 240);

		std::stringstream buffer;
		buffer << "window " << i;
		windowNames[i] = buffer.str();

		cv::namedWindow(windowNames[i].c_str(), CV_WINDOW_AUTOSIZE);
	}
	
	while (cv::waitKey(30) == -1) {
		for (int i = 0; i < 2; ++i)
			cap[i] >> frame[i];

		for (int i = 0; i < 2; ++i)
			cv::imshow(windowNames[i].c_str(), frame[i]);		
	}
}

That's it for now. Next time I'll delve into basic image operations and work towards an actual application, and at some point in the future I will revisit this subject and show how to import a video feed from another library.

11 thoughts on “OpenCV 2.0 Tutorial 02

  1. This give HIGHGUI ERROR: V4L2: getting property #5 is not supported error on linux
    do you have any idea?

    1. The driver support is a little flaky under linux; the way I described here is the intended usage, but if the camera driver doesn’t support it you’re better off using a vendor-specific API for capturing images.
      I’m sorry I can’t be of more help 😐

  2. Hi,

    I have a question regarding webcams and openCV. The webcam I have is said to be able to capture video of a resolution 1600×1200. However when using openCV, the default is 640×480. Even if I set the resolution to 1600×1200, the image appears to be bigger but it’s quality is still bad, as though it has been interpolated using the 640×480 image. Is there any way to reach the capacity of the webcam?

    1. That kind of depends… lots of webcams advertise stuff like 1600×1200 video, but only a couple actually manage to truly get to that resolution with decent quality. Most have a sensor that only detects something like 640×480 or worse, and the webcam driver then interpolates it into a higher resolution. Usually it’s a marketing ploy.

      In the case that your webcam is actually a very high grade camera, there’s a lot of other stuff you need to consider – 1600×1200 images consume a *lot* of bandwith – about 6mb per image, so you can probably only capture still images. The openCV interface is kind of tailored to realtime image processing, and I’m guessing that you would need something different for high-resolution snapshots. My best guess would be to find out if the manufacturer of your webcam has a device-specific SDK that you can use. If at all possible, that would be the best place to find stuff like that out.

  3. please tell me how can i interface SONY EVI D70 camera with opencv. The above method is not helping me out.

    1. as far as I can tell that camera doesn’t have a public SDK, I’m afraid you’ll have to contact sony to help you with that… (send mail to bis.product.support@am.sony.com)

      Probably the way forward is to use their custom SDK to acquire frames and then, if needed, convert those frames to an openCV image so that you can use openCV algorithms with it.

      Hope this helps 😛

  4. Object Marker Reader (OMR) detection in multiple DPI (Dots Per Inch)using opencv

    Need to detect reference image (marker) in source image of multiple DPI’s.
    Library used : opencv-2.4.7
    Methods used : matchTemplate, normalize, threshold, minMaxLoc

    Issue facing
    If the source and reference image DPI are different, marker detection is working wrongly (it is showing places where is no marker) One more thing I want to know, is it possible to find the DPI of an image in opencv ???. pls help me to solve the issue. Here I give the code also.

  5. Hi! I like your article, it is short and relevant. I am a translator and I have to translate few articles about the OpenCV, so I read as much about it as I can. For now, I’ve only translated one piece, it’s about integrating OpenCV with Android Studio project. You can check it out and let me know if there are any mistakes: http://blog.zaven.co/opencv-in-android-studio-project/ Thanks!

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.