OpenCV3 3.5 通过色调、饱和度进行肤色检测

通过色调、饱和度进行肤色检测

肤色检测领域的大量研究表明,来自不同人种人群的皮肤颜色,可以在色调-饱和度色彩空间中很好的归类,本实例仅适用色调和饱和度值来识别肤色。

cv::Mat skinDetect(const cv::Mat& image, double minHue, double maxHue, double minSat, double maxSat)
{
    //创建HSV图像
    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, minHue, 255, cv::THRESH_BINARY);
    //创建小于最大色调的掩码
    cv::Mat mask2;
    cv::threshold(channels[0], mask2, maxHue, 255, cv::THRESH_BINARY_INV);

    //创建色调掩码
    cv::Mat hueMask;
    //如果输入的最小色的小于最大色调,取交
    if (minHue < maxHue)
    {
        hueMask = mask1 & mask2;
    }
    //如果输入的最小色的大于最大色调,即横跨了0度中轴线
    else
    {
        hueMask = mask1 | mask2;
    }

    //创建饱和度掩码
    cv::Mat satMask;
    //由于饱和度没有中轴线,直接调用cv::inRange函数创建二值图即可
    cv::inRange(channels[1], minSat, maxSat, satMask);
    return hueMask & satMask;
}

int main()
{
    cv::Mat nana = cv::imread("nana.jpg");
    cv::Mat mask;
    //设置的色调范围为160~15之间(320~30),饱和度范围在25~180之间(0.1~0.65)
    mask = skinDetect(nana, 160, 15, 25, 166);
    cv::Mat detected(nana.size(), CV_8UC3, cv::Scalar(0, 0, 0));
    //通过copyTo加掩码的方法将原图拷贝到检测图中
    nana.copyTo(detected, mask);
    //输出原图和检测图
    cv::imshow("nana", nana);
    cv::imshow("detected", detected);
    cv::waitKey();
    return 0;
}

本例中没有考虑颜色的亮度,排除较高亮度的颜色可以降低把明亮的淡红色误认为皮肤的可能性。

效果

在这里插入图片描述
在这里插入图片描述

补充:cv::inRange函数的使用

函数类似cv::threshold函数(例3.2),可以识别图像中一定范围的像素,并创建二值图,以便作为掩码分割图像。

函数签名

CV_EXPORTS_W void inRange(InputArray src, InputArray lowerb,
                          InputArray upperb, OutputArray dst);

参数分别为:输入图像,最低阈值,最高阈值,输出掩码图

这里的阈值在单通道为常数uchar,在多通道时为向量cv::Vec3b,其中每个通道都必须在给定范围内。在没有中轴线的情况下比threshold函数方便一些。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值