開始了OpenCV的試水工作了。。。
1.Get ready
在OpenCV中我們會使用函數cv::CascadeClassifier 來進行人臉檢測。但是在使用本函數之前我們需要添加一個XML文件對該函數進行訓練。最后用一個小紅色方塊將人臉表示出來
(當然Apple自帶的函數也是可以進行人臉檢測(CIDetector )的,但是CascadeClassifier除了人臉檢測還可以檢測各種其他部位,超強大有木有~~)
2.如何實現
我們將用一下四步來實現人臉檢測的過程。
#添加XML文件到工程中
#創建函數cv::CascadeClassifier(使用XML文件內容)
#檢測一張圖像中的人臉
#畫一個紅色小四方形
3.習慣性的上代碼
#import "ViewController.h" #import <opencv2/opencv.hpp> #import <opencv2/imgproc/types_c.h> #import <opencv2/imgcodecs/ios.h> @interface ViewController () { cv::CascadeClassifier faceDetector; } @property (weak, nonatomic) IBOutlet UIImageView *imgView; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // 添加xml文件 NSString* cascadePath = [[NSBundle mainBundle] pathForResource:@"haarcascade_frontalface_alt" ofType:@"xml"]; faceDetector.load([cascadePath UTF8String]); //上傳圖片 UIImage *image = [UIImage imageNamed:@"lena1.png"]; cv::Mat faceImage; UIImageToMat(image, faceImage); // 轉為灰度 cv::Mat gray; cvtColor(faceImage, gray, CV_BGR2GRAY); // 檢測人臉並儲存 std::vector<cv::Rect>faces; faceDetector.detectMultiScale(gray, faces,1.1,2,0|CV_HAAR_SCALE_IMAGE,cv::Size(30,30)); // 在每個人臉上畫一個紅色四方形 for(unsigned int i= 0;i < faces.size();i++) { const cv::Rect& face = faces[i]; cv::Point tl(face.x,face.y); cv::Point br = tl + cv::Point(face.width,face.height); // 四方形的畫法 cv::Scalar magenta = cv::Scalar(255, 0, 255); cv::rectangle(faceImage, tl, br, magenta, 4, 8, 0); } self.imgView.image = MatToUIImage(faceImage); }
4.看結果
5.友情提示
建議使用Auto Layout
布局 + Image Assets
管理各個分辨率的圖片 + Interface Builder
(xib+storyboard)構建UI,Size Classes
在低版本iOS系統的表現未知。
想要這套手動適配方案,起碼你的工程需要部署在iOS6+,還不用AutoLayout布局的會死的蠻慘
6.解惑
為什么一定要添加xml文件呢?
其實這個xml文件就是對人臉石識別的初始化(初始化數據by Paul Viola and later extended by Rainer Lienhart),現在已經成為一種人臉識別的標准了。
為了能夠把xml文件成功倒入,我們需要把NSString object 轉化為 std::string(使用UTF8String)
經過以上的准備工作后我們就可以使用方法detectMultiScale進行人臉檢測了。
方法detectMultiScale有四個參數。分別為:
scaleFactor :制定循環遞減的圖片尺寸
minNeighbors :制定保留數據的矩形大小
CV_HAAR_SCALE_IMAGE :這是一個標志,它指定算法縮放圖像,而不是檢測器。它有助於實現最佳的性能