{"id":1020,"date":"2015-09-29T20:04:22","date_gmt":"2015-09-30T03:04:22","guid":{"rendered":"http:\/\/visualgdb.com\/w\/?p=1020"},"modified":"2015-09-30T11:15:50","modified_gmt":"2015-09-30T18:15:50","slug":"using-opencv-with-raspberry-pi-2-camera","status":"publish","type":"post","link":"https:\/\/visualgdb.com\/tutorials\/raspberry\/opencv\/camera\/","title":{"rendered":"Using OpenCV with Raspberry Pi 2 Camera"},"content":{"rendered":"<p>This tutorial shows how to use the OpenCV library to process the images obtained from the OpenCV camera. Before you begin, follow <a href=\"http:\/\/visualgdb.com\/tutorials\/raspberry\/opencv\/build\/\">this tutorial<\/a> to cross-compile the OpenCV library for Raspberry Pi or <a href=\"http:\/\/visualgdb.com\/tutorials\/raspberry\/opencv\/\">this one<\/a> to use a pre-built one and <a href=\"http:\/\/visualgdb.com\/tutorials\/raspberry\/camera\/\">this tutorial<\/a> to setup the raspicam library that allows obtaining images from the Raspberry Pi camera.<\/p>\n<ol>\n<li>Start Visual Studio and open the project created during the <a href=\"http:\/\/visualgdb.com\/tutorials\/raspberry\/camera\/\">Raspberry Pi camera tutorial<\/a>:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/01-camprj.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1023\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/01-camprj.png\" alt=\"01-camprj\" width=\"699\" height=\"673\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/01-camprj.png 699w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/01-camprj-300x289.png 300w\" sizes=\"(max-width: 699px) 100vw, 699px\" \/><\/a><\/li>\n<li>Our first step will be to modify the RaspiCam project to support OpenCV. Open the VisualGDB Project Properties for it and add the OpenCV build directory from <a href=\"http:\/\/visualgdb.com\/tutorials\/raspberry\/opencv\/build\/\">this tutorial<\/a> (or\u00a0&lt;sysroot&gt;\\usr\\share\\OpenCV if using a pre-built OpenCV) to the CMAKE_PREFIX_PATH variable for the CMake command:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/02-prefix.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1024\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/02-prefix.png\" alt=\"02-prefix\" width=\"750\" height=\"681\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/02-prefix.png 750w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/02-prefix-300x272.png 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/a><\/li>\n<li>Rebuild the RaspiCam project. Ensure that OpenCV is detected:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/03-buildcv.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1025\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/03-buildcv.png\" alt=\"03-buildcv\" width=\"699\" height=\"664\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/03-buildcv.png 699w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/03-buildcv-300x285.png 300w\" sizes=\"(max-width: 699px) 100vw, 699px\" \/><\/a>If OpenCV is not detected, double-check that the directory specified in the previous step contains the <strong>OpenCVConfig.cmake<\/strong> file.<\/li>\n<li>Add another project to the solution using the VisualGDB Linux Project Wizard:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/04-camera.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1026\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/04-camera.png\" alt=\"04-camera\" width=\"800\" height=\"450\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/04-camera.png 800w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/04-camera-300x169.png 300w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><\/a><\/li>\n<li>Select &#8220;New Project-&gt;Application-&gt;CMake&#8221;:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/05-cmake.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1027\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/05-cmake.png\" alt=\"05-cmake\" width=\"696\" height=\"628\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/05-cmake.png 696w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/05-cmake-300x271.png 300w\" sizes=\"(max-width: 696px) 100vw, 696px\" \/><\/a><\/li>\n<li>Then select &#8220;Build the project locally&#8221; and ensure that Raspberry Pi is still selected as the deployment machine:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/06-cross.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1028\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/06-cross.png\" alt=\"06-cross\" width=\"696\" height=\"628\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/06-cross.png 696w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/06-cross-300x271.png 300w\" sizes=\"(max-width: 696px) 100vw, 696px\" \/><\/a><\/li>\n<li>Once the project is created, add the OpenCV build directory (or &lt;sysroot&gt;\\usr\\share\\OpenCV) to the CMAKE_PREFIX_PATH variable of the CMake command for the newly created project:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/07-prefix.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1029\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/07-prefix.png\" alt=\"07-prefix\" width=\"817\" height=\"705\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/07-prefix.png 817w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/07-prefix-300x259.png 300w\" sizes=\"(max-width: 817px) 100vw, 817px\" \/><\/a><\/li>\n<li>Add the following lines to CMakeLists.txt in the new project:\n<pre class=\"\">find_package(OpenCV REQUIRED)\r\n\r\nocv_include_directories(\"${OpenCV_SOURCE_DIR}\/include\")\r\nocv_include_modules_recurse(${OPENCV_CPP_SAMPLES_REQUIRED_DEPS})\r\ntarget_link_libraries(OpenCVCameraDemo -L${CMAKE_SOURCE_DIR}\/..\/..\/raspicam-0.1.3\/build\/Debug\/src ${OpenCV_LIBS} raspicam_cv raspicam \"${LIBRARIES_FROM_REFERENCES}\")\r\ninclude_directories(..\/..\/raspicam-0.1.3\/src)<\/pre>\n<p>Replace ..\/..\/raspicam-0.1.3 with the relative path to the raspicam project:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/08-cmakefile.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1030\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/08-cmakefile.png\" alt=\"08-cmakefile\" width=\"699\" height=\"664\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/08-cmakefile.png 699w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/08-cmakefile-300x285.png 300w\" sizes=\"(max-width: 699px) 100vw, 699px\" \/><\/a>If you are using OpenCV 2.x, use <strong>ocv_include_modules()<\/strong> instead of <strong>ocv_include_modules_recurse()<\/strong>.<\/li>\n<li>To speed up building the solution, you can remove the non-OpenCV demo project and disable building for the RaspiCam library:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/09-nobuild.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1031\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/09-nobuild.png\" alt=\"09-nobuild\" width=\"716\" height=\"449\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/09-nobuild.png 716w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/09-nobuild-300x188.png 300w\" sizes=\"(max-width: 716px) 100vw, 716px\" \/><\/a><\/li>\n<li>As the new camera demo project uses complex CMake macros that cannot be parsed without querying CMake explicitly, enable the corresponding checkbox for the newly created project and rebuild it:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/10-flags.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1032\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/10-flags.png\" alt=\"10-flags\" width=\"817\" height=\"705\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/10-flags.png 817w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/10-flags-300x259.png 300w\" sizes=\"(max-width: 817px) 100vw, 817px\" \/><\/a><\/li>\n<li>First of all, we will create a very basic program that will grab images from the camera and display them using the OpenCV API:\n<ul>\n<li>First we will create and initialize a <strong>raspicam::RaspiCam_Cv<\/strong> object.<\/li>\n<li>Then we will call the grab() method on the object to grab the images.<\/li>\n<li>Then the retrieve() method will be used to save the images into an OpenCV-supported image container.<\/li>\n<li>Finally we will use the cv::imshow() function to show the image on the screen.<\/li>\n<\/ul>\n<p>The full source code of the first basic program is shown below. Copy it to the main source file of the new project:<\/p>\n<pre class=\"\">#include &lt;ctime&gt;\r\n#include &lt;iostream&gt;\r\n#include &lt;raspicam_cv.h&gt;\r\n\r\nusing namespace cv;\r\nusing namespace std;\r\n\u00a0\r\nint main(int argc, char **argv)\r\n{\r\n\u00a0\u00a0 \u00a0raspicam::RaspiCam_Cv cam;\r\n\u00a0\u00a0 \u00a0Mat image;\r\n\u00a0\u00a0 \u00a0cam.set(CV_CAP_PROP_FORMAT, CV_8UC1);\r\n\u00a0\u00a0 \u00a0if (!cam.open())\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0return 1;\r\n\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0const char szSourceWindow[] = \"Source\";\r\n\u00a0\u00a0 \u00a0namedWindow(szSourceWindow, WINDOW_AUTOSIZE);\r\n\r\n\u00a0\u00a0 \u00a0for (;;)\r\n\u00a0\u00a0 \u00a0{\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0cam.grab();\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0cam.retrieve(image);\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0imshow(szSourceWindow, image);\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0waitKey(100);\r\n\u00a0\u00a0 \u00a0}\r\n\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0cam.release();\r\n\u00a0\u00a0 \u00a0return 0;\r\n}<\/pre>\n<p><a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/11-source.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1033\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/11-source.png\" alt=\"11-source\" width=\"699\" height=\"673\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/11-source.png 699w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/11-source-300x289.png 300w\" sizes=\"(max-width: 699px) 100vw, 699px\" \/><\/a><\/li>\n<li>If you start debugging now, VisualGDB will show that the program has exited immediately and the GDBServer log will contain an error message about a missing library:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/nolib1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1039\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/nolib1.png\" alt=\"nolib1\" width=\"800\" height=\"400\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/nolib1.png 800w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/nolib1-300x150.png 300w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><\/a><\/li>\n<li>You can get the list of missing libraries by running &#8220;ldd &lt;deployed project file&gt; | grep found&#8221; via SSH:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/nolibs.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1040\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/nolibs.png\" alt=\"nolibs\" width=\"624\" height=\"402\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/nolibs.png 624w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/nolibs-300x193.png 300w\" sizes=\"(max-width: 624px) 100vw, 624px\" \/><\/a><\/li>\n<li>You can fix this either by uploading the libraries manually, or by adding custom pre-debug actions to upload the necessary libraries:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/actions.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1041\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/actions.png\" alt=\"actions\" width=\"817\" height=\"705\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/actions.png 817w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/actions-300x259.png 300w\" sizes=\"(max-width: 817px) 100vw, 817px\" \/><\/a><\/li>\n<li>If you upload the libraries outside the normal library directories, do not forget to add the target directory to LD_LIBRARY_PATH:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/ldlib.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1042\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/ldlib.png\" alt=\"ldlib\" width=\"817\" height=\"705\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/ldlib.png 817w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/ldlib-300x259.png 300w\" sizes=\"(max-width: 817px) 100vw, 817px\" \/><\/a><\/li>\n<li>Now you can start debugging by hitting F5. You will see a window forwarded from your Raspberry Pi that will show the video stream from the camera:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/12-picture.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1034\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/12-picture.png\" alt=\"12-picture\" width=\"833\" height=\"511\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/12-picture.png 833w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/12-picture-300x184.png 300w\" sizes=\"(max-width: 833px) 100vw, 833px\" \/><\/a><\/li>\n<li>In order to step into RaspiCam and OpenCV functions, add the directories containing the library files to GDB shared library search path by adding the <a href=\"http:\/\/visualgdb.com\/gdbreference\/commands\/set_solib-search-path\">set solib-search-path command<\/a> to startup commands:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/13-path.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1035\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/13-path.png\" alt=\"13-path\" width=\"817\" height=\"705\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/13-path.png 817w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/13-path-300x259.png 300w\" sizes=\"(max-width: 817px) 100vw, 817px\" \/><\/a><\/li>\n<li>Then you can try stepping into grab() or retrieve() to see what happens inside them:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/14-retrieve.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1036\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/14-retrieve.png\" alt=\"14-retrieve\" width=\"699\" height=\"673\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/14-retrieve.png 699w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/14-retrieve-300x289.png 300w\" sizes=\"(max-width: 699px) 100vw, 699px\" \/><\/a><\/li>\n<li>Now we will add code for running the contour detection algorithm similar to the one shown in the <a href=\"http:\/\/visualgdb.com\/tutorials\/raspberry\/opencv\/\">OpenCV tutorial<\/a>:\n<ul>\n<li>For each captured image we will first call resize() to halve its size.<\/li>\n<li>Then we will run the <a href=\"http:\/\/en.wikipedia.org\/wiki\/Canny_edge_detector\">Canny edge detector<\/a> on the image by calling the Canny() function.<\/li>\n<li>After detecting the edges, we will run the contour extraction algorithm by calling findContours().<\/li>\n<li>We will then draw the contours on a separate blank image by calling drawContours().<\/li>\n<li>Finally, we will display both the original image and the visualization of the contours by calling imshow().<\/li>\n<\/ul>\n<p>The code implementing the procedure described above is shown below:<\/p>\n<pre class=\"\">#include &lt;ctime&gt;\r\n#include &lt;iostream&gt;\r\n#include &lt;raspicam_cv.h&gt;\r\n#include \"opencv2\/highgui\/highgui.hpp\"\r\n#include \"opencv2\/imgproc\/imgproc.hpp\"\r\n\r\nusing namespace cv;\r\nusing namespace std;\r\n\u00a0\r\nint main(int argc, char **argv)\r\n{\r\n\u00a0\u00a0 \u00a0int threshold = 100;\r\n\u00a0\u00a0 \u00a0const int frameDelay = 100, maxContours = 500;\r\n\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0raspicam::RaspiCam_Cv cam;\r\n\u00a0\u00a0 \u00a0Mat image;\r\n\u00a0\u00a0 \u00a0cam.set(CV_CAP_PROP_FORMAT, CV_8UC1);\r\n\u00a0\u00a0 \u00a0if (!cam.open())\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0return 1;\r\n\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0const char szSourceWindow[] = \"Source\", szContoursWindow[] = \"Contours\";\r\n\u00a0\u00a0 \u00a0namedWindow(szSourceWindow, WINDOW_AUTOSIZE);\r\n\u00a0\u00a0 \u00a0namedWindow(szContoursWindow, WINDOW_AUTOSIZE);\r\n\u00a0\u00a0 \u00a0createTrackbar(\"Threshold:\", szSourceWindow, &amp;threshold, 255, NULL);\r\n\r\n\u00a0\u00a0 \u00a0for (;;)\r\n\u00a0\u00a0 \u00a0{\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0RNG rng(12345);\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0cam.grab();\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0cam.retrieve(image);\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0Mat smallImage;\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0resize(image, smallImage, Size(), 0.5, 0.5);\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0imshow(szSourceWindow, smallImage);\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0Mat canny_output;\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0vector&lt;vector&lt;Point&gt; &gt; contours;\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0vector&lt;Vec4i&gt; hierarchy;\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0Canny(smallImage, canny_output, threshold, threshold * 2, 3);\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0findContours(canny_output, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));\r\n\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0Mat drawing = Mat::zeros(canny_output.size(), CV_8UC3);\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0for (size_t i = 0; i &lt; std::min(contours.size(), (size_t)maxContours); i++)\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0{\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0drawContours(drawing, contours, (int)i, color, 2, 8, hierarchy, 0, Point());\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0}\r\n\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0imshow(szContoursWindow, drawing);\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0waitKey(frameDelay);\r\n\u00a0\u00a0 \u00a0}\r\n\u00a0\u00a0 \u00a0cam.release();\r\n}<\/pre>\n<\/li>\n<li>Build and run the modified program. You will see two X11 windows: one with the original frames from the camera and another one with the contours extracted from them:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/15-contours.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1037\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/15-contours.png\" alt=\"15-contours\" width=\"719\" height=\"378\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/15-contours.png 719w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/15-contours-300x158.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/09\/15-contours-390x205.png 390w\" sizes=\"(max-width: 719px) 100vw, 719px\" \/><\/a>You can change the threshold value for the Canny edge detection algorithm by moving the trackbar in the left window. When done, press Shift-F5 in Visual Studio to end debugging.<\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This tutorial shows how to use the OpenCV library to process the images obtained from the OpenCV camera. Before you<\/p>\n","protected":false},"author":1,"featured_media":1038,"comment_status":"closed","ping_status":"closed","sticky":true,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12],"tags":[72,33,85],"_links":{"self":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/1020"}],"collection":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/comments?post=1020"}],"version-history":[{"count":4,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/1020\/revisions"}],"predecessor-version":[{"id":1047,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/1020\/revisions\/1047"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/media\/1038"}],"wp:attachment":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/media?parent=1020"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/categories?post=1020"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/tags?post=1020"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}