OpenCV入門指南----人臉檢測

本篇介紹圖像處理與模式識別中最熱門的一個領域——人臉檢測(人臉識別)。人臉檢測可以說是學術界的寵兒,在不少EI,SCI高級別論文都能看到它的身影。甚至很多高校學生的畢業設計都會涉及到人臉檢測。當然人臉檢測的巨大實用價值也讓很多公司紛紛關注,很多公司都擁有這方面的專利或是開發商業產品出售。

????在OpenCV中,人臉檢測也是其熱門應用之一。在OpenCV的特征檢測專題就詳細介紹了人臉檢測的原理——通過Haar特征來識別是否為人臉。Haar特征檢測原理與Haar特征分類器的訓練放到下一篇《【OpenCV入門指南】第十四篇? Haartraining》來講,本篇主要介紹如何在OpenCV中使用Haar特征分類器來對圖像中的人臉進行檢測和識別。下面將分成五步來詳細示范如何在OpenCV中進行人臉識別:

??? 一.人臉的Haar特征分類器是什么

??? 二.在哪找人臉的Haar特征分類器

??? 三.怎么用人臉的Haar特征分類器

??? 四.人臉識別示例代碼

??? 五.人臉識別程序運行結果

一.人臉的Haar特征分類器是什么

人臉的Haar特征分類器就是一個XML文件,該文件中會描述人臉的Haar特征值。當然Haar特征的用途可不止可以用來描述人臉這一種,用來描述眼睛,嘴唇或是其它物體也是可以的。

二.在哪找人臉的Haar特征分類器

OpenCV有已經自帶了人臉的Haar特征分類器。OpenCV安裝目錄中的\data\ haarcascades目錄下的haarcascade_frontalface_alt.xml與haarcascade_frontalface_alt2.xml都是用來檢測人臉的Haar分類器。這個haarcascades目錄下還有人的全身,眼睛,嘴唇的Haar分類器。讀者可以仿照本方的例子來試驗下效果看看。

三.怎么用人臉的Haar特征分類器

使用人臉的Haar特征分類器非常之簡單,直接使用cvHaarDetectObjects。下面來看看這個函數的介紹:

函數功能:檢測圖像中的目錄

函數原型:

CVAPI(CvSeq*)?cvHaarDetectObjects(

? const?CvArr*?image,

? CvHaarClassifierCascade*?cascade,

? CvMemStorage*?storage,

? double?scale_factor?CV_DEFAULT(1.1),

? int?min_neighbors?CV_DEFAULT(3),

? int?flags?CV_DEFAULT(0),

? CvSize?min_size?CV_DEFAULT(cvSize(0,0)),

? CvSize?max_size?CV_DEFAULT(cvSize(0,0))

);

函數說明:

第一個參數表示輸入圖像,盡量使用灰度圖以加快檢測速度。

第二個參數表示Haar特征分類器,可以用cvLoad()函數來從磁盤中加載xml文件作為Haar特征分類器。

第三個參數為CvMemStorage類型,大家應該很熟悉這個CvMemStorage類型了,《OpenCV入門指南》中很多文章都介紹過了。

第四個參數表示在前后兩次相繼的掃描中,搜索窗口的比例系數。默認為1.1即每次搜索窗口依次擴大10%

第五個參數表示構成檢測目標的相鄰矩形的最小個數(默認為3個)。如果組成檢測目標的小矩形的個數和小于?min_neighbors - 1?都會被排除。如果min_neighbors?為?0,?則函數不做任何操作就返回所有的被檢候選矩形框,這種設定值一般用在用戶自定義對檢測結果的組合程序上。

第六個參數要么使用默認值,要么使用CV_HAAR_DO_CANNY_PRUNING,如果設置為CV_HAAR_DO_CANNY_PRUNING,那么函數將會使用Canny邊緣檢測來排除邊緣過多或過少的區域,因此這些區域通常不會是人臉所在區域。

第七個,第八個參數表示檢測窗口的最小值和最大值,一般設置為默認即可。

函數返回值:

函數將返回CvSeq對象,該對象包含一系列CvRect表示檢測到的人臉矩形。

四.人臉識別示例代碼

下面給出一個完整的示例代碼,代碼中的GetTickCount可以參閱《Windows?各種計時函數總結》,cvEqualizeHist可以參閱《【OpenCV入門指南】第八篇灰度直方圖》。

// FaceDetect.cpp : 定義控制臺應用程序的入口點。
// 本文配套博客文章地址: http://blog.csdn.net/morewindows/article/details/8426318  

#include "stdafx.h"#include <iostream>
#include <opencv2/core/core.hpp>   //cvGetSize  cvCreateImage
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/opencv.hpp>  //cvResize cvInitMatHeader cvGetMinMaxHistValue cvCvtColor
#include <opencv2/imgproc/imgproc.hpp>#include <Windows.h>   //DWORD  GetTickCount()

#ifdef _DEBUG
#pragma comment(lib, "opencv_core244d")
#pragma comment(lib, "opencv_highgui244d")
#pragma comment(lib, "opencv_imgproc244d")  //cvResize 
#pragma comment(lib, "opencv_objdetect244d")  //cvHaarDetectObjects
#else
#pragma comment(lib, "opencv_core244")
#pragma comment(lib, "opencv_highgui244")
#pragma comment(lib, "opencv_imgproc244")  //cvResize
#pragma comment(lib, "opencv_objdetect244") //cvHaarDetectObjects
#endifusing namespace std;  
int main()  
{  // 加載Haar特征檢測分類器  // haarcascade_frontalface_alt.xml系OpenCV自帶的分類器 下面是我機器上的文件路徑  const char *pstrCascadeFileName = "G:\\Software\\openCV\\opencv\\data\\haarcascades\\haarcascade_frontalface_alt.xml";  CvHaarClassifierCascade *pHaarCascade = NULL;  pHaarCascade = (CvHaarClassifierCascade*)cvLoad(pstrCascadeFileName);  // 載入圖像  const char *pstrImageName = "./images/linzhiling.jpg";  //const char *pstrImageName = "./images/liuyifei.jpg";  //const char *pstrImageName = "./images/unknown.jpg";  IplImage *pSrcImage = cvLoadImage(pstrImageName, CV_LOAD_IMAGE_UNCHANGED);  IplImage *pGrayImage = cvCreateImage(cvGetSize(pSrcImage), IPL_DEPTH_8U, 1);  cvCvtColor(pSrcImage, pGrayImage, CV_BGR2GRAY);  // 人臉識別與標記  if (pHaarCascade != NULL)  {         CvScalar FaceCirclecolors[] =   {  {{0, 0, 255}},  {{0, 128, 255}},  {{0, 255, 255}},  {{0, 255, 0}},  {{255, 128, 0}},  {{255, 255, 0}},  {{255, 0, 0}},  {{255, 0, 255}}  };  CvMemStorage *pcvMStorage = cvCreateMemStorage(0);  cvClearMemStorage(pcvMStorage);  // 識別  
        DWORD dwTimeBegin, dwTimeEnd;  dwTimeBegin = GetTickCount();  //函數將返回CvSeq對象,該對象包含一系列CvRect表示檢測到的人臉矩形//第一個參數表示輸入圖像,盡量使用灰度圖以加快檢測速度//第二個參數表示Haar特征分類器,可以用cvLoad()函數來從磁盤中加載xml文件作為Haar特征分類器//第三個參數為CvMemStorage類型//第四個參數表示在前后兩次相繼的掃描中,搜索窗口的比例系數。默認為1.1即每次搜索窗口依次擴大10%//第五個參數表示構成檢測目標的相鄰矩形的最小個數(默認為3個)。如果組成檢測目標的小矩形的個數和小于 min_neighbors - 1 都會被排除。//如果min_neighbors 為 0, 則函數不做任何操作就返回所有的被檢候選矩形框,這種設定值一般用在用戶自定義對檢測結果的組合程序上//第六個參數要么使用默認值,要么使用CV_HAAR_DO_CANNY_PRUNING,如果設置為CV_HAAR_DO_CANNY_PRUNING,那么函數將會使用Canny邊緣檢測//來排除邊緣過多或過少的區域,因此這些區域通常不會是人臉所在區域//第七個,第八個參數表示檢測窗口的最小值和最大值,一般設置為默認即可CvSeq *pcvSeqFaces = cvHaarDetectObjects(pGrayImage, pHaarCascade, pcvMStorage);  dwTimeEnd = GetTickCount();  printf("人臉個數: %d   識別用時: %d ms\n", pcvSeqFaces->total, dwTimeEnd - dwTimeBegin);  // 標記  for(int i = 0; i <pcvSeqFaces->total; i++)  {  CvRect* r = (CvRect*)cvGetSeqElem(pcvSeqFaces, i);  //用圓形畫出臉部部分
            CvPoint center;  int radius;  center.x = cvRound((r->x + r->width * 0.5));  center.y = cvRound((r->y + r->height * 0.5));  radius = cvRound((r->width + r->height) * 0.25);  cvCircle(pSrcImage, center, radius, FaceCirclecolors[i % 8], 2); //用矩形畫出臉部部分/*CvPoint startPoint,endPoint;startPoint.x = cvRound(r->x);startPoint.y = cvRound(r->y);endPoint.x = cvRound(r->x + r->width);endPoint.y = cvRound(r->x + r->height);cvRectangle(pSrcImage,startPoint,endPoint,FaceCirclecolors[i % 8]);*/}  cvReleaseMemStorage(&pcvMStorage);  }  const char *pstrWindowsTitle = "人臉識別";  cvNamedWindow(pstrWindowsTitle, CV_WINDOW_AUTOSIZE);  cvShowImage(pstrWindowsTitle, pSrcImage);  cvWaitKey(0);  cvDestroyWindow(pstrWindowsTitle);  cvReleaseImage(&pSrcImage);   cvReleaseImage(&pGrayImage);  return 0;  
}
View Code

五.人臉識別程序運行結果

運行結果一(單人正面):

這張圖的干擾太少,換張干擾大點的圖來試試。

?

運行結果二:

?

運行結果三(多人):

?

本文轉自:http://blog.csdn.net/morewindows/article/details/8426318

轉載于:https://www.cnblogs.com/tianyalu/p/5689285.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/372629.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/372629.shtml
英文地址,請注明出處:http://en.pswp.cn/news/372629.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

matlab提取艾里斑,艾里斑:我不是雀斑

正是艾里斑&#xff0c;限制了光學儀器的精度我們知道凸透鏡能把入射光會聚到它的焦點上&#xff0c;由于透鏡的口徑有一定大小&#xff0c;限制了光線的傳播&#xff0c;所以凸透鏡也會發生衍射。這導致透鏡無法把光線會聚成無限小的點&#xff0c;而只會在焦點上形成具有一定…

mysql啟動錯誤排查-無法申請足夠內存

一般情況下mysql的啟動錯誤還是很容易排查的&#xff0c;但是今天我們就來說一下不一般的情況。拿到一臺服務器&#xff0c;安裝完mysql后進行啟動&#xff0c;啟動錯誤如下&#xff1a; 有同學會說&#xff0c;哥們兒你是不是buffer pool設置太大了&#xff0c;設置了96G內存。…

Spring vs Guice:重要的一個關鍵區別

根據彈簧對象的名稱識別它們 不管使用XML還是Java配置都沒有關系&#xff0c;Spring范圍大致類似于Map <String&#xff0c;Object>結構。 這意味著您不能有兩個名稱相同的對象 。 為什么這是一件壞事&#xff1f; 如果您的大型應用程序包含許多Configuration類或XML文件…

php 批量更新死鎖,php – 在嘗試獲取鎖定時,哪個查詢導致死鎖;嘗試重新啟動事務...

我無法弄清楚哪個Query在嘗試獲取鎖定時導致死鎖;嘗試重新啟動事務.我的mysql包裝器有以下幾行if (mysql_errno($this->conn) 1213) {$this->bug_log(0,"Deadlock. SQL:".$this->sql);}bug_log寫入文件的位置.錯誤日志文件沒有死鎖錯誤,但/var/log/mysqld.…

Task和BackTask

一、總結性知識點&#xff1a; 1、Android應用運行時會創建任務Task&#xff0c;用于存放主窗口2、每一個任務包含一個堆棧數據結構&#xff0c;用于保存當前應用已創建的窗口對象&#xff0c;這個堆棧即回退棧BackStack3&#xff64; 位于回退棧頂的窗口會處于焦點狀態4&#…

Java面試題二

1、public、private、protected、Friendly的區別與作用域 public,protected,friendly,private的訪問權限如下&#xff1a; 關鍵字 當前類 包內 子孫類 包外 public √ √ √ √ protected…

使用Spring Roo進行快速云開發–第1部分:Google App Engine(GAE)

Spring Roo是在Java平臺上提供快速應用程序開發的工具。 我已經解釋了何時使用它&#xff1a; http : //www.kai-waehner.de/blog/2011/04/05/when-to-use-spring-roo 。 Spring Roo目前支持兩種針對云計算的解決方案&#xff1a;Google App Engine&#xff08;GAE&#xff09;…

mysql 重裝,Windows系統中完全卸載MySQL數據庫實現重裝mysql

一、在控制面板&#xff0c;卸載MySQL的所有組件控制面板——》所有控制面板項——》程序和功能&#xff0c;卸載所有和MySQL有關的程序二、找到你的MysQL安裝路徑&#xff0c;看還有沒有和MySQL有關的文件夾&#xff0c;全刪如果安裝在C盤&#xff0c;檢查一下C:\Program File…

loadrunner 關聯

1、記住關聯的位置&#xff08;之前&#xff09;&#xff0c;因為登錄之前需要token&#xff0c;才能驗證登錄是否成功&#xff0c;所以&#xff0c;放在登錄之前 轉載于:https://www.cnblogs.com/zyp1/p/5692343.html

網頁上線后音頻不能自動播放

一、問題描述 開發環境谷歌瀏覽器本地測試通過&#xff0c;網站上線后的音樂不播放&#xff0c;而是自動下載&#xff1f; 開發環境safari瀏覽器中&#xff0c;音頻不播放。 二、問題分析 用audio或者embed標簽都有問題&#xff0c;為了節省用戶的流量&#xff0c;安卓和ios都默…

Akka STM –與STM Ref和Agent進行乒乓球比賽

乒乓是一個經典示例&#xff0c;其中2個玩家&#xff08;或線程&#xff09;訪問共享資源–乒乓球桌并在彼此之間傳遞Ball&#xff08;狀態變量&#xff09;。 使用任何共享資源&#xff0c;除非我們同步訪問&#xff0c;否則線程可能會遇到潛在的死鎖情況。 PingPong算法非常簡…

c mysql二進制,MySQL運用connector C/C+讀取二進制字段

MySQL使用connector C/C讀取二進制字段MySQL使用connector C/C讀取二進制字段&#xff0c;兩種方法&#xff1a;用getStringvector vec;while (pResultSet->next()){string str pResultSet->getString("data");vec.insert(vec.end(), str.begin(), str.end())…

在下一個項目中不使用JavaDoc的5大原因

JavaDoc對于框架和庫的開發是絕對必要的&#xff0c;這些框架和庫為其他框架&#xff08;例如Spring Framework&#xff0c;JDK&#xff09;提供了公共接口。 對于內部企業軟件和/或產品開發&#xff0c;我有以下原因會在將來忽略“ 100&#xff05;JavaDoc策略”。 1&#xff…

NPOI操作Excel輔助類

/// <summary> /// NPOI操作excel輔助類 /// </summary> public static class NPOIHelper {#region 定義與初始化public static HSSFWorkbook workbook;[Flags]public enum LinkType{網址,檔案,郵件,內容};private static void InitializeWorkbook(){if (workbook …

JSP九大內置對象,七大動作,三大指令

JSP之九大內置對象 隱藏對象入門探索 Servlet 和JSP中輸出數據都需要使用out對象。Servlet 中的out對象是通過getWriter()方法獲取的。而JSP中沒有定義out對象卻可以直接使用。這是因為out是JSO的內置隱藏對象。JSP中的常見的9個內置隱藏對象如下 out輸出流對象 隱藏對象out是…

matlab變步長的梯形公式,用變步長梯形法計算積分∫sinx/x*x的近似值(二分二次即可)...

共回答了20個問題采納率&#xff1a;90%題目沒寫全吧?現假定積分區間為[0,1],教材《數值分析》(華中科技大學出版)第87頁,例題4.2就有詳細的解答.貌似題目也有錯?確定分母是【x^2】?現在附上該例題(分母是x)的全部解答過程&#xff1a;先對整個區間[0,1]使用梯形公式.對于函…

使用Cloud SQL的Google App Engine全文搜索

許多Google AppEngine開發人員一直在等待全文搜索功能&#xff0c;特別是來自網絡上最大的搜索引擎Google。 很高興看到Google團隊正在努力&#xff0c;您可以在Google I / O 2011大會上簽到&#xff1a; Bo Majewski和Ged Ellis進行的全文本搜索 。 據我所知&#xff0c;非常有…

php 數組值sum,php sum數組值(如果特定列的值重復)

我有一個陣列。我要檢查是否有重復的費用,如果有,我要用相同的費用列匯總所有值。[12] > Array([type] > Other Miscellaneous Fees[fee] > 158[amount] > -22.56[code] > COL_AUDIO[feedesc] > COLLEGE AUDIO VISUAL FEE)[13] > Array([type] > Other…

hdu-5734 Acperience(數學)

題目鏈接&#xff1a; Acperience Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Problem DescriptionDeep neural networks (DNN) have shown significant improvements in several application domains including computer vision and…

Ninject依賴注入(一)

Ninject學習筆記&#xff08;一&#xff09; Ninject學習筆記&#xff08;一&#xff09;理解依賴注入DI概念什么是DI&#xff1f;DI是如何工作的&#xff1f;什么是DI容器使用Ninject如何使用NinjectNinject對象生命周期暫時范圍單例范圍線程范圍請求范圍自定義范圍Ninject模塊…