基于opencv的肤色检测,并将肤色区域用矩形框标出。

入门,学习笔记之一,很简单,算法很傻,只能说可以实践实践大概的流程吧,欢迎评论,欢迎指导。直接上源码,觉得算法核心主要有两部分吧。第一是提取出肤色区域,第二部分连通域及其坐标值的获得。

// color_detection.cpp : 定义控制台应用程序的入口点。
//

//----------------------------------------本程序用于肤色检测-------------------------------------------//
#include "stdafx.h"
#include <cv.h>
#include <cvaux.h>
#include <highgui.h>  
#include <ml.h>
#include <cxcore.h>


//利用RGB方法进行肤色检测
void Skin_RGB_draw(IplImage *src, IplImage *dst)
{
	int step = src->widthStep;
	int channels = src->nChannels;

	static int B=0;
	static int G=0;
	static int R=0;

	cvNamedWindow("win1",1);
	cvMoveWindow("win1",100,100);
	cvNamedWindow("win2",1);

	CvMemStorage* storage = cvCreateMemStorage(0);
	CvSeq* contour = 0;
	CvSeq *contmax = 0;

	CvRect rect=cvRect(0,0,0,0);

	IplImage* _dst=cvCreateImage(cvGetSize(src),8,3);  
	cvZero(_dst);
	IplImage* _mask=cvCreateImage(cvGetSize(src),8,1);

	for (int i = 0; i < src->height; i++)
	{
		for (int j = 0; j < src->width; j++)
		{
			uchar *data_src = (uchar *)src->imageData+i*step+j*channels;
			uchar *data_dst = (uchar *)_dst->imageData+i*step+j*channels;
			B=*(data_src+0);
			G=*(data_src+1);
			R=*(data_src+2);
			if (R>95 && G>40 && B>20 && (R-B)>15 && abs(R-G)>15 && R>G && R>B) //满足肤色的条件
				{
					memcpy(data_dst,data_src,channels);
				}
				else
				{
					continue;
				}
		}
	}
	cvCvtColor(_dst,_mask,CV_RGB2GRAY);
	cvThreshold(_mask, _mask, 1, 255, CV_THRESH_BINARY );//二值化
	cvShowImage("win1",_mask);
	cvFindContours(_mask, storage, &contour, sizeof(CvContour), 
		CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE); //提取出最外面的轮廓
	double area,maxArea =100;//过滤掉连通区域过小的连通区域,阈值的确定现在固定,以后最好能做到动态确定
	for( ; contour != 0; contour = contour->h_next )		 
	{
		area =fabs(cvContourArea( contour, CV_WHOLE_SEQ )); //获取当前轮廓面积
		printf("area == %lf\n", area);
		if (area>maxArea)
		{
			contmax=contour;//找出最大连通区域
			maxArea=area;
			rect=cvBoundingRect(contmax,0);
			printf("x=%d,y=%d,width=%d,height=%d",rect.x,rect.y,rect.width,rect.height);
		}
	}
	cvRectangle(src,cvPoint(rect.x,rect.y),
			cvPoint(rect.x+rect.width,rect.y+rect.height),
			cvScalar(0,0,255),2,8,0);
	cvShowImage("win2",src);
	cvCopyImage(src,dst);
	cvReleaseImage(&_mask);
}

int _tmain(int argc, _TCHAR* argv[])
{
	IplImage *img = 0;
	IplImage *dst = 0;
	img = cvLoadImage("D:/OpenCV2.1/samples/c/sharmy.jpg",1);
	dst=cvCreateImage(cvGetSize(img),8,3);
	if (!img)
	{
		printf("could not load image");
		exit(0);
	}
	Skin_RGB_draw(img,dst);
	cvWaitKey(0);
	cvReleaseImage(&img);
    return 0;
}

检测结果:

《基于opencv的肤色检测,并将肤色区域用矩形框标出。》
下一步使用HSV方法来提取肤色区域,据大牛说,HSV颜色空间受光照影响不大,再下一步就是进入视频捕捉肤色区域。

    原文作者:爱上健身的菇凉
    原文地址: https://blog.csdn.net/XIAXIA__/article/details/8985710
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞