天天看點

皮膚檢測算法三種,示例與代碼

今天是地球日,就選了張相關主題的圖像做測試

第一種:rgb color space

第二種:rg color space

第三種:ycrcb之cr分量+otsu門檻值化

還有别的一些模型,效果不太好就不貼了

1.rgb model

[cpp] view

plaincopy

// 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/*&& 

                !(prgb[r]>170&&prgb[g]>170&&prgb[b]>170)*/)||//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);  

}  

2.rg model

// 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;  

        unsigned char* pgray=(unsigned char*)gray->imagedata+h*gray->widthstep;  

        unsigned char* prgb=(unsigned char* )rgb->imagedata+h*rgb->widthstep;  

            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++;  

3.cr+otsu

[c-sharp] view

// implementation of otsu algorithm  

// author: onezeros#yahoo.cn  

// reference: rafael c. gonzalez. digital image processing using matlab  

void cvthresholdotsu(iplimage* src, iplimage* dst)  

    int height=src->height;  

    int width=src->width;  

    //histogram  

    float histogram[256]={0};  

    for(int i=0;i<height;i++) {  

        unsigned char* p=(unsigned char*)src->imagedata+src->widthstep*i;  

        for(int j=0;j<width;j++) {  

            histogram[*p++]++;  

    //normalize histogram  

    int size=height*width;  

    for(int i=0;i<256;i++) {  

        histogram[i]=histogram[i]/size;  

    //average pixel value  

    float avgvalue=0;  

        avgvalue+=i*histogram[i];  

    int threshold;    

    float maxvariance=0;  

    float w=0,u=0;  

        w+=histogram[i];  

        u+=i*histogram[i];  

        float t=avgvalue*w-u;  

        float variance=t*t/(w*(1-w));  

        if(variance>maxvariance) {  

            maxvariance=variance;  

            threshold=i;  

    cvthreshold(src,dst,threshold,255,cv_thresh_binary);  

void cvskinotsu(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);  

    cvthresholdotsu(cr,cr);  

    cvcopyimage(cr,dst);  

    cvreleaseimage(&cr);  

    cvreleaseimage(&ycrcb);  

原圖像

皮膚檢測算法三種,示例與代碼

rgb model

皮膚檢測算法三種,示例與代碼

rg model

皮膚檢測算法三種,示例與代碼

otsu+cr

皮膚檢測算法三種,示例與代碼

皮膚檢測算法三種,示例與代碼

繼續閱讀