【OpenCV】基于HSV的肤色分割

时间:2022-11-30 21:17:44
//函数功能:在HSV颜色空间对图像进行肤色模型分割 //输入:src-待处理的图像,imgout-输出图像 //返回值:返回一个iplimgae指针,指向处理后的结果 IplImage* SkinSegmentHSV(IplImage* src,IplImage* imgout)

{

//定义一些中间指针,指向处理过程中的中间变量

IplImage* HSV = NULL;

IplImage* HImg= NULL;

IplImage* SImg= NULL;

IplImage* VImg= NULL;

//指向处理后的结果

IplImage* result = NULL;

if (!src||!imgout) { return NULL; }

//获取输入图像的大小

CvSize SrcSize = cvGetSize(src);

//为中间结果指针分配存储空间

HSV = cvCreateImage(SrcSize,8,3);

HImg= cvCreateImage(SrcSize,8,1);

SImg= cvCreateImage(SrcSize,8,1);

VImg= cvCreateImage(SrcSize,8,1);

result= cvCreateImage(cvGetSize(imgout),8,1);

//将图像从RGB颜色空间转换到HSV空间

cvCvtColor(src,HSV,CV_BGR2HSV);

//将HSV分解为三张单通道图像,便于后面就行处理

cvSplit(HSV,HImg,SImg,VImg,NULL);

int i,j; int value = 0;

//对通道H进行处理

for (i = 0; i < HImg->height; i++)

{

for (j = 0; j < HImg->width; j++)

{

value = cvGetReal2D(HImg,i,j);

if (value >=0 && value <= 25)

{ *(HImg->imageData+i*HImg->widthStep+j) = 255; }

else { *(HImg->imageData+i*HImg->widthStep+j) = 0; }

}

}

//对通道S进行处理

for (i = 0; i < SImg->height; i++) { for (j = 0; j < SImg->width; j++)

{ value = cvGetReal2D(SImg,i,j);

if (value >=26 && value <= 200)

{ *(SImg->imageData+i*SImg->widthStep+j) = 255; }

else { *(SImg->imageData+i*SImg->widthStep+j) = 0; }

}

}

//对通道V进行处理

for (i = 0; i < VImg->height; i++) {

for (j = 0; j < VImg->width; j++) {

value = cvGetReal2D(VImg,i,j);

if (value >=20 && value <= 200) { *(VImg->imageData+i*VImg->widthStep+j) = 255; }

else { *(VImg->imageData+i*VImg->widthStep+j) = 0; } } }

cvAnd(HImg,SImg,result,0);

cvAnd(VImg,result,result,0);

//对所得到的结果进行形态学腐蚀处理,去除小区域部分

cvErode(result,result); cvErode(result,result); cvErode(result,result); cvDilate(result,result);

//将处理后的结果赋值给输出图像

cvCopy(result,imgout);

//释放相关资源

cvReleaseImage(&src); cvReleaseImage(&HSV); cvReleaseImage(&HImg); cvReleaseImage(&SImg); cvReleaseImage(&VImg); cvReleaseImage(&result);

//返回处理后的结果

return imgout;

}