颜色用于检测:肤色检测

在对特定物体做初步检测时,颜色信息非常有用。例如辅助驾驶程序中的路标检测功能,就要凭借标准路标的颜色快速识别可能是路标的信息。另一个例子是肤色检测,检测到的皮肤区域可作为图像中有人存在的标志。手势识别就经常使用肤色检测确定手的位置。
通常来说,为了用颜色来检测目标,首先需要收集一个存储有大量图像样本的数据库,每个样本包含从不同观察条件下捕捉到的目标,作为定义分类器的参数。你还需要选择一种用于分类的颜色表示法。肤色检测领域的大量研究已经表明,来自不同人种的人群的皮肤颜色,可以在色调-饱和度色彩空间中很好地归类。因此,在后面的图像中,我们将只使用色调和饱和度值来识别肤色。
我们定义了一个基于数值区间(最小和最大色调、最小和最大饱和度)的函数,把图像中的像素分为皮肤和非皮肤两类:

void detectHScolor(const cv::Mat& image, // 输入图像
 double minHue, double maxHue, // 色调区间
 double minSat, double maxSat, // 饱和度区间
 cv::Mat& mask) { // 输出掩码
 // 转换到 HSV 空间
 cv::Mat hsv; 
 cv::cvtColor(image, hsv, CV_BGR2HSV); 
 // 将 3 个通道分割到 3 幅图像
 std::vector<cv::Mat> channels; 
 cv::split(hsv, channels); 
 // channels[0]是色调
 // channels[1]是饱和度
 // channels[2]是亮度
  // 色调掩码
 cv::Mat mask1; // 小于 maxHue 
 cv::threshold(channels[0], mask1, maxHue, 255, 
 cv::THRESH_BINARY_INV); 
 cv::Mat mask2; // 大于 minHue 
 cv::threshold(channels[0], mask2, minHue, 255, cv::THRESH_BINARY); 
 cv::Mat hueMask; // 色调掩码
 if (minHue < maxHue) 
 hueMask = mask1 & mask2; 
 else // 如果区间穿越 0 度中轴线
 hueMask = mask1 | mask2; 
 // 饱和度掩码
 // 从 minSat 到 maxSat 
 cv::Mat satMask; // 饱和度掩码
 cv::inRange(channels[1], minSat, maxSat, satMask); 
 // 组合掩码
 mask = hueMask & satMask; 
} 

如果在处理时有了大量的皮肤(以及非皮肤)样本,我们就可以使用概率方法估算在皮肤样本中和非皮肤样本中发现指定颜色的可能性。此处,我们依据经验定义了一个合理的色调-饱和度区间,用于这里的测试图像(记住,8 位版本的色调在 0~180,饱和度在 0~255):

// 检测肤色
cv::Mat mask; 
detectHScolor(image, 160, 10, // 色调为 320 度~20 度
 25, 166, // 饱和度为~0.1~0.65 
 mask); 
// 显示使用掩码后的图像
cv::Mat detected(image.size(), CV_8UC3, cv::Scalar(0, 0, 0)); 
image.copyTo(detected, mask); 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值