我的opencv之旅:ios人脸识别

时间:2024-04-20 15:35:54

学习opencv有一年多了,这本来是我的毕业设计的一部分,但是因为不能突出专业重点,所以换了个课题。

opencv在vc、android、ios下都能用,其中vc和android下的教程和主题贴最多,ios最少了。

今天就来谈谈如何在ios下使用opencv,并做个人脸识别的Demo。

要使用opencv,可以自行编译库,也可以直接去官网下载编译好的库:http://opencv.org/downloads.html

把解压出来的文件夹直接拖进工程里就能用了,也可以在Build Phases 里面的link Binary With Librarises里面添加;

添加完把用到opencv的地方的.m文件改为.mm文件,因为opencv是c++写的,要让xcode知道这里既用到OC也用到C++。

然后在viewController里添加头:

#import <opencv2/opencv.hpp>
#import <opencv2/imgproc/types_c.h>
#import <opencv2/imgcodecs/ios.h>
#import <opencv2/objdetect/objdetect_c.h>

好了直接上代码:

- (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, ); //先转为灰度图
cvCvtColor(image, grayImg, CV_BGR2GRAY); //将输入图像缩小4倍以加快处理速度
int scale = ;
IplImage *small_image = cvCreateImage(cvSize(image->width/scale,image->height/scale), IPL_DEPTH_8U, );
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();
cvClearMemStorage(storage); //关键部分,使用cvHaarDetectObjects进行检测,得到一系列方框
CvSeq* faces = cvHaarDetectObjects(small_image, cascade, storage ,1.1, , CV_HAAR_DO_CANNY_PRUNING, cvSize(,), cvSize(, )); 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,, img.size.width * ,colorSpace, kCGImageAlphaPremultipliedLast|kCGBitmapByteOrderDefault); CGContextDrawImage(contextRef, CGRectMake(, , img.size.width, img.size.height), imageRef); CGContextSetLineWidth(contextRef, );
CGContextSetRGBStrokeColor(contextRef, 1.0, 0.0, 0.0, ); //对人脸进行标记,如果isDoge为Yes则在人脸上贴图
for(int i = ; 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, );
CGContextRef contextRef = CGBitmapContextCreate(iplimage->imageData, iplimage->width, iplimage->height,
iplimage->depth, iplimage->widthStep,
colorSpace, kCGImageAlphaPremultipliedLast|kCGBitmapByteOrderDefault);
CGContextDrawImage(contextRef, CGRectMake(, , image.size.width, image.size.height), imageRef);
CGContextRelease(contextRef);
CGColorSpaceRelease(colorSpace); return iplimage;
}

这是检测图片honger1的人脸有多少个,并且把它框出来的Demo

效果如下图:

我的opencv之旅:ios人脸识别

完整代码放在我的github上:https://github.com/panxiaochun/AFaceRecognizerOpenCVDemoForIOS