继续创作,加快生长!这是我参加「日新方案 10 月更文挑战」的第18天,点击检查活动概况
前言
色彩信息对于特定目标的初始检测非常有用。例如,辅助驾驶应用程序中的路途标志检测能够依托规范标志的色彩来快速提取潜在的候选路途标志。皮肤色彩的检测是另一个例子,其间检测到的皮肤区域能够用作图画中是否有人的目标;这种办法常常用于手势识别,运用肤色检测来检测手部方位。
运用色彩进行肤色检测
一般,要运用色彩进行目标检测,首要需求收集包括从不同环境条件获取的目标的大型图画样本数据库。需求运用这些图画样本界说分类器参数,并用于分类的色彩表示。对于肤色检测,研讨标明,来自不同种族的肤色在色彩饱和度空间中能够很好地聚集。出于以上原因,咱们将运用色彩和饱和度值来识别下图中的肤色:
因此,咱们界说一个函数 detectHScolor
,该函数依据值的区间(最小和最大色彩,以及最小和最大饱和度值)将图画的像素分类为皮肤或非皮肤:
void detectHScolor(const cv::Mat& image, // 输入图画
double minHue, double maxHue, // Hue 区间
double minSat, double maxSat, // Saturation 区间
cv::Mat& mask) { // 输出掩码
// 转化色彩空间
cv::Mat hsv;
cv::cvtColor(image, hsv, cv::COLOR_BGR2HSV);
// 分割图画通道
std::vector<cv::Mat> channels;
cv::split(hsv, channels);
cv::Mat mask1;
cv::threshold(channels[0], mask1, maxHue, 255, cv::THRESH_BINARY_INV);
cv::Mat mask2;
cv::threshold(channels[0], mask2, minHue, 255, cv::THRESH_BINARY);
cv::Mat hueMask;
if (minHue < maxHue) hueMask = mask1 & mask2;
else hueMask = mask1 | mask2;
cv::threshold(channels[1], mask1, maxSat, 255, cv::THRESH_BINARY_INV);
cv::threshold(channels[1], mask2, minSat, 255, cv::THRESH_BINARY);
cv::Mat satMask;
satMask = mask1 & mask2;
// 组合掩码
mask = hueMask & satMask;
}
有很多包括皮肤(和非皮肤)的图画样本可供运用,咱们能够运用概率办法来确定在皮肤类中观察给定色彩的可能性与在非皮肤类中观察到相同色彩的可能性。在本节中,咱们依据经验为测试图画界说了一个可接受的色彩饱和度间区间( 8
位版本的色彩从 0
到 180
,饱和度从 0
到 255
):
detectHScolor(image, 140, 10, 20, 166, mask);
cv::Mat detected(image.size(), CV_8UC3, cv::Scalar(0, 0, 0));
image.copyTo(detected, mask);
执行以上程序,结果得到如下检测图画:
为简单起见,咱们没有在检测中考虑色彩饱和度。实际上,排除具有高饱和度的色彩会下降将亮红色过错检测为皮肤的可能性。显然,牢靠且精确的肤色检测需求依据对很多皮肤样本更加精细的分析。仅运用色彩信息很难保证对不同图画的均具有杰出的检测作用,因为有许多因素会影响摄影中的色彩作用,例如白平衡和照明条件。尽管如此,仅运用色彩信息作为初始检测器也能够得到在可接受范围内的结果。