OpenCV 2.4+ C++ 人臉識別

機器學習 html

  • 機器學習的目的是把數據轉換成信息。
  • 機器學習經過從數據裏提取規則或模式來把數據轉成信息。

 

人臉識別 node

  • 人臉識別經過級聯分類器對特徵的分級篩選來肯定是不是人臉。
  • 每一個節點的正確識別率很高,但正確拒絕率很低。
  • 任一節點判斷沒有人臉特徵則結束運算,宣佈不是人臉。
  • 所有節點經過,則宣佈是人臉。

工業上,經常使用人臉識別技術來識別物體。  ios

 

對圖片進行識別 算法

複製代碼
#include "opencv2/core/core.hpp" #include "opencv2/objdetect/objdetect.hpp" #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include <iostream> #include <stdio.h> using namespace std; using namespace cv; string face_cascade_name = "haarcascade_frontalface_alt.xml"; CascadeClassifier face_cascade; string window_name = "人臉識別"; void detectAndDisplay( Mat frame ); int main( int argc, char** argv ){ Mat image; image = imread( argv[1]); if( argc != 2 || !image.data ){ printf("[error] 沒有圖片\n"); return -1; } if( !face_cascade.load( face_cascade_name ) ){ printf("[error] 沒法加載級聯分類器文件!\n"); return -1; } detectAndDisplay(image); waitKey(0); } void detectAndDisplay( Mat frame ){ std::vector<Rect> faces; Mat frame_gray; cvtColor( frame, frame_gray, CV_BGR2GRAY ); equalizeHist( frame_gray, frame_gray ); face_cascade.detectMultiScale( frame_gray, faces, 1.1, 2, 0|CV_HAAR_SCALE_IMAGE, Size(30, 30) ); for( int i = 0; i < faces.size(); i++ ){ Point center( faces[i].x + faces[i].width*0.5, faces[i].y + faces[i].height*0.5 ); ellipse( frame, center, Size( faces[i].width*0.5, faces[i].height*0.5), 0, 0, 360, Scalar( 255, 0, 255 ), 4, 8, 0 ); } imshow( window_name, frame ); }
複製代碼

效果: 機器學習

 

 

CascadeClassifier類 函數

class CascadeClassifier 學習

用於檢測物體的級聯分類器類。 ui

CascadeClassifier::CascadeClassifier

從一個文件讀取分類器。 lua

C++: CascadeClassifier::CascadeClassifier(const string& filename)
參數 filename – 所要讀取分類器文件的文件名

CascadeClassifier::empty

檢查分類器是否已經載入。 spa

C++: bool CascadeClassifier::empty() const

CascadeClassifier::load

從一個文件讀取分類器。

C++: bool CascadeClassifier::load(const string&  filename)
參數 filename – 所要讀取分類器文件的文件名。文件能夠是舊版的HAAR分類器模型也能夠是新版的分類器模型。

CascadeClassifier::read

讀取一個文件存儲節點的分類器。

C++: bool CascadeClassifier::read(const FileNode& node)

CascadeClassifier::detectMultiScale

對不一樣大小的輸入圖像進行物體識別,並返回一個識別到的物體的矩陣列表。

C++: void CascadeClassifier::detectMultiScale(const Mat&  image, vector<Rect>&  objects, double  scaleFactor=1.1, int minNeighbors=3, int  flags=0, Size  minSize=Size(), Size maxSize=Size())
參數
  • image – 須要檢測的 CV_8U 輸入矩陣。
  • objects – 輸出vector載體容器用於保存被識別的物體矩陣。
  • scaleFactor – 指定每張圖片的縮小比例的參數。
  • minNeighbors – 指定每一個候選矩陣至少包含的鄰近元素個數。
  • flags – 與舊版級聯分類器模型函數cvHaarDetectObjects的flags相同. 此參數不被用於新版模型。
  • minSize – 最小可能的對象的大小,小於的對象將被忽略。
  • maxSize – 最大可能的對象的大小,大於的對象將被忽略。

CascadeClassifier::setImage

設置被用於檢測的圖像。

C++: bool CascadeClassifier::setImage(Ptr<FeatureEvaluator>& feval, const Mat&  image)
參數
  • feval – 用於特徵計算的特徵求值程序的指針。
  • image – 須要進行特徵檢測的 CV_8U 輸入矩陣。

這個函數將在每張圖片中被 CascadeClassifier::detectMultiScale() 自動調用。 但若是你想在不一樣位置手動使用 CascadeClassifier::runAt(),你須要先調用該函數,使得圖像被積分計算。

CascadeClassifier::runAt

在指定點運行檢測。

C++: int CascadeClassifier::runAt(Ptr<FeatureEvaluator>& feval, Point  pt, double&  weight)
參數

feval – 用於特徵計算的特徵求值程序。

pt – 指定檢測窗口左上角的點。窗口的大小和檢測的圖片大小一致。

若是級聯分類器檢測到給定的位置中的一個對象,該函數返回1。不然,它會返回已被否決的候選區域在哪一個階段的否認的指數

使用CascadeClassifier::setImage() 設置圖像的檢測工做

代碼註釋:

複製代碼
//須要載入的級聯分類器文件 string face_cascade_name = "haarcascade_frontalface_alt.xml"; //級聯分類器類 CascadeClassifier face_cascade; //…… //載入級聯分類器,並判斷是否載入成功,若是不成功則打印提示 if( !face_cascade.load( face_cascade_name ) ){ printf("[error] 沒法加載級聯分類器文件!\n"); return -1; } //…… //對圖片frame進行識別檢測 face_cascade.detectMultiScale( frame_gray, faces, 1.1, 2, 0|CV_HAAR_SCALE_IMAGE, Size(30, 30) );
複製代碼

 

轉換成灰度圖

因爲CascadeClassifier類只支持CV_8U矩陣數據,因此咱們須要將圖片變成灰度圖。

cvtColor API:

將圖片從一個色彩空間轉到另外一個色彩空間。

C++: void cvtColor(InputArray  src, OutputArray  dst, int code, int  dstCn=0 )
參數
  • src – 輸入圖像:8位無符號,16位無符號(CV_16UC...),或單精度浮點數據類型。
  • dst – 輸出圖像,與輸入圖像相同大小、深度。
  • code – 顏色空間轉換代碼
  • dstCn – 目標圖像的通道數,當該參數爲0時,則通道樹由src和code自動得出。

該函數將輸入圖片從一個色彩空間轉到另外一個色彩空間。當從RGB顏色空間進行變換時,應明確指定的信道的順序(RGB或BGR)。值得注意,在OpenCV的默認顏色格式中,一般被稱爲做爲RGB,但其實是BGR(字節是相反的)。所以,在一個標準的(24位)的彩色圖像的第一個字節是一個8位的藍色份量,第二個字節將是綠色的,第三個字節將是紅色的。而第四,第五,和第六字節,則是第二像素(藍,而後綠色,而後紅色),依此類推。

R、G和B 通道一般信道值範圍:

  • CV_8U:0 — 255
  • CV_16U:0 — 65535
  • CV_32F:0 — 1

線性變換的狀況下,有沒有範圍是無所謂的。可是,在一個非線性變換的狀況下,輸入的RGB圖像應被歸爲適當的值範圍內,以獲得正確的結果。例如,若是你有一個32位浮點圖像直接轉換成一個8位的圖像而沒有任何縮放,那麼它將有0到255的數值範圍,而這並不能準確0..1全部浮點數的值。因此,你須要以前調用cvtColor,進行圖像縮放。

代碼註釋:

//將frame轉換成灰度圖,輸出到frame_gray cvtColor( frame, frame_gray, CV_BGR2GRAY );

 

直方圖均衡化

  • 直方圖是圖像中像素強度分佈的圖形表達方式。
  • 它統計了每個強度值所具備的像素個數。

  http://www.cnblogs.com/http://www.cnblogs.com/../_images/Histogram_Equalization_Theory_0.jpg

  • 直方圖均衡化是經過拉伸像素強度分佈範圍來加強圖像對比度的一種方法。
  • 說得更清楚一些, 以上面的直方圖爲例, 你能夠看到像素主要集中在中間的一些強度值上. 直方圖均衡化要作的就是 拉伸 這個範圍. 見下面左圖: 綠圈圈出了 少有像素分佈其上的 強度值. 對其應用均衡化後, 獲得了中間圖所示的直方圖. 均衡化的圖像見下面右圖.

  http://www.cnblogs.com/http://www.cnblogs.com/../_images/Histogram_Equalization_Theory_1.jpg

咱們利用直方圖均衡化對圖片加強對比度,方便級聯分類器分析。

equalizeHist API:

對灰度圖像進行直方圖均衡。

C++: void equalizeHist(InputArray  src, OutputArray  dst)
參數
  • src – 源爲8位單通道圖像。
  • dst – 輸出圖像,和源圖片一樣大小類型。

直方圖均衡函數使用了下列的算法:

  1. 計算源文件的直方圖 H 。

  2. 調整直方圖,使得其方格總個數爲255。

  3. 對直方圖進行積分:

    H'_i =  \sum _{0  \le j < i} H(j)

  4. 使用 H' 變換圖片,其映射函數爲:\texttt{dst}(x,y) = H'(\texttt{src}(x,y))

該算法歸一化亮度並增長了圖像的對比度。

 

 

 

被山寨的原文

Cascade Classifier . OpenCV.org

Cascade Classification API . OpenCV.org

Histogram Equalization . OpenCV.org

相關文章
相關標籤/搜索