{"id":49,"date":"2010-03-23T13:45:12","date_gmt":"2010-03-23T13:45:12","guid":{"rendered":"http:\/\/grandmaster.student.utwente.nl\/?page_id=49"},"modified":"2011-12-17T23:24:05","modified_gmt":"2011-12-17T22:24:05","slug":"opencv-2-0-tutorial-02","status":"publish","type":"page","link":"https:\/\/www.grandmaster.nu\/blog\/?page_id=49","title":{"rendered":"OpenCV 2.0 Tutorial 02"},"content":{"rendered":"<p>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.<\/p>\n<pre lang=\"c++\">#include <cv.h>\r\n#include <highgui.h>\r\n#include <iostream>\r\n\r\nvoid main() {\r\n\tcv::Mat frame;\r\n\tcv::VideoCapture cap(0);\r\n\r\n\tif (!cap.isOpened()) {\r\n\t\tstd::cout << \"Failed to open video capture device 0\\n\";\r\n\t\treturn;\r\n\t}\r\n\r\n\tcv::namedWindow(\"picture window\", CV_WINDOW_AUTOSIZE);\r\n\t\r\n\twhile (cv::waitKey(30) == -1) {\r\n\t\tcap >> frame;\r\n\t\tcv::imshow(\"picture window\", frame);\r\n\t}\r\n}<\/pre>\n<p>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.<\/p>\n<p>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 <em>waitKey<\/em> function doesn&#8217;t just wait for keys, it also processes window events. So in order to achieve default window behaviour with openCV&#8217;s HighGUI, you need to make use of the <em>namedWindow<\/em> together with <em>waitKey<\/em>. 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:<\/p>\n<pre lang=\"c++\">#include <cv.h>\r\n#include <highgui.h>\r\n#include <iostream>\r\n\r\nvoid main() {\r\n\tcv::Mat frame;\r\n\tcv::VideoCapture cap;\r\n\t\r\n\tcap.open(0);\t\r\n\r\n\tif (!cap.isOpened()) {\r\n\t\tstd::cout << \"Failed to open video capture device 0\\n\";\r\n\t\treturn;\r\n\t}\r\n\t\r\n\tcap.set(CV_CAP_PROP_FRAME_WIDTH, 320);\r\n\tcap.set(CV_CAP_PROP_FRAME_HEIGHT, 240);\r\n\r\n\tcv::namedWindow(\"picture window\", CV_WINDOW_AUTOSIZE);\r\n\t\r\n\twhile (cv::waitKey(30) == -1) {\r\n\t\tcap >> frame;\r\n\t\tcv::imshow(\"picture window\", frame);\r\n\t}\r\n}<\/pre>\n<p>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:<\/p>\n<ul>\n<li>CV_CAP_PROP_POS_MSEC<\/li>\n<li>CV_CAP_PROP_POS_FRAMES<\/li>\n<li>CV_CAP_PROP_POS_AVI_RATIO<\/li>\n<li>CV_CAP_PROP_FRAME_WIDTH<\/li>\n<li>CV_CAP_PROP_FRAME_HEIGHT<\/li>\n<li>CV_CAP_PROP_FPS<\/li>\n<li>CV_CAP_PROP_FOURCC<\/li>\n<li>CV_CAP_PROP_FRAME_COUNT<\/li>\n<\/li>\n<li>CV_CAP_PROP_FORMAT<\/li>\n<li>CV_CAP_PROP_MODE<\/li>\n<li>CV_CAP_PROP_BRIGHTNESS<\/li>\n<li>CV_CAP_PROP_CONTRAST<\/li>\n<li>CV_CAP_PROP_SATURATION<\/li>\n<li>CV_CAP_PROP_HUE<\/li>\n<li>CV_CAP_PROP_GAIN<\/li>\n<li>CV_CAP_PROP_EXPOSURE<\/li>\n<li>CV_CAP_PROP_CONVERT_RGB<\/li>\n<li>CV_CAP_PROP_WHITE_BALANCE<\/li>\n<li>CV_CAP_PROP_RECTIFICATION<\/li>\n<\/ul>\n<p>Some of the properties only work with video files, and others only work with cameras. The last thing I&#8217;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 &#8211; 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).<\/p>\n<pre lang=\"c++\">#include <cv.h>\r\n#include <highgui.h>\r\n#include <iostream>\r\n\r\nvoid main() {\r\n\tcv::Mat frame[2];\r\n\tcv::VideoCapture cap[2];\r\n\tstd::string windowNames[2];\r\n\r\n\tfor (int i = 0; i < 2; ++i) {\r\n\t\tcap[i].open(i);\r\n\r\n\t\tif (!cap[i].isOpened()) {\r\n\t\t\tstd::cout << \"Failed to open video capture device \" << i << std::endl;\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tcap[i].set(CV_CAP_PROP_FRAME_WIDTH, 320);\r\n\t\tcap[i].set(CV_CAP_PROP_FRAME_HEIGHT, 240);\r\n\r\n\t\tstd::stringstream buffer;\r\n\t\tbuffer << \"window \" << i;\r\n\t\twindowNames[i] = buffer.str();\r\n\r\n\t\tcv::namedWindow(windowNames[i].c_str(), CV_WINDOW_AUTOSIZE);\r\n\t}\r\n\t\r\n\twhile (cv::waitKey(30) == -1) {\r\n\t\tfor (int i = 0; i < 2; ++i)\r\n\t\t\tcap[i] >> frame[i];\r\n\r\n\t\tfor (int i = 0; i < 2; ++i)\r\n\t\t\tcv::imshow(windowNames[i].c_str(), frame[i]);\t\t\r\n\t}\r\n}\r\n<\/pre>\n<p>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.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>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 <a class=\"more-link\" href=\"https:\/\/www.grandmaster.nu\/blog\/?page_id=49\">Read More&#8230;<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"parent":25,"menu_order":0,"comment_status":"open","ping_status":"open","template":"","meta":{"ngg_post_thumbnail":0,"footnotes":""},"_links":{"self":[{"href":"https:\/\/www.grandmaster.nu\/blog\/index.php?rest_route=\/wp\/v2\/pages\/49"}],"collection":[{"href":"https:\/\/www.grandmaster.nu\/blog\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.grandmaster.nu\/blog\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.grandmaster.nu\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.grandmaster.nu\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=49"}],"version-history":[{"count":2,"href":"https:\/\/www.grandmaster.nu\/blog\/index.php?rest_route=\/wp\/v2\/pages\/49\/revisions"}],"predecessor-version":[{"id":552,"href":"https:\/\/www.grandmaster.nu\/blog\/index.php?rest_route=\/wp\/v2\/pages\/49\/revisions\/552"}],"up":[{"embeddable":true,"href":"https:\/\/www.grandmaster.nu\/blog\/index.php?rest_route=\/wp\/v2\/pages\/25"}],"wp:attachment":[{"href":"https:\/\/www.grandmaster.nu\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=49"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}