學習opencv有一年多了,這原本是個人畢業設計的一部分,可是由於不能突出專業重點,因此換了個課題。html
opencv在vc、android、ios下都能用,其中vc和android下的教程和主題貼最多,ios最少了。android
今天就來談談如何在ios下使用opencv,並作我的臉識別的Demo。ios
要使用opencv,能夠自行編譯庫,也能夠直接去官網下載編譯好的庫:http://opencv.org/downloads.htmlgit
把解壓出來的文件夾直接拖進工程裏就能用了,也能夠在Build Phases 裏面的link Binary With Librarises裏面添加;github
添加完把用到opencv的地方的.m文件改成.mm文件,由於opencv是c++寫的,要讓xcode知道這裏既用到OC也用到C++。xcode
而後在viewController裏添加頭:學習
#import <opencv2/opencv.hpp> #import <opencv2/imgproc/types_c.h> #import <opencv2/imgcodecs/ios.h> #import <opencv2/objdetect/objdetect_c.h>
好了直接上代碼:ui
- (void) opencvFaceDetect { UIImage * img = [UIImage imageNamed:@"honger1"]; if(img) { cvSetErrMode(CV_ErrModeParent); IplImage *image = [self CreateIplImageFromUIImage:img]; IplImage *grayImg = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1); //先轉爲灰度圖 cvCvtColor(image, grayImg, CV_BGR2GRAY); //將輸入圖像縮小4倍以加快處理速度 int scale = 4; IplImage *small_image = cvCreateImage(cvSize(image->width/scale,image->height/scale), IPL_DEPTH_8U, 1); cvResize(grayImg, small_image); //加載分類器 NSString *path = [[NSBundle mainBundle] pathForResource:@"haarcascade_frontalface_alt2" ofType:@"xml"]; CvHaarClassifierCascade* cascade = (CvHaarClassifierCascade*)cvLoad([path cStringUsingEncoding:NSASCIIStringEncoding], NULL, NULL, NULL); CvMemStorage* storage = cvCreateMemStorage(0); cvClearMemStorage(storage); //關鍵部分,使用cvHaarDetectObjects進行檢測,獲得一系列方框 CvSeq* faces = cvHaarDetectObjects(small_image, cascade, storage ,1.1, 9, CV_HAAR_DO_CANNY_PRUNING, cvSize(0,0), cvSize(0, 0)); NSLog(@"faces:%d",faces->total); cvReleaseImage(&small_image); cvReleaseImage(&image); cvReleaseImage(&grayImg); //建立畫布將人臉部分標記出 CGImageRef imageRef = img.CGImage; CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); CGContextRef contextRef = CGBitmapContextCreate(NULL, img.size.width, img.size.height,8, img.size.width * 4,colorSpace, kCGImageAlphaPremultipliedLast|kCGBitmapByteOrderDefault); CGContextDrawImage(contextRef, CGRectMake(0, 0, img.size.width, img.size.height), imageRef); CGContextSetLineWidth(contextRef, 4); CGContextSetRGBStrokeColor(contextRef, 1.0, 0.0, 0.0, 1); //對人臉進行標記,若是isDoge爲Yes則在人臉上貼圖 for(int i = 0; i < faces->total; i++) {// Calc the rect of faces CvRect cvrect = *(CvRect*)cvGetSeqElem(faces, i); CGRect face_rect = CGContextConvertRectToDeviceSpace(contextRef, CGRectMake(cvrect.x*scale, cvrect.y*scale , cvrect.width*scale, cvrect.height*scale)); CGContextStrokeRect(contextRef, face_rect); } self.opencvImageView.image = [UIImage imageWithCGImage:CGBitmapContextCreateImage(contextRef)]; CGContextRelease(contextRef); CGColorSpaceRelease(colorSpace); cvReleaseMemStorage(&storage); cvReleaseHaarClassifierCascade(&cascade); } }
-(IplImage *)CreateIplImageFromUIImage:(UIImage *)image { CGImageRef imageRef = image.CGImage; CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); IplImage *iplimage = cvCreateImage(cvSize(image.size.width, image.size.height), IPL_DEPTH_8U, 4); CGContextRef contextRef = CGBitmapContextCreate(iplimage->imageData, iplimage->width, iplimage->height, iplimage->depth, iplimage->widthStep, colorSpace, kCGImageAlphaPremultipliedLast|kCGBitmapByteOrderDefault); CGContextDrawImage(contextRef, CGRectMake(0, 0, image.size.width, image.size.height), imageRef); CGContextRelease(contextRef); CGColorSpaceRelease(colorSpace); return iplimage; }
這是檢測圖片honger1的人臉有多少個,而且把它框出來的Demospa
效果以下圖:設計
完整代碼放在個人github上:https://github.com/panxiaochun/AFaceRecognizerOpenCVDemoForIOS