{"id":1797,"date":"2015-11-18T14:51:59","date_gmt":"2015-11-18T14:51:59","guid":{"rendered":"https:\/\/intelligentbee.com\/blog\/?p=1797"},"modified":"2024-11-01T11:25:41","modified_gmt":"2024-11-01T11:25:41","slug":"build-a-face-detector-on-os-x-using-opencv-and-c","status":"publish","type":"post","link":"https:\/\/intelligentbee.com\/blog\/build-a-face-detector-on-os-x-using-opencv-and-c\/","title":{"rendered":"Build a Face Detector on OS X Using OpenCV and C++"},"content":{"rendered":"<p>Building and using C++ libraries can be a daunting task, even more so for big libraries like OpenCV. This article should get you started with a minimal build of OpenCV and a sample application written in C++.<\/p>\n<p>This application will get images from the webcam, draw rectangles around the faces in the images and show them to you on screen<\/p>\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_68_1 counter-hierarchy ez-toc-counter ez-toc-grey ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title \" >Table of Contents<\/p>\n<span class=\"ez-toc-title-toggle\"><a href=\"#\" class=\"ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle\" aria-label=\"Toggle Table of Content\"><span class=\"ez-toc-js-icon-con\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/span><\/a><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/intelligentbee.com\/blog\/build-a-face-detector-on-os-x-using-opencv-and-c\/#Build_a_Face_Detector_on_OS_X_Using_OpenCV_and_C_%E2%80%93_Requirements\" title=\"Build a Face Detector on OS X Using OpenCV and C &#8211; \u00a0 \u00a0 Requirements\">Build a Face Detector on OS X Using OpenCV and C &#8211; \u00a0 \u00a0 Requirements<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/intelligentbee.com\/blog\/build-a-face-detector-on-os-x-using-opencv-and-c\/#_Building_OpenCV\" title=\"\u00a0\u00a0\u00a0 Building OpenCV\">\u00a0\u00a0\u00a0 Building OpenCV<\/a><\/li><\/ul><\/nav><\/div>\n<h2><span class=\"ez-toc-section\" id=\"Build_a_Face_Detector_on_OS_X_Using_OpenCV_and_C_%E2%80%93_Requirements\"><\/span>Build a Face Detector on OS X Using OpenCV and C &#8211; \u00a0 \u00a0 Requirements<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>I&#8217;ve built this on a <i>MacBook Pro <\/i>running <i>OS X El Capitan Version 10.11.1<\/i>.<\/p>\n<p>We&#8217;ll be using the <i>GNU C++ compiler (g++) <\/i>from the command line. Note that you should still have <i>Xcode <\/i>installed (I have<i> Xcode 7.1<\/i> installed).<\/p>\n<p>Here&#8217;s what you need to do :<\/p>\n<ol>\n<li>Get &#8220;<i>OpenCV for Linux\/Mac<\/i>&#8221; from <a style=\"background: none; width: auto; text-indent: 0; height: auto;\" href=\"http:\/\/opencv.org\/downloads.html\" target=\"_blank\" rel=\"noopener\"> the OpenCV Downloads Page<\/a> I got version 3.0.<\/li>\n<li>Extract the contents of the zip file from step 1 to a folder of your choosing (I chose <i>~\/opencv-3.0.0<\/i>).<\/li>\n<li>Get a binary distribution of Cmake from <a style=\"background: none; width: auto; text-indent: 0; height: auto;\" title=\"the Cmake Downloads page\" href=\"https:\/\/cmake.org\/download\/\" target=\"_blank\" rel=\"noopener\">the Cmake Downloads Page<\/a> I got <i>cmake-3.4.0-Darwin-x86_64.dmg<\/i>.<\/li>\n<li>Install Cmake.<\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<h2><span class=\"ez-toc-section\" id=\"_Building_OpenCV\"><\/span>\u00a0\u00a0\u00a0 Building OpenCV<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>OpenCV uses CMake files to describe how the project needs to be built. CMake can transform these files into actual project settings (e.g. an Xcode project, Unix makefiles, a Visual Studio project, etc.) depending on the <b>generator<\/b> you choose.<\/p>\n<p>First open CMake and a small window will pop-up that will let you choose your build options based on the <i>CMakeList.txt <\/i>files in the opencv source directory. First click on the <i>Browse Source&#8230; <\/i>button and choose the path to the opencv source folder (the folder you extracted the zip file to at step 2). Then click on the <i>Browse Build&#8230;<\/i> button and choose a path to a build folder, I&#8217;m going to create a new folder called<i> build <\/i>in the previously mentioned source folder.<\/p>\n<p>If at any point you are prompted to choose a generator, pick <i>Unix Makefiles.<\/i> If the paths you chose were correct, after you click the <i>Configure <\/i>button, you should be looking at something like this :<\/p>\n<p><img decoding=\"async\" class=\"alignnone size-full wp-image-1798\" src=\"\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2015\/11\/cmake_options.png\" alt=\"cmake_options\" width=\"607\" height=\"616\" srcset=\"https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2015\/11\/cmake_options.png 607w, https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2015\/11\/cmake_options-296x300.png 296w\" sizes=\"(max-width: 607px) 100vw, 607px\" \/><\/p>\n<p>For a somewhat minimal OpenCV build, make sure you only have the following options enabled :<\/p>\n<ul>\n<li>BUILD_JASPER<\/li>\n<li>BUILD_JPEG<\/li>\n<li>BUILD_OPENEXR<\/li>\n<li>BUILD_PACKAGE<\/li>\n<li>BUILD_PNG<\/li>\n<li>BUILD_TIFF<\/li>\n<li>BUILD_WITH_DEBUG_INFO<\/li>\n<li>BUILD_ZLIB<\/li>\n<li>BUILD_opencv_apps<\/li>\n<li>BUILD_opencv_calib3d<\/li>\n<li>BUILD_opencv_core<\/li>\n<li>BUILD_opencv_features2d<\/li>\n<li>BUILD_opencv_flann<\/li>\n<li>BUILD_opencv_hal<\/li>\n<li>BUILD_opencv_highgui<\/li>\n<li>BUILD_opencv_imgcodecs<\/li>\n<li>BUILD_opencv_imgproc<\/li>\n<li>BUILD_opencv_ml<\/li>\n<li>BUILD_opencv_objdetect<\/li>\n<li>BUILD_opencv_photo<\/li>\n<li>BUILD_opencv_python2<\/li>\n<li>BUILD_opencv_shape<\/li>\n<li>BUILD_opencv_stitching<\/li>\n<li>BUILD_opencv_superres<\/li>\n<li>BUILD_opencv_ts<\/li>\n<li>BUILD_opencv_video<\/li>\n<li>BUILD_opencv_videoio<\/li>\n<li>BUILD_opencv_videostab<\/li>\n<li>ENABLE_SSE<\/li>\n<li>ENABLE_SSE2<\/li>\n<li>WITH_1394<\/li>\n<li>WITH_JASPER<\/li>\n<li>WITH_JPEG<\/li>\n<li>WITH_LIBV4L<\/li>\n<li>WITH_OPENEXR<\/li>\n<li>WITH_PNG<\/li>\n<li>WITH_TIFF<\/li>\n<li>WITH_V4L<\/li>\n<li>WITH_WEBP<\/li>\n<\/ul>\n<p>You <strong>should<\/strong> disable the options that are not in the list, especially the <em>BUILD_SHARED_LIBS<\/em> one. Don&#8217;t touch the options that are text fields unless you know what you&#8217;re doing.<\/p>\n<p>Most of these options you don&#8217;t need for this particular exercise, but it will save you time by not having to rebuild OpenCV should you decide to try something else.<\/p>\n<p>Once you have selected the settings above, click <em>Generate<\/em>. Now you can navigate to the build folder, I&#8217;ll do so with<i> cd ~\/opencv-3.0.0\/build\/ <\/i>and run <i>make<\/i> to build OpenCV.<\/p>\n<h3>\u00a0\u00a0\u00a0 Installing OpenCV<\/h3>\n<p>If everything goes well, after the build finishes, run<i> make install <\/i>to add the OpenCV includes to the <i>\/usr\/local\/include <\/i>folder and the libraries to the <i>\/usr\/local\/lib <\/i>and <i>\/usr\/local\/share\/OpenCV\/3rdparty\/lib <\/i>folders.<\/p>\n<p>After that&#8217;s done, you should be able to build your own C++ applications that link against OpenCV.<\/p>\n<h3>\u00a0\u00a0\u00a0 The Face Detector Application<\/h3>\n<p>Now let&#8217;s try to build our first application with OpenCV<\/p>\n<p>Here&#8217;s the code and comments that explain how to do just that :<\/p>\n<pre class=\"lang:c++ decode:true \">#include &lt;iostream&gt;\r\n\r\n\/\/Include OpenCV\r\n#include &lt;opencv2\/opencv.hpp&gt;\r\n\r\nint main(void )\r\n{\r\n   \/\/Capture stream from webcam.\r\n   cv::VideoCapture capture(0);\r\n\r\n   \/\/Check if we can get the webcam stream.\r\n   if(!capture.isOpened())\r\n   {\r\n      std::cout &lt;&lt; \"Could not open camera\" &lt;&lt; std::endl;\r\n      return -1;\r\n   }\r\n\r\n   \/\/OpenCV saves detection rules as something called a CascadeClassifier which\r\n   \/\/    can be used to detect objects in images.\r\n   cv::CascadeClassifier faceCascade;\r\n\r\n   \/\/We'll load the lbpcascade_frontalface.xml containing the rules to detect faces.\r\n   \/\/The file should be right next to the binary.\r\n   if(!faceCascade.load(\"lbpcascade_frontalface.xml\"))\r\n   {\r\n      std::cout &lt;&lt; \"Failed to load cascade classifier\" &lt;&lt; std::endl;\r\n      return -1;\r\n   }\r\n\r\n   while (true)\r\n   {\r\n      \/\/This variable will hold the image from the camera.\r\n      cv::Mat cameraFrame;\r\n\r\n      \/\/Read an image from the camera.\r\n      capture.read(cameraFrame);\r\n\r\n      \/\/This vector will hold the rectangle coordinates to a detection inside the image.\r\n      std::vector&lt;cv::Rect&gt; faces;\r\n\r\n      \/\/This function detects the faces in the image and\r\n      \/\/ places the rectangles of the faces in the vector.\r\n      \/\/See the detectMultiScale() documentation for more details\r\n      \/\/ about the rest of the parameters.\r\n      faceCascade.detectMultiScale(\r\n        cameraFrame, \r\n        faces, \r\n        1.09, \r\n        3,\r\n        0 | CV_HAAR_SCALE_IMAGE,\r\n        cv::Size(30, 30));\r\n\r\n      \/\/Here we draw the rectangles onto the image with a red border of thikness 2.\r\n      for( size_t i = 0; i &lt; faces.size(); i++ )\r\n            cv::rectangle(cameraFrame, faces[i], cv::Scalar(0, 0, 255), 2);\r\n\r\n      \/\/Here we show the drawn image in a named window called \"output\".\r\n      cv::imshow(\"output\", cameraFrame);\r\n\r\n      \/\/Waits 50 miliseconds for key press, returns -1 if no key is pressed during that time\r\n      if (cv::waitKey(50) &gt;= 0)\r\n          break;\r\n   }\r\n\r\n   return 0;\r\n}<\/pre>\n<p>&nbsp;<\/p>\n<p>I saved this as <i>main.cpp<\/i>. To build it I used the following command :<\/p>\n<pre class=\"lang:default decode:true \" title=\"OpenCV Application Compile Command\">g++ -o main main.cpp -I\/usr\/local\/include \\\r\n-L\/usr\/local\/lib -lopencv_core -lopencv_imgproc -lopencv_objdetect \\\r\n-lopencv_imgcodecs -lopencv_highgui -lopencv_hal -lopencv_videoio \\\r\n-L\/usr\/local\/share\/OpenCV\/3rdparty\/lib -llibpng -llibjpeg -llibwebp \\\r\n-llibtiff -lzlib -lIlmImf -llibjasper -framework AVFoundation -framework QuartzCore \\\r\n-framework CoreMedia -framework Cocoa -framework QTKit<\/pre>\n<p>Hopefully, no errors should occur.<\/p>\n<h3>\u00a0\u00a0\u00a0 Conclusions<\/h3>\n<p>Build a Face Detector on OS X Using OpenCV and C? Before running the application, you have to copy the <i>lbpcascade_frontalface.xml <\/i>next to the <i>main<\/i> file. \u00a0You can find this file in the OpenCV source folder under <i>\/data\/lbpcascades\/<\/i>. You can also find some other cascades to detect eyes, cat faces, etc.<\/p>\n<p>Now just run the <i>.\/main<\/i> and enjoy!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Building and using C++ libraries can be a daunting task, even more so for big libraries like OpenCV. This article [&hellip;]<\/p>\n","protected":false},"author":28,"featured_media":1820,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[86],"tags":[102,136,185],"yst_prominent_words":[384,593,700,1013,1087,1098],"post_mailing_queue_ids":[],"_links":{"self":[{"href":"https:\/\/intelligentbee.com\/blog\/wp-json\/wp\/v2\/posts\/1797"}],"collection":[{"href":"https:\/\/intelligentbee.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/intelligentbee.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/intelligentbee.com\/blog\/wp-json\/wp\/v2\/users\/28"}],"replies":[{"embeddable":true,"href":"https:\/\/intelligentbee.com\/blog\/wp-json\/wp\/v2\/comments?post=1797"}],"version-history":[{"count":4,"href":"https:\/\/intelligentbee.com\/blog\/wp-json\/wp\/v2\/posts\/1797\/revisions"}],"predecessor-version":[{"id":133290,"href":"https:\/\/intelligentbee.com\/blog\/wp-json\/wp\/v2\/posts\/1797\/revisions\/133290"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/intelligentbee.com\/blog\/wp-json\/wp\/v2\/media\/1820"}],"wp:attachment":[{"href":"https:\/\/intelligentbee.com\/blog\/wp-json\/wp\/v2\/media?parent=1797"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/intelligentbee.com\/blog\/wp-json\/wp\/v2\/categories?post=1797"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/intelligentbee.com\/blog\/wp-json\/wp\/v2\/tags?post=1797"},{"taxonomy":"yst_prominent_words","embeddable":true,"href":"https:\/\/intelligentbee.com\/blog\/wp-json\/wp\/v2\/yst_prominent_words?post=1797"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}