肤色检测opencv

来源:互联网 发布:ok三连冠科比数据 编辑:程序博客网 时间:2024/04/29 02:09

原文地址:

第一种:RGB color space生气

第二种:RG color space

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

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

第五种:HSV中 7<H<29

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

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