赞
踩
使用opencv检测bmp图片中人脸,主要使用cvHaarDetectObjects函数实现。
函数定义
CvSeq* cvHaarDetectObjects( const CvArr* image, CvHaarClassifierCascade* cascade,
CvMemStorage* storage, double scale_factor=1.1,
int min_neighbors=3, int flags=0, CvSize(min_size=cvSize(0,0) ,CvSize max_size=cvSize(0,0));
参数说明
image 被检图像
cascade haar 分类器级联的内部标识形式
storage 用来存储检测到的一序列候选目标矩形框的内存区域。
scale_factor 在前后两次相继的扫描中,搜索窗口的比例系数。例如1.1指将搜索窗口依次扩大10%
min_neighbors 构成检测目标的相邻矩形的最小个数(缺省-1)。如果组成检测目标的小矩形的个数和小于min_neighbors-1 都会被排除。如果min_neighbors 为 0, 则函数不做任何操作就返回所有的被检候选矩形框,这种设定值一般用在用户自定义对检测结果的组合程序上。
flags 操作方式。当前唯一可以定义的操作方式是 CV_HAAR_DO_CANNY_PRUNING。如果被设定,函数利用Canny边缘检测器来排除一些边缘很少或者很多的图像区域,因为这样的区域一般不含被检目标。人脸检测中通过设定阈值使用了这种方法,并因此提高了检测速度。
min_size 检测窗口的最小尺寸。缺省的情况下被设为分类器训练时采用的样本尺寸(人脸检测中缺省大小是~20×20)。
具体函数调用
faces = cvHaarDetectObjects(imgTmp, cascade, storage, 1.5, 4, 0, cvSize(50,50) );
cascade是加载了haarcascade_frontalface_alt2.xml人脸标识的文件。
返回值faces是检测到的人脸信息,包括坐标和宽高信息。
根据faaces中的信息,再利用cvRectangle函数,将人脸的矩形框绘制出来。
/******************************************************* * file:testFace.c * date:2021-07-17 * version:1.0.0.1 * author:jack8126 * description: bmp file, dectect face *******************************************************/ #include "cv.h" #include "highgui.h" #include "stdio.h" #include <sys/time.h> int main(int argc, char* argv[]) { struct timeval timeStart,timeEnd; unsigned long timeCount; char u8PicNameRead[64] = {0}; char u8PicNameOut[64] = {0}; int i = 0; if(argc < 3) { printf("please input like this:\r\n"); printf("./testFace.bin test.bmp test-out.bmp\r\n"); printf("test.bmp ---------------- input file \r\n"); printf("test-out.bmp ------------ output file \r\n"); return -1; } sprintf(u8PicNameRead,"%s",argv[1]); sprintf(u8PicNameOut,"%s",argv[2]); printf("u8PicNameRead=%s\r\n",u8PicNameRead); IplImage* img = NULL; IplImage* cutImg = NULL; CvMemStorage* storage = cvCreateMemStorage(0); CvHaarClassifierCascade* cascade = (CvHaarClassifierCascade*)cvLoad("./haarcascade_frontalface_alt2.xml", 0, 0, 0); CvSeq* faces; //加载图像 img = cvLoadImage(u8PicNameRead, 1); // 0 - gray; 1 - color //缩放到1/2大小 IplImage *imgTmp = cvCreateImage(cvSize(img->width, img->height), 8, img->nChannels); printf("imgTmp w=%d h=%d\n", imgTmp->width, imgTmp->height); cvResize(img, imgTmp); //检测并计时 gettimeofday(&timeStart,0); faces = cvHaarDetectObjects(imgTmp, cascade, storage, 1.5, 4, 0, cvSize(50,50) ); gettimeofday(&timeEnd,0); timeCount = (timeEnd.tv_sec-timeStart.tv_sec)*1000000 + timeEnd.tv_usec-timeStart.tv_usec; printf("use time: %uus\n",timeCount); if (faces->total == 0){ printf("no face!\n"); goto ERROR; } for( i = 0; i < (faces ? faces->total : 0); i++ ) { CvRect* r = (CvRect*)cvGetSeqElem( faces, i ); printf("face detected! i=%d, x=%d, y=%d\n",i, r->x,r->y); printf("face detected! i=%d, width=%d, height=%d\n",i, r->width,r->height); cvRectangle(img, cvPoint(r->x, r->y), cvPoint(r->x + r->width, r->y + r->height), cvScalar(255, 0, 0), 1 ); } cvSaveImage(u8PicNameOut, img); cvResetImageROI(img); printf("face detected! in face.bmp! total:%d\n",faces->total); ERROR: //释放内存 cvReleaseImage(&img); cvReleaseImage(&imgTmp); return 0; }
makefile文件
PWD_DIR := $(shell pwd) OPENCV_BASE_DIR := /usr/local/ OPENCV_DIR := -I$(OPENCV_BASE_DIR)/include OPENCV1_DIR := -I$(OPENCV_BASE_DIR)/include/opencv OPENCV2_DIR := -I$(OPENCV_BASE_DIR)/include/opencv2 OPENCV_LIB_DIR := -L$(OPENCV_BASE_DIR)lib/ OPENCV_LIB_DIR2 := -L$(OPENCV_BASE_DIR)lib/ OPENCV_LIBS := $(OPENCV_LIB_DIR)libopencv_highgui.a\ $(OPENCV_LIB_DIR)libopencv_core.a\ $(OPENCV_LIB_DIR)libopencv_imgproc.a\ $(OPENCV_LIB_DIR)libopencv_objdetect.a INC_FLAGS := $(OPENCV_DIR) $(OPENCV1_DIR) $(OPENCV2_DIR) SRC := $(wildcard *.c) OBJ := $(SRC:%.c=%.o) TARGET := $(OBJ:%.o=%) .PHONY : clean all all: testFace.bin testFace.bin: g++ -g testFace.cpp $(INC_FLAGS) -lpthread -lrt -lopencv_highgui -lopencv_core -lopencv_imgproc -lopencv_objdetect -o testFace.bin clean: rm testFace.bin
编译命令如下
make
执行完上述命令之后,会生成testOpenCvBinarization.bin文件,后面执行程序时需要该文件。
使用如下命令执行程序,可检测出bmp图片中的人脸。
执行完上述命令后,生成image-out.bmp文件。
原图
检测后的图片
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。