下面是肤色检测代码:
#include<cv.h>
#include<highgui.h>
#include<opencv2/contrib/contrib.hpp>
#include<iostream>
using namespace std;
int main(int argc,char* argv[])
{
IplImage* image = cvLoadImage("test.jpg");
if(image == NULL)
{
cout<<"load image failed!"<<endl;
return -1;
}
IplImage* mask = cvCreateImage(cvGetSize(image),IPL_DEPTH_8U,1);
cvZero(mask);
CvAdaptiveSkinDetector skinDetector(1,CvAdaptiveSkinDetector::MORPHING_METHOD_NONE);
skinDetector.process(image,mask);
cvSet(mask,cvScalar(255),mask);
cvShowImage("image",image);
cvShowImage("mask",mask);
while(cvWaitKey(20) != 27);
cvDestroyAllWindows();
cvReleaseImage(&image);
cvReleaseImage(&mask);
return 0;
}
肤色检测被内置在opencv2/contrib/contrib.hpp里的CvAdaptiveSkinDetector类中。其主要检测函数为:
CvAdaptiveSkinDetector::process(IplImage* image, IplImage* mask);
该函数接受一个图像image,然后将检测结果返回到mask中。mask为一个二值图像,背景像素值为0,前景像素值为1。类CvAdaptiveSkinDetector只有一个构造函数:
CvAdaptiveSkinDetector(int samplingDivider = 1, int morphingMethod = MORPHING_METHOD_NONE);
第一个参数不知道是什么意思,第二个参数为一个枚举值,表示对结果所做的形态学操作,有四种选择。
模板匹配代码:
#include<cv.h>
#include<highgui.h>
#include<iostream>
using namespace std;
int main(void)
{
IplImage* palmTempl = cvLoadImage("template.jpg");
IplImage* result = NULL;
CvRect imageROI = cvRect(0,0,640,480);
for(int i=0;i<1000;i++)
{
char fileName[80];
sprintf(fileName,"image//%d.jpg",i);
IplImage* palmImage = cvLoadImage(fileName);
if(palmImage == NULL) continue;
CvSize size;
size.width = imageROI.width-palmTempl->width+1;
size.height = imageROI.height-palmTempl->height+1;
result = cvCreateImage(size,IPL_DEPTH_32F,1);
cvSetImageROI(palmImage,imageROI);
cvMatchTemplate(palmImage,palmTempl,result,CV_TM_SQDIFF);
cvResetImageROI(palmImage);
double min, max;
CvPoint minLoc;
cvMinMaxLoc(result,&min,&max,&minLoc,NULL);
minLoc.x = minLoc.x+imageROI.x;
minLoc.y = minLoc.y+imageROI.y;
CvPoint point2 = cvPoint(minLoc.x+palmTempl->width,minLoc.y+palmTempl->height);
cvRectangle(palmImage,minLoc,point2,cvScalar(255,255,255));
cvShowImage("image",palmImage);
cvReleaseImage(&palmImage);
if(cvWaitKey(10) == 27) break;
imageROI.x = minLoc.x-palmTempl->width/2>0 ? minLoc.x-palmTempl->width/2 : 0;
imageROI.y = minLoc.y-palmTempl->height/2>0 ? minLoc.y-palmTempl->height/2 : 0;
imageROI.width = 2*palmTempl->width;
imageROI.height = 2*palmTempl->height;
}
cvReleaseImage(&palmTempl);
return 0;
}
OpenCV中的template matching也可以支持imageROI,只是结果矩阵result的大小是严格限制了的,imageROI的改变必然导致result矩阵大小的改变,所以用imageROI还得颇费些周折。在每一步根据imageROI去调整result的大小。