皮肤检测

今天是地球日,就选了张相关主题的图像做测试

 

第一种:RGB color space

第二种:RG color space

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

 

还有别的一些模型,效果不太好就不贴了

 

1.rgb model

[cpp]  view plain copy
  1. // skin region location using rgb limitation  
  2. void SkinRGB(IplImage* rgb,IplImage* _dst)  
  3. {  
  4.     assert(rgb->nChannels==3&& _dst->nChannels==3);  
  5.   
  6.     static const int R=2;  
  7.     static const int G=1;  
  8.     static const int B=0;  
  9.   
  10.     IplImage* dst=cvCreateImage(cvGetSize(_dst),8,3);  
  11.     cvZero(dst);  
  12.   
  13.     for (int h=0;h<rgb->height;h++) {  
  14.         unsigned char* prgb=(unsigned char*)rgb->imageData+h*rgb->widthStep;  
  15.         unsigned char* pdst=(unsigned char*)dst->imageData+h*dst->widthStep;  
  16.         for (int w=0;w<rgb->width;w++) {  
  17.             if ((prgb[R]>95 && prgb[G]>40 && prgb[B]>20 &&  
  18.                 prgb[R]-prgb[B]>15 && prgb[R]-prgb[G]>15/*&& 
  19.                 !(prgb[R]>170&&prgb[G]>170&&prgb[B]>170)*/)||//uniform illumination   
  20.                 (prgb[R]>200 && prgb[G]>210 && prgb[B]>170 &&  
  21.                 abs(prgb[R]-prgb[B])<=15 && prgb[R]>prgb[B]&& prgb[G]>prgb[B])//lateral illumination  
  22.                 ) {  
  23.                     memcpy(pdst,prgb,3);  
  24.             }             
  25.             prgb+=3;  
  26.             pdst+=3;  
  27.         }  
  28.     }  
  29.     cvCopyImage(dst,_dst);  
  30.     cvReleaseImage(&dst);  
  31. }  

 

2.rg model

[cpp]  view plain copy
  1. // skin detection in rg space  
  2. void cvSkinRG(IplImage* rgb,IplImage* gray)  
  3. {  
  4.     assert(rgb->nChannels==3&&gray->nChannels==1);  
  5.       
  6.     const int R=2;  
  7.     const int G=1;  
  8.     const int B=0;  
  9.   
  10.     double Aup=-1.8423;  
  11.     double Bup=1.5294;  
  12.     double Cup=0.0422;  
  13.     double Adown=-0.7279;  
  14.     double Bdown=0.6066;  
  15.     double Cdown=0.1766;  
  16.     for (int h=0;h<rgb->height;h++) {  
  17.         unsigned char* pGray=(unsigned char*)gray->imageData+h*gray->widthStep;  
  18.         unsigned char* pRGB=(unsigned char* )rgb->imageData+h*rgb->widthStep;  
  19.         for (int w=0;w<rgb->width;w++) {  
  20.             int s=pRGB[R]+pRGB[G]+pRGB[B];  
  21.             double r=(double)pRGB[R]/s;  
  22.             double g=(double)pRGB[G]/s;  
  23.             double Gup=Aup*r*r+Bup*r+Cup;  
  24.             double Gdown=Adown*r*r+Bdown*r+Cdown;  
  25.             double Wr=(r-0.33)*(r-0.33)+(g-0.33)*(g-0.33);  
  26.             if (g<Gup && g>Gdown && Wr>0.004){  
  27.                 *pGray=255;  
  28.             }else{   
  29.                 *pGray=0;  
  30.             }  
  31.             pGray++;  
  32.             pRGB+=3;  
  33.         }  
  34.     }  
  35.   
  36. }  

 

3.cr+otsu

[c-sharp]  view plain copy
  1. // implementation of otsu algorithm  
  2. // author: onezeros#yahoo.cn  
  3. // reference: Rafael C. Gonzalez. Digital Image Processing Using MATLAB  
  4. void cvThresholdOtsu(IplImage* src, IplImage* dst)  
  5. {  
  6.     int height=src->height;  
  7.     int width=src->width;  
  8.   
  9.     //histogram  
  10.     float histogram[256]={0};  
  11.     for(int i=0;i<height;i++) {  
  12.         unsigned char* p=(unsigned char*)src->imageData+src->widthStep*i;  
  13.         for(int j=0;j<width;j++) {  
  14.             histogram[*p++]++;  
  15.         }  
  16.     }  
  17.     //normalize histogram  
  18.     int size=height*width;  
  19.     for(int i=0;i<256;i++) {  
  20.         histogram[i]=histogram[i]/size;  
  21.     }  
  22.   
  23.     //average pixel value  
  24.     float avgValue=0;  
  25.     for(int i=0;i<256;i++) {  
  26.         avgValue+=i*histogram[i];  
  27.     }  
  28.   
  29.     int threshold;    
  30.     float maxVariance=0;  
  31.     float w=0,u=0;  
  32.     for(int i=0;i<256;i++) {  
  33.         w+=histogram[i];  
  34.         u+=i*histogram[i];  
  35.   
  36.         float t=avgValue*w-u;  
  37.         float variance=t*t/(w*(1-w));  
  38.         if(variance>maxVariance) {  
  39.             maxVariance=variance;  
  40.             threshold=i;  
  41.         }  
  42.     }  
  43.   
  44.     cvThreshold(src,dst,threshold,255,CV_THRESH_BINARY);  
  45. }  
  46.   
  47. void cvSkinOtsu(IplImage* src, IplImage* dst)  
  48. {  
  49.     assert(dst->nChannels==1&& src->nChannels==3);  
  50.   
  51.     IplImage* ycrcb=cvCreateImage(cvGetSize(src),8,3);  
  52.     IplImage* cr=cvCreateImage(cvGetSize(src),8,1);  
  53.     cvCvtColor(src,ycrcb,CV_BGR2YCrCb);  
  54.     cvSplit(ycrcb,0,cr,0,0);  
  55.   
  56.     cvThresholdOtsu(cr,cr);  
  57.     cvCopyImage(cr,dst);  
  58.     cvReleaseImage(&cr);  
  59.     cvReleaseImage(&ycrcb);  
  60. }  

 

原图像

皮肤检测_第1张图片

 

rgb model

皮肤检测_第2张图片

 

rg model

皮肤检测_第3张图片

 

otsu+cr皮肤检测_第4张图片

你可能感兴趣的:(皮肤检测)