OpenCV肤色检测和模板匹配

        想起来做手势了,虽然OpenNI里有内置的手势识别算法,但效果似乎不是很好,于是乎就寻思着自己从头开始,包括手的侦测,跟踪,然后识别手势。不过不知道能不能做的比OpenNI内置的方法好。不管怎样先打打基础再说。于是乎拿着OpenCV瞅瞅,花了一个上午时间实验了两个内置的函数,其一为肤色检测,其二为模板匹配。下面是肤色检测代码:

#include
#include
#include

#include
using namespace std;

int main(int argc,char* argv[])
{
	IplImage* image = cvLoadImage("test.jpg");
	if(image == NULL) 
	{
		cout<<"load image failed!"<

肤色检测被内置在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);

第一个参数不知道是什么意思,第二个参数为一个枚举值,表示对结果所做的形态学操作,有四种选择。

输入图像: 输出结果:

OpenCV肤色检测和模板匹配_第1张图片OpenCV肤色检测和模板匹配_第2张图片


 

模板匹配代码:

#include
#include

#include
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的大小。

模板图像: 运行结果:

OpenCV肤色检测和模板匹配_第3张图片

由于只是选取了最优结果,所以只检测到了一只手。并且,由结果可知,模板匹配并不是那么robust.

附注:由于用的图像由kinect产生,故图像大小为640*480.

简单的肤色检测和模板匹配效果不是很好,需要改进。

http://blog.csdn.net/chenli2010/article/details/7046149

你可能感兴趣的:(OpenCV)