学习OpenCV——肤色检测

前三种方式转载:http://blog.csdn.net/onezeros/article/details/6342567

 

第一种:RGB color space

第二种:RG color space

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

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

第五种:HSV中 7<H<29

 下一步需要滤波操作 因为检测结果中有许多瑕疵

[cpp] view plain copy print ?
  1. #include "highgui.h"   
  2. #include "cv.h"   
  3.   
  4. // skin region location using rgb limitation   
  5. void SkinRGB(IplImage* rgb,IplImage* _dst)  
  6. {  
  7.     assert(rgb->nChannels==3&& _dst->nChannels==3);  
  8.   
  9.     static const int R=2;  
  10.     static const int G=1;  
  11.     static const int B=0;  
  12.   
  13.     IplImage* dst=cvCreateImage(cvGetSize(_dst),8,3);  
  14.     cvZero(dst);  
  15.   
  16.     for (int h=0;h<rgb->height;h++) {  
  17.         unsigned char* prgb=(unsigned char*)rgb->imageData+h*rgb->widthStep;  
  18.         unsigned char* pdst=(unsigned char*)dst->imageData+h*dst->widthStep;  
  19.         for (int w=0;w<rgb->width;w++) {  
  20.             if ((prgb[R]>95 && prgb[G]>40 && prgb[B]>20 &&  
  21.                 prgb[R]-prgb[B]>15 && prgb[R]-prgb[G]>15/*&& 
  22.                 !(prgb[R]>170&&prgb[G]>170&&prgb[B]>170)*/)||//uniform illumination    
  23.                 (prgb[R]>200 && prgb[G]>210 && prgb[B]>170 &&  
  24.                 abs(prgb[R]-prgb[B])<=15 && prgb[R]>prgb[B]&& prgb[G]>prgb[B])//lateral illumination   
  25.                 ) {  
  26.                     memcpy(pdst,prgb,3);  
  27.             }             
  28.             prgb+=3;  
  29.             pdst+=3;  
  30.         }  
  31.     }  
  32.     cvCopyImage(dst,_dst);  
  33.     cvReleaseImage(&dst);  
  34. }  
  35. // skin detection in rg space   
  36. void cvSkinRG(IplImage* rgb,IplImage* gray)  
  37. {  
  38.     assert(rgb->nChannels==3&&gray->nChannels==1);  
  39.       
  40.     const int R=2;  
  41.     const int G=1;  
  42.     const int B=0;  
  43.   
  44.     double Aup=-1.8423;  
  45.     double Bup=1.5294;  
  46.     double Cup=0.0422;  
  47.     double Adown=-0.7279;  
  48.     double Bdown=0.6066;  
  49.     double Cdown=0.1766;  
  50.     for (int h=0;h<rgb->height;h++) {  
  51.         unsigned char* pGray=(unsigned char*)gray->imageData+h*gray->widthStep;  
  52.         unsigned char* pRGB=(unsigned char* )rgb->imageData+h*rgb->widthStep;  
  53.         for (int w=0;w<rgb->width;w++)   
  54.         {  
  55.             int s=pRGB[R]+pRGB[G]+pRGB[B];  
  56.             double r=(double)pRGB[R]/s;  
  57.             double g=(double)pRGB[G]/s;  
  58.             double Gup=Aup*r*r+Bup*r+Cup;  
  59.             double Gdown=Adown*r*r+Bdown*r+Cdown;  
  60.             double Wr=(r-0.33)*(r-0.33)+(g-0.33)*(g-0.33);  
  61.             if (g<Gup && g>Gdown && Wr>0.004)  
  62.             {  
  63.                 *pGray=255;  
  64.             }  
  65.             else  
  66.             {   
  67.                 *pGray=0;  
  68.             }  
  69.             pGray++;  
  70.             pRGB+=3;  
  71.         }  
  72.     }  
  73.   
  74. }  
  75. // implementation of otsu algorithm   
  76. // author: onezeros#yahoo.cn   
  77. // reference: Rafael C. Gonzalez. Digital Image Processing Using MATLAB   
  78. void cvThresholdOtsu(IplImage* src, IplImage* dst)  
  79. {  
  80.     int height=src->height;  
  81.     int width=src->width;  
  82.   
  83.     //histogram   
  84.     float histogram[256]={0};  
  85.     for(int i=0;i<height;i++) {  
  86.         unsigned char* p=(unsigned char*)src->imageData+src->widthStep*i;  
  87.         for(int j=0;j<width;j++) {  
  88.             histogram[*p++]++;  
  89.         }  
  90.     }  
  91.     //normalize histogram   
  92.     int size=height*width;  
  93.     for(int i=0;i<256;i++) {  
  94.         histogram[i]=histogram[i]/size;  
  95.     }  
  96.   
  97.     //average pixel value   
  98.     float avgValue=0;  
  99.     for(int i=0;i<256;i++) {  
  100.         avgValue+=i*histogram[i];  
  101.     }  
  102.   
  103.     int threshold;    
  104.     float maxVariance=0;  
  105.     float w=0,u=0;  
  106.     for(int i=0;i<256;i++) {  
  107.         w+=histogram[i];  
  108.         u+=i*histogram[i];  
  109.   
  110.         float t=avgValue*w-u;  
  111.         float variance=t*t/(w*(1-w));  
  112.         if(variance>maxVariance) {  
  113.             maxVariance=variance;  
  114.             threshold=i;  
  115.         }  
  116.     }  
  117.   
  118.     cvThreshold(src,dst,threshold,255,CV_THRESH_BINARY);  
  119. }  
  120.   
  121. void cvSkinOtsu(IplImage* src, IplImage* dst)  
  122. {  
  123.     assert(dst->nChannels==1&& src->nChannels==3);  
  124.   
  125.     IplImage* ycrcb=cvCreateImage(cvGetSize(src),8,3);  
  126.     IplImage* cr=cvCreateImage(cvGetSize(src),8,1);  
  127.     cvCvtColor(src,ycrcb,CV_BGR2YCrCb);  
  128.     cvSplit(ycrcb,0,cr,0,0);  
  129.   
  130.     cvThresholdOtsu(cr,cr);  
  131.     cvCopyImage(cr,dst);  
  132.     cvReleaseImage(&cr);  
  133.     cvReleaseImage(&ycrcb);  
  134. }  
  135.   
  136. void cvSkinYUV(IplImage* src,IplImage* dst)  
  137. {  
  138.     IplImage* ycrcb=cvCreateImage(cvGetSize(src),8,3);  
  139.     //IplImage* cr=cvCreateImage(cvGetSize(src),8,1);   
  140.     //IplImage* cb=cvCreateImage(cvGetSize(src),8,1);   
  141.     cvCvtColor(src,ycrcb,CV_BGR2YCrCb);  
  142.     //cvSplit(ycrcb,0,cr,cb,0);   
  143.   
  144.     static const int Cb=2;  
  145.     static const int Cr=1;  
  146.     static const int Y=0;  
  147.   
  148.     //IplImage* dst=cvCreateImage(cvGetSize(_dst),8,3);   
  149.     cvZero(dst);  
  150.   
  151.     for (int h=0;h<src->height;h++) {  
  152.         unsigned char* pycrcb=(unsigned char*)ycrcb->imageData+h*ycrcb->widthStep;  
  153.         unsigned char* psrc=(unsigned char*)src->imageData+h*src->widthStep;  
  154.         unsigned char* pdst=(unsigned char*)dst->imageData+h*dst->widthStep;  
  155.         for (int w=0;w<src->width;w++) {  
  156.             if (pycrcb[Cr]>=133&&pycrcb[Cr]<=173&&pycrcb[Cb]>=77&&pycrcb[Cb]<=127)  
  157.             {  
  158.                     memcpy(pdst,psrc,3);  
  159.             }  
  160.             pycrcb+=3;  
  161.             psrc+=3;  
  162.             pdst+=3;  
  163.         }  
  164.     }  
  165.     //cvCopyImage(dst,_dst);   
  166.     //cvReleaseImage(&dst);   
  167. }  
  168.   
  169. void cvSkinHSV(IplImage* src,IplImage* dst)  
  170. {  
  171.     IplImage* hsv=cvCreateImage(cvGetSize(src),8,3);  
  172.     //IplImage* cr=cvCreateImage(cvGetSize(src),8,1);   
  173.     //IplImage* cb=cvCreateImage(cvGetSize(src),8,1);   
  174.     cvCvtColor(src,hsv,CV_BGR2HSV);  
  175.     //cvSplit(ycrcb,0,cr,cb,0);   
  176.   
  177.     static const int V=2;  
  178.     static const int S=1;  
  179.     static const int H=0;  
  180.   
  181.     //IplImage* dst=cvCreateImage(cvGetSize(_dst),8,3);   
  182.     cvZero(dst);  
  183.   
  184.     for (int h=0;h<src->height;h++) {  
  185.         unsigned char* phsv=(unsigned char*)hsv->imageData+h*hsv->widthStep;  
  186.         unsigned char* psrc=(unsigned char*)src->imageData+h*src->widthStep;  
  187.         unsigned char* pdst=(unsigned char*)dst->imageData+h*dst->widthStep;  
  188.         for (int w=0;w<src->width;w++) {  
  189.             if (phsv[H]>=7&&phsv[H]<=29)  
  190.             {  
  191.                     memcpy(pdst,psrc,3);  
  192.             }  
  193.             phsv+=3;  
  194.             psrc+=3;  
  195.             pdst+=3;  
  196.         }  
  197.     }  
  198.     //cvCopyImage(dst,_dst);   
  199.     //cvReleaseImage(&dst);   
  200. }  
  201.   
  202. int main()  
  203. {     
  204.       
  205.     IplImage* img= cvLoadImage("D:/skin.jpg"); //随便放一张jpg图片在D盘或另行设置目录   
  206.     IplImage* dstRGB=cvCreateImage(cvGetSize(img),8,3);  
  207.     IplImage* dstRG=cvCreateImage(cvGetSize(img),8,1);  
  208.     IplImage* dst_crotsu=cvCreateImage(cvGetSize(img),8,1);  
  209.     IplImage* dst_YUV=cvCreateImage(cvGetSize(img),8,3);  
  210.     IplImage* dst_HSV=cvCreateImage(cvGetSize(img),8,3);  
  211.   
  212.   
  213.     cvNamedWindow("inputimage", CV_WINDOW_AUTOSIZE);  
  214.     cvShowImage("inputimage", img);  
  215.     cvWaitKey(0);  
  216.   
  217.     SkinRGB(img,dstRGB);  
  218.     cvNamedWindow("outputimage1", CV_WINDOW_AUTOSIZE);  
  219.     cvShowImage("outputimage1", dstRGB);  
  220.     cvWaitKey(0);  
  221.     cvSkinRG(img,dstRG);  
  222.     cvNamedWindow("outputimage2", CV_WINDOW_AUTOSIZE);  
  223.     cvShowImage("outputimage2", dstRG);  
  224.     cvWaitKey(0);  
  225.     cvSkinOtsu(img,dst_crotsu);  
  226.     cvNamedWindow("outputimage3", CV_WINDOW_AUTOSIZE);  
  227.     cvShowImage("outputimage3", dst_crotsu);  
  228.     cvWaitKey(0);  
  229.     cvSkinYUV(img,dst_YUV);  
  230.     cvNamedWindow("outputimage4", CV_WINDOW_AUTOSIZE);  
  231.     cvShowImage("outputimage4", dst_YUV);  
  232.     cvWaitKey(0);  
  233.     cvSkinHSV(img,dst_HSV);  
  234.     cvNamedWindow("outputimage5", CV_WINDOW_AUTOSIZE);  
  235.     cvShowImage("outputimage5", dst_HSV);  
  236.     cvWaitKey(0);  
  237.     return 0;  
  238. }  

你可能感兴趣的:(DST)