几种肤色分割算法(OpenCV实现)

本文总结了几种使用OpenCV进行肤色分割的方法,适用于手势识别和人脸识别。实验表明,在HSV颜色空间上应用大津分割法表现优秀。还提到了一种基于HSV空间,通过(S+V)/H值判决的肤色分割技巧,但其效果具有特定性,不具广泛适用性。
摘要由CSDN通过智能技术生成

几种肤色分割算法(OpenCV实现)

        在手势识别和人脸识别中,肤色分割是非常重要的,特将几种肤色分割方法总结了一下,将代码贴出。

        ps:有部分代码非原创,若有侵权,修改。

        包括在rgb、rg空间上进行分割,以及大津分割法在多个颜色空间上的实现。

#include "highgui.h"
#include "cv.h"
#include<iostream>
using namespace std;
// skin region location using rgb limitation
void SkinRGB(IplImage* rgb,IplImage* _dst)
{
    assert(rgb->nChannels==3&& _dst->nChannels==3);

    static const int R=2;
    static const int G=1;
    static const int B=0;

    IplImage* dst=cvCreateImage(cvGetSize(_dst),8,3);
    cvZero(dst);

    for (int h=0; h<rgb->height; h++)
    {
        unsigned char* prgb=(unsigned char*)rgb->imageData+h*rgb->widthStep;
        unsigned char* pdst=(unsigned char*)dst->imageData+h*dst->widthStep;
        for (int w=0; w<rgb->width; w++)
        {
            if ((prgb[R]>95 && prgb[G]>40 && prgb[B]>20 &&
                    prgb[R]-prgb[B]>15 && prgb[R]-prgb[G]>15)||//uniform illumination
                    (prgb[R]>200 && prgb[G]>210 && prgb[B]>170 &&
                     abs(prgb[R]-prgb[B])<=15 && prgb[R]>prgb[B]&& prgb[G]>prgb[B])//lateral illumination
               )
            {
                memcpy(pdst,prgb,3);
            }
            prgb+=3;
            pdst+=3;
        }
    }
    cvCopyImage(dst,_dst);
    cvReleaseImage(&dst);
}
// skin detection in rg space
void cvSkinRG(IplImage* rgb,IplImage* gray)
{
    assert(rgb->nChannels==3&&gray->nChannels==1);

    const int R=2;
    const int G=1;
    const int B=0;

    double Aup=-1.8423;
    double Bup=1.5294;
    double Cup=0.0422;
    double Adown=-0.7279;
    double Bdown=0.6066;
    double Cdown=0.1766;
    for (int h=0; h<rgb->height; h++)
    {
        unsigned char* pGray=(unsigned char*)gray->imageData+h*gray->widthStep;
        unsigned char* pRGB=(unsigned char* )rgb->imageData+h*rgb->widthStep;
        for (int w=0; w<rgb->width; w++)
        {
            int s=pRGB[R]+pRGB[G]+pRGB[B];
            double r=(double)pRGB[R]/s;
            double g=(double)pRGB[G]/s;
            double Gup=Aup*r*r+Bup*r+Cup;
            double Gdown=Adown*r*r+Bdown*r+Cdown;
            double Wr=(r-0.33)*(r-0.33)+(g-0.33)*(g-0.33);
            if (g<Gup && g>Gdown && Wr>0.004)
            {
                *pGray=255;
            }
            else
            {
                *pGray=0;
            }
            pGray++;
            pRGB+=3;
        }
    }

}
// implementation of otsu algorithm
// author: onezeros#yahoo.cn
// reference:
  • 4
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值