原理:
YCbCr颜色空间是一种常用的肤色检测的色彩模型,其中Y代表亮度(为了消除光照的影响一般放弃亮度通道),Cr代表光源中的红色分量,Cb代表光源中的蓝色分量,人体的皮肤的颜色集中在色度的较小区域内。肤色的CbCr平面分布在近似椭圆的区域内,通过判断当前像素点的CbCr值是否落在肤色分布的椭圆区域内,就可以很容易确认当前像素点是否属于肤色。。代码中用到了OpenCV的ellipse函数。
函数原型如下:
C++: void ellipse(InputOutputArray img, Point center, Size axes, double angle, double startAngle, double endAngle, const Scalar& color, int thickness=1, int lineType=LINE_8, int shift=0 )
参数意义如下:
img:椭圆图像生成存储阵列
center:椭圆的中心点坐标
axes:椭圆轴的半长度。
angle :椭圆的旋转角度
startAngle:圆弧起始角的角度。
endAngle:圆弧终结角的角度。
color:线条的颜色
thickness:线条的粗细程度,如果为负值,代表为填充
lineType:线条的类型
shift:中心点和轴长度的小数部分
示例代码如下:
图像处理开发资料、图像处理开发需求、图像处理接私活挣零花钱,可以搜索公众号"qxsf321",并关注!
//opencv版本:OpenCV3.0
//VS版本:VS2013
//Author:qxsf321.net
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/imgproc/types_c.h>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/highgui/highgui_c.h>
#include <iostream>
using namespace cv;
using namespace std;
Mat input_image;
Mat output_mask;
Mat output_image;
int main()
{
Mat input_image = imread("30.jpg");
/*椭圆皮肤模型*/
Mat skinCrCbHist = Mat::zeros(Size(256, 256), CV_8UC1);
ellipse(skinCrCbHist, Point(113, 155.6), Size(23.4, 15.2), 43.0, 0.0, 360.0, Scalar(255, 255, 255), -1);
Mat ycrcb_image;
output_mask = Mat::zeros(input_image.size(), CV_8UC1);
cvtColor(input_image, ycrcb_image, CV_BGR2YCrCb); //首先转换成到YCrCb空间
for (int i = 0; i < input_image.cols; i++) //利用椭圆皮肤模型进行皮肤检测
for (int j = 0; j < input_image.rows; j++){
Vec3b ycrcb = ycrcb_image.at<Vec3b>(j, i);
if (skinCrCbHist.at<uchar>(ycrcb[1], ycrcb[2]) > 0)
output_mask.at<uchar>(j, i) = 255;
}
input_image.copyTo(output_image, output_mask);
imshow("input image", input_image);
imshow("output mask", output_mask);
imshow("output image", output_image);
waitKey(0);
return 0;
}
运行结果截图如下图所示: