{"id":75,"date":"2009-06-18T14:06:49","date_gmt":"2009-06-18T04:06:49","guid":{"rendered":"http:\/\/www.computer-vision-software.com\/blog\/?p=75"},"modified":"2009-11-30T13:11:18","modified_gmt":"2009-11-30T03:11:18","slug":"fastfurious-face-detection-with-opencv","status":"publish","type":"post","link":"http:\/\/www.computer-vision-software.com\/blog\/2009\/06\/fastfurious-face-detection-with-opencv\/","title":{"rendered":"Fast &#038; Furious face detection with OpenCV"},"content":{"rendered":"<p style=\"text-align: justify; padding-left: 30px;\">In OpenCV\/Samples there is\u00a0 facedetect program.\u00a0 This program can detect\u00a0 faces on images and video.\u00a0 It&#8217;s very fun, but its speed leaves much to be desired =(.\u00a0 Of course\u00a0 with OpenMP,\u00a0 it works\u00a0 faster; on Intel Core Duo 2.7GHZ, it works fast;\u00a0 but will it work fast on ARM? I have big doubts.\u00a0 I compiled facedetect without OpenMP and on average it takes 600 ms for 640&#215;480 resolution to find one face. \u00a0 I wanted to find out, if it&#8217;s possible to improve this time by software means or not&#8230;\u00a0 After some investigations, code refactoring and improvements, facedetect started to work <strong>2.5 time faster<\/strong>, even on ARM.\u00a0 Of course, <strong>without big quality loss<\/strong> =)<\/p>\n<p><!--more--><\/p>\n<p style=\"text-align: justify;\">I started investigation with profiling cvHaarDetectObjects on 640&#215;480 image.\u00a0 Function cvRunHaarClassifierCascade tooks <span style=\"text-decoration: underline;\">70% of computation time<\/span>.\u00a0 But cvRunHaarClassifierCascade is not so heavy, why it takes so much time? Scanning 20&#215;20 window is moved on X-direction and Y-direction and Scale-direction and on each scanning window, cvRunHaarClassifierCascade is called.\u00a0 Totally we have <strong>160000<\/strong> calls!<\/p>\n<p>So to reduce time, we need <span style=\"text-decoration: underline;\">optimize this triple cycle<\/span>.\u00a0 I know several ways:<\/p>\n<ol>\n<li>change parameters in cvHaarDetectObjects function.\u00a0 Sometimes, it really helps, but let&#8217;s resort to such shamanism another time.\u00a0\u00a0 I used &#8220;default&#8221; parameters: <em>1.1 scale factor, 20&#215;20 window<\/em>.<\/li>\n<li>use fixed point in algorithm.\u00a0 We did it <a onclick=\"javascript:pageTracker._trackPageview('\/outgoing\/www.computer-vision-software.com\/blog\/2009\/04\/fixing-opencv\/');\" title=\"here\"  href=\"http:\/\/www.computer-vision-software.com\/blog\/2009\/04\/fixing-opencv\/\" target=\"_blank\">here<\/a><\/li>\n<li>optimize OpenCV default frontal face cascade.\u00a0 <a onclick=\"javascript:pageTracker._trackPageview('\/outgoing\/www.computer-vision-software.com\/blog\/2009\/06\/parallel-world-of-opencv\/');\" title=\"Cascade generation\"  href=\"http:\/\/www.computer-vision-software.com\/blog\/2009\/06\/parallel-world-of-opencv\/\" target=\"_blank\">Cascade generation<\/a> takes much time and who knows, will it be good or not =)<\/li>\n<li>somehow reduce number of cvRunHaarClassifierCascade calls.\u00a0 Image contains only several real faces, not 160000 &#8211; so all this makes sence.<\/li>\n<\/ol>\n<p>We have researched a lot of approaches and combination of ways above and got the result (Intel Core Duo 2.7GHZ):<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-80\" title=\"2\" src=\"http:\/\/www.computer-vision-software.com\/blog\/wp-content\/uploads\/2009\/06\/22.JPG\" alt=\"2\" width=\"775\" height=\"395\" srcset=\"http:\/\/www.computer-vision-software.com\/blog\/wp-content\/uploads\/2009\/06\/22.JPG 775w, http:\/\/www.computer-vision-software.com\/blog\/wp-content\/uploads\/2009\/06\/22-300x152.jpg 300w\" sizes=\"auto, (max-width: 775px) 100vw, 775px\" \/><\/p>\n<div id=\"_mcePaste\" style=\"overflow: hidden; position: absolute; width: 1px; height: 1px; top: 288px; left: -10000px;\">\n<table style=\"width: 440pt; border-collapse: collapse;\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\" width=\"587\">\n<colgroup span=\"1\">\n<col style=\"width: 116pt;\" span=\"1\" width=\"155\"><\/col>\n<col style=\"width: 54pt;\" span=\"6\" width=\"72\"><\/col>\n<\/colgroup>\n<tbody>\n<tr style=\"height: 75pt;\" height=\"100\">\n<td class=\"xl65\" style=\"width: 116pt; height: 75pt;\" width=\"155\" height=\"100\"><\/td>\n<td class=\"xl66\" style=\"border-left: medium none; width: 162pt;\" colspan=\"3\" width=\"216\">Original face detect<\/td>\n<td class=\"xl66\" style=\"border-left: medium none; width: 162pt;\" colspan=\"3\" width=\"216\">Fast face detect<\/td>\n<\/tr>\n<tr style=\"height: 22.5pt;\" height=\"30\">\n<td class=\"xl67\" style=\"border-top: medium none; height: 22.5pt;\" height=\"30\"><\/td>\n<td class=\"xl68\" style=\"border-top: medium none; border-left: medium none; width: 54pt;\" width=\"72\">ColorFERET<br \/>\nfrontal<\/td>\n<td class=\"xl68\" style=\"border-top: medium none; border-left: medium none; width: 54pt;\" width=\"72\">LabeledFaces<br \/>\nInTheWild<\/td>\n<td class=\"xl68\" style=\"border-top: medium none; border-left: medium none; width: 54pt;\" width=\"72\">NoFaces<br \/>\n(Negative)<\/td>\n<td class=\"xl68\" style=\"border-top: medium none; border-left: medium none; width: 54pt;\" width=\"72\">ColorFERET<br \/>\nfrontal<\/td>\n<td class=\"xl68\" style=\"border-top: medium none; border-left: medium none; width: 54pt;\" width=\"72\">LabeledFaces<br \/>\nInTheWild<\/td>\n<td class=\"xl68\" style=\"border-top: medium none; border-left: medium none; width: 54pt;\" width=\"72\">NoFaces<br \/>\n(Negative)<\/td>\n<\/tr>\n<tr style=\"height: 30pt;\" height=\"40\">\n<td class=\"xl65\" style=\"border-top: medium none; height: 30pt;\" height=\"40\"><\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\">512&#215;768<\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\">250&#215;250<\/td>\n<td class=\"xl70\" style=\"border-top: medium none; border-left: medium none; width: 54pt;\" width=\"72\">up to<br \/>\n1280&#215;1024<\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\">512&#215;768<\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\">250&#215;250<\/td>\n<td class=\"xl70\" style=\"border-top: medium none; border-left: medium none; width: 54pt;\" width=\"72\">up to<br \/>\n1280&#215;1024<\/td>\n<\/tr>\n<tr style=\"height: 15pt;\" height=\"20\">\n<td class=\"xl65\" style=\"border-top: medium none; height: 15pt;\" height=\"20\"><\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\"><\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\"><\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\"><\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\"><\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\"><\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\"><\/td>\n<\/tr>\n<tr style=\"height: 15pt;\" height=\"20\">\n<td class=\"xl65\" style=\"border-top: medium none; height: 15pt;\" height=\"20\">Total<\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\">5444<\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\">1872<\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\">1748<\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\">5276<\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\">1872<\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\">1748<\/td>\n<\/tr>\n<tr style=\"height: 15pt;\" height=\"20\">\n<td class=\"xl65\" style=\"border-top: medium none; height: 15pt;\" height=\"20\"><\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\"><\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\"><\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\"><\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\"><\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\"><\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\"><\/td>\n<\/tr>\n<tr style=\"height: 15pt;\" height=\"20\">\n<td class=\"xl65\" style=\"border-top: medium none; height: 15pt;\" height=\"20\">Fount<\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\">5420<\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\">1765<\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\"><\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\">5191<\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\">1685<\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\"><\/td>\n<\/tr>\n<tr style=\"height: 15pt;\" height=\"20\">\n<td class=\"xl71\" style=\"border-top: medium none; height: 15pt;\" height=\"20\">Hit rate<\/td>\n<td class=\"xl72\" style=\"border-top: medium none; border-left: medium none;\">99,6%<\/td>\n<td class=\"xl72\" style=\"border-top: medium none; border-left: medium none;\">94,3%<\/td>\n<td class=\"xl72\" style=\"border-top: medium none; border-left: medium none;\"><\/td>\n<td class=\"xl72\" style=\"border-top: medium none; border-left: medium none;\">98,4%<\/td>\n<td class=\"xl72\" style=\"border-top: medium none; border-left: medium none;\">90,0%<\/td>\n<td class=\"xl72\" style=\"border-top: medium none; border-left: medium none;\"><\/td>\n<\/tr>\n<tr style=\"height: 15pt;\" height=\"20\">\n<td class=\"xl65\" style=\"border-top: medium none; height: 15pt;\" height=\"20\">FP (incorrect found)<\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\">57<\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\">12<\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\">37<\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\">18<\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\">10<\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\">13<\/td>\n<\/tr>\n<tr style=\"height: 15pt;\" height=\"20\">\n<td class=\"xl73\" style=\"border-top: medium none; height: 15pt;\" height=\"20\">False alarm rate<\/td>\n<td class=\"xl74\" style=\"border-top: medium none; border-left: medium none;\"><\/td>\n<td class=\"xl74\" style=\"border-top: medium none; border-left: medium none;\"><\/td>\n<td class=\"xl72\" style=\"border-top: medium none; border-left: medium none;\">2,1%<\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\"><\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\"><\/td>\n<td class=\"xl72\" style=\"border-top: medium none; border-left: medium none;\">0,7%<\/td>\n<\/tr>\n<tr style=\"height: 15pt;\" height=\"20\">\n<td class=\"xl65\" style=\"border-top: medium none; height: 15pt;\" height=\"20\">FN (not found)<\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\">23<\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\">107<\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\"><\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\">85<\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\">187<\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\"><\/td>\n<\/tr>\n<tr style=\"height: 15pt;\" height=\"20\">\n<td class=\"xl65\" style=\"border-top: medium none; height: 15pt;\" height=\"20\"><\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\"><\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\"><\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\"><\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\"><\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\"><\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\"><\/td>\n<\/tr>\n<tr style=\"height: 15pt;\" height=\"20\">\n<td class=\"xl65\" style=\"border-top: medium none; height: 15pt;\" height=\"20\">Average time, ms<\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\"><\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\"><\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\"><\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\"><\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\"><\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\"><\/td>\n<\/tr>\n<tr style=\"height: 15pt;\" height=\"20\">\n<td class=\"xl73\" style=\"border-top: medium none; height: 15pt;\" height=\"20\">not found<\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\">623,98<\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\">85,43<\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\">775,23<\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\">139,07<\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\">39,48<\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\">287,98<\/td>\n<\/tr>\n<tr style=\"height: 15pt;\" height=\"20\">\n<td class=\"xl73\" style=\"border-top: medium none; height: 15pt;\" height=\"20\">one face found<\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\">629,53<\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\">87,07<\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\">1053,49<\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\">248,26<\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\">42,99<\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\">455,31<\/td>\n<\/tr>\n<tr style=\"height: 15pt;\" height=\"20\">\n<td class=\"xl73\" style=\"border-top: medium none; height: 15pt;\" height=\"20\">two or more face found<\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\">632,32<\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\">88,04<\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\"><\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\">245,12<\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\">43,39<\/td>\n<td class=\"xl69\" style=\"border-top: medium none; border-left: medium none;\"><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>In OpenCV\/Samples there is\u00a0 facedetect program.\u00a0 This program can detect\u00a0 faces on images and video.\u00a0 It&#8217;s very fun, but its speed leaves much to be desired =(.\u00a0 Of course\u00a0 with OpenMP,\u00a0 it works\u00a0 faster; on Intel Core Duo 2.7GHZ, it works fast;\u00a0 but will it work fast on ARM? I have big doubts.\u00a0 I compiled [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[84],"tags":[7,29,31,6,28,30],"class_list":["post-75","post","type-post","status-publish","format-standard","hentry","category-opencv","tag-arm","tag-face-detection","tag-haar","tag-opencv","tag-performance","tag-viola-jones"],"_links":{"self":[{"href":"http:\/\/www.computer-vision-software.com\/blog\/wp-json\/wp\/v2\/posts\/75","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.computer-vision-software.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.computer-vision-software.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.computer-vision-software.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.computer-vision-software.com\/blog\/wp-json\/wp\/v2\/comments?post=75"}],"version-history":[{"count":0,"href":"http:\/\/www.computer-vision-software.com\/blog\/wp-json\/wp\/v2\/posts\/75\/revisions"}],"wp:attachment":[{"href":"http:\/\/www.computer-vision-software.com\/blog\/wp-json\/wp\/v2\/media?parent=75"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.computer-vision-software.com\/blog\/wp-json\/wp\/v2\/categories?post=75"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.computer-vision-software.com\/blog\/wp-json\/wp\/v2\/tags?post=75"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}