图像肤色初步检测实现(一)

2014-11-23 22:15:18 · 作者: · 浏览: 0

肤色检测输出结果中有许多瑕疵,待于进一步处理(如:滤波操作.....)。在此贴出几种图像肤色检测相关代码,供大家参考。

第一种:RGB color space

// skin region location using rgb limitation  
void ImageSkin::ImageSkinRGB(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
  
   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
   
    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]) ) { memcpy(pdst,prgb,3); } prgb+=3; pdst+=3; } } cvCopyImage(dst,_dst); cvReleaseImage(&dst); } 
   
  

第二种:RG color space

// skin detection in rg space  
void ImageSkin::ImageSkinRG(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
  
   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
   
    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
    
     Gdown && Wr>0.004) { *pGray=255; } else { *pGray=0; } pGray++; pRGB+=3; } } } 
    
   
  

第三种:otsu阈值化

// reference: Rafael C. Gonzalez. Digital Image Processing Using MATLAB  
void ImageSkin::ImageThresholdOtsu(IplImage* src, IplImage* dst)  
{  
    int height=src->
height; int width=src->width; //histogram float histogram[256]={0}; for(int i=0;i imageData+src->widthStep*i; for(int j=0;j maxVariance) { maxVariance=variance; threshold=i; } } cvThreshold(src,dst,threshold,255,CV_THRESH_BINARY); }

第四种:Ycrcb之cr分量+otsu阈值化

void ImageSkin::ImageSkinOtsu(IplImage* src, IplImage* dst)  
{  
    assert(dst->nChannels==1&& src->nChannels==3);  
  
    IplImage* ycrcb=cvCreateImage(cvGetSize(src),8,3);  
    IplImage* cr=cvCreateImage(cvGetSize(src),8,1);  
    cvCvtColor(src,ycrcb,CV_BGR2YCrCb);  
    cvSplit(ycrcb,0,cr,0,0);  
  
	ImageThresholdOtsu(cr,cr);  
    cvCopyImage(cr,dst);  
    cvReleaseImage(&cr);  
    cvReleaseImage(&ycrcb);  
}  

第五种:YCrCb中133<=Cr<=173 77<=Cb<=127

void ImageSkin::ImageSkinYUV(IplImage* src,IplImage* dst)  
{  
    IplImage* ycrcb=cvCreateImage(cvGetSize(src),8,3);  
    //IplImage* cr=cvCreateImage(cvGetSize(src),8,1);  
    //IplImage* cb=cvCreateImage(cvGetSize(src),8,1);  
    cvCvtColor(src,ycrcb,CV_BGR2YCrCb);  
    //cvSplit(ycrcb,0,cr,cb,0);  
  
    static const int Cb=2;  
    static const int Cr=1;  
    static const int Y=0;  
  
    //IplImage* dst=cvCreateImage(cvGetSize(_dst),8,3);  
    cvZero(dst);  
  
    for (int h=0;h
  
   height;h++) {  
        unsigned char* pycrcb=(unsigned char*)ycrcb->imageData+h*ycrcb->widthStep;  
        unsigned char* psrc=(unsigned char*)src->imageData+h*src->widthStep;  
        unsigned char* pdst=(unsigned char*)dst->imageData+h*dst->widthStep;  
        for (int w=0;w
   
    width;w++) { if (pycrcb[Cr]