个人opencv之旅:ios人脸识别

学习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

相关文章
相关标签/搜索