算法思想:主要判断YCrCb空间中以(Cr, Cb)为坐标的点是否落在肤色椭圆内,如果在椭圆内,则为肤色点。
注:RGB空间转换为YCrCb空间时要以为坐标(Cb, Cr),BGR空间转换为YCrCb空间时,要以(Cr, Cb)为坐标。
void skin_Ellipse(Mat * src, Mat * mask)
{
Mat srcImg;
src->copyTo (srcImg);
//定义肤色椭圆模型
Mat skinEllipse = Mat::zeros(Size(256,256), CV_8UC1 );
ellipse (skinEllipse, Point(113, 155.6), Size(23.4,15.2),43.0, 0.0, 360, Scalar (255,255,255),-1);//画填充的椭圆区
imshow("skinEllipse", skinEllipse );
//定义模板mask
//Mat mask = Mat::zeros(srcImg.size(), CV_8UC1 );
//将BGR转换为YCrCb空间
Mat ycrcbImg;
cvtColor (srcImg, ycrcbImg, CV_BGR2YCrCb );
imshow("ycrcbImg",ycrcbImg );
Mat Cr_Img, Cb_Img;
//肤色检测
for (int i = 0; i < ycrcbImg.rows; i++)
for (int j = 0; j < ycrcbImg.cols; j++)
{
Vec3b ycrcb = ycrcbImg.at<Vec3b>(i,j);
if (skinEllipse.at<uchar>(ycrcb[1], ycrcb[2]) > 0)
mask->at<uchar>(i,j) =255;
}
imshow("Ellipse_mask",*mask);
}
参考文献
http://www.cnblogs.com/tornadomeet/archive/2012/12/05/2802428.html
https://blog.csdn.net/qq_29540745/article/details/52589008
https://blog.csdn.net/zdx19880830/article/details/45892739
https://blog.csdn.net/wj080211140/article/details/23384927