<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                  如今我們的MFC框架已經初具規模,能夠讀取并顯示文件夾下的圖片,在這篇博文中我們將向其中添加人臉檢測的程序。   一、人臉檢測算法   這里我們使用OpenCv封裝的Adaboost方法來進行人臉檢測,參見:[C++開發人臉性別識別教程(4)——OpenCv的人臉檢測函數](http://blog.csdn.net/u013088062/article/details/50439630)   二、初始化   1、添加初始化按鈕   在進行人臉檢測之前需要初始化一些相關變量,例如開辟內存,加載檢測器等等。首先,我們為MFC框架添加一個初始化按鈕,并將ID更改為IDC_BUTTON_INITIAL: ![](https://box.kancloud.cn/2016-02-25_56ce6388ef242.png)   雙擊這個按鈕,添加事件響應函數: ![](https://box.kancloud.cn/2016-02-25_56ce63890b684.png)   2、初始化變量   從之前的博客中可知,OpenCv在進行人臉檢測時需要用到兩個靜態變量:static CvMemStorage* storage和static CvHaarClassifierCascade* cascade,這里我們將其作為成員變量添加到CGenderRecognitionMFCDlg類中,這里由于static CvMemStorage*和static CvHaarClassifierCascade*這兩個類型名在MFC類向導中是無法被識別的,因此需要手動添加至CGenderRecognitionMFCDlg類的構造函數中: ![](https://box.kancloud.cn/2016-02-25_56ce63891b1b7.png)   接下里對這兩個驚天變量進行初始化。C++明確規定靜態成員變量要在類外進行初始化,而不能在類內聲明時或者構造函數內進行初始化,原因就是靜態變量時屬于類本身的,而非類對象的屬性,和全局變量類似,因此我們將這兩個靜態變量的初始化操作放在GenderRecognitionMFCDlg.cpp文件(從解決方案資源管理器窗口中查找cpp文件)的開頭位置: ~~~ // 用于應用程序“關于”菜單項的 CAboutDlg 對話框 CvMemStorage* CGenderRecognitionMFCDlg::storage = NULL; CvHaarClassifierCascade* CGenderRecognitionMFCDlg::cascade = NULL; ~~~   然后在“初始化”按鈕的響應函數OnBnClickedButtonInitial()中加載對應的人臉檢測器: ~~~ void CGenderRecognitionMFCDlg::OnBnClickedButtonInitial() { cascade = cvLoadHaarClassifierCascade("D:\\opencv\\sources\\data\\haarcascades \\haarcascade_frontalface_alt_tree.xml",cvSize(30,30)); storage = cvCreateMemStorage(0); // TODO: 在此添加控件通知處理程序代碼 } ~~~   初始化完成。   三、編寫人臉檢測函數     這里將人臉檢測的操作封裝成一個函數detect_and_draw(),作為成員函數添加到CGenderRecognitionMFCDlg類中: ![](https://box.kancloud.cn/2016-02-25_56ce63892ea3b.png) ?  在類視圖中找到detect_and_draw()函數,完善其人臉檢測代碼,由于之前已經詳細介紹過人臉檢測的相關操作,這里直接給出代碼: ~~~ void CGenderRecognitionMFCDlg::detect_and_draw(IplImage* img) { /**********初始化**********/ double scale = 1.2; IplImage* gray = cvCreateImage(cvSize(img->width,img->height),8,1); /**********灰度化**********/ if (img->nChannels = 3) { cvCvtColor(img,gray, CV_BGR2GRAY);//將圖像灰度化存放在gray中 } else { gray = img; } /**********直方圖均衡**********/ cvEqualizeHist(gray,gray); /**********人臉檢測**********/ cvClearMemStorage(storage); CvSeq* objects = cvHaarDetectObjects(gray,//待檢測圖像 cascade, //分類器標識 storage, //存儲檢測到的候選矩形 1.3, //相鄰兩次檢測中窗口擴大的比例 3, //認為是人臉的最小矩形數(閾值) 0, //CV_HAAR_DO_CANNY_PRUNING cvSize(30,30)); //初始檢測窗口大小 /**********繪制檢測結果**********/ if(objects->total > 0) //如果人臉檢測成功 { for (int i = 0; i < (objects ? objects->total : 0); i++) { CvRect* rect = (CvRect*)cvGetSeqElem(objects,i); cvRectangle(img,cvPoint(rect->x,rect->y), cvPoint(rect->x + rect->width,rect->y + rect->height),cvScalar(0.0,255)); } } /**********在圖像控件上顯示圖像**********/ CvvImage cvvImage; cvvImage.CopyOf(img); cvvImage.DrawToHDC(m_pPicCtlHdc,m_PicCtlRect); cvReleaseImage(&gray); } ~~~   注意這里相對于之前的程序,添加了一項直方圖均衡化的操作,以提高人臉檢測的成功率: ![](https://box.kancloud.cn/2016-02-25_56ce63893f93a.png) ?  四、調用人臉檢測函數   理論上在顯示圖像之前應該自動調用人臉檢測操作,因此在GetNextBigImg()函數中調用人臉檢測函數: ![](https://box.kancloud.cn/2016-02-25_56ce638951805.png)   由于在detect_and_draw()函數中已經封裝了picture顯示的程序,所以可以將GetNextBigImg()函數中原有的picture控件顯示程序去掉。   大功告成,順利完成人臉檢測: ![](https://box.kancloud.cn/2016-02-25_56ce6389675a2.png)   三、總結   這里我們初步完成了MFC中的人臉檢測功能,但這里存在兩個嚴重的BUG,一是如果用戶未單擊“初始化”按鈕,直接打開圖片,程序會因缺少必要的初始化步驟而直接崩潰;二是如上圖所見,OpenCv在進行人臉檢測時可能會錯誤檢測出多個矩形,其中只有一個矩形包含人臉,其余的都是干擾,需要進行處理,我們將在下一篇博客中介紹如何解決這兩個BUG。   同時在此需要強調一下兩個問題:   1、靜態成員變量的初始化:[c++中可以對類中私有成員中的靜態變量初始化嗎?](http://www.cnblogs.com/carbs/archive/2012/04/04/2431992.html)   2、字符串的連接:[C++字符換行 .](http://www.cnblogs.com/zhoug2020/archive/2012/04/01/2428156.html) ?
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看