皮肤检测及对检测到皮肤单独校色 (基于自动白平衡)

原理见前几篇博客,修改修改可以做美颜的程序直接贴代码:

/*对照片中的皮肤单独进行较色,然后塞进原始图片作为输出*/
/*包含皮肤的检测、皮肤的校正两步*/
/*单张照片测试效果不错,但对于一百多张照片,结果还是有偏差,这种单独校正然后再用于贴图的方法 行不通*/
/*时间:2015.8.24*/
#include   
#include   
#include 
#include   
#include   
#include   
  
using namespace std;  
using namespace cv;  
double baidianave(Mat frame,int n)
{  
    int a[256];
    for (int i=0;i<256;i++)
    {
        a[i]=0;
    }
    double sum=0;
    double ave;
    for (int i=0;i(0,i);
        a[d]++;
    }
    int n0=255;
    for (int k=255;k>0;k--)
    {
        sum+=a[k];
        if (sum>frame.rows*frame.cols/25)
        {
            break;
        }
        n0--;
    }
    sum=0;
    for (int i=n0;i<256;i++)
    {
        sum+=a[i]*i;
    }
    ave=sum/(frame.rows*frame.cols/25);
    return ave;
}
double baidianave(Mat frame)
{ 
    int a[256];
//cvZero(a);
    for (int i=0;i<256;i++)
    {
        a[i]=0;
    }
    double sum=0;
    double ave;
    for (int i=0;i(i,j);
            a[d]++;
        }
    }

    int n0=255;
    for (int k=255;k>0;k--)
    {
        sum+=a[k];
        if (sum>frame.rows*frame.cols/25)
        {
            break;
        }
        n0--;
    }
    sum=0;
    for (int i=n0;i<256;i++)
    {
        sum+=a[i]*i;
    }
    ave=sum/(frame.rows*frame.cols/25);
    return ave;

}

Mat input_image;  
Mat output_mask;  
Mat output_image;  
Mat mask;  
  
int main(int argc,char *argv[])  
{  
    if (2 != argc) 
    {
        cout << "Please enter the image list!" <  file_names;
    FILE *file_list =  fopen(argv[1],"r");
    char buf[255];
    memset(&buf,0,sizeof(buf));

    while(fgets(buf,255,file_list))
    {
        if(buf[strlen(buf)-1] == '\n') 
            buf[strlen(buf)-1] = '\0';
        file_names.push_back(string(buf));

    }
    
    fclose(file_list);
    int count = file_names.size();
    
    Mat skinCrCbHist = Mat::zeros(Size(256, 256), CV_8UC1);  
    ellipse(skinCrCbHist, Point(113, 155.6), Size(25,12), -20, 0.0, 360.0, Scalar(255, 255, 255), -1);  
  
    Mat element = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1) );  
    for(int  i=0; i(i);  
            Vec3b* ycrcb = (Vec3b*)ycrcb_image.ptr(i);  
            for(int j = 0; j < input_image.cols; j++)  
            {  
                if(skinCrCbHist.at(ycrcb[j][1], ycrcb[j][2]) > 0)  
                {
                    // input_image.at(i,j)[2]=255;
                    p[j] = 255;  
                }
            }  
        }     
        // imwrite("test.jpg",input_image);
        morphologyEx(output_mask,output_mask,MORPH_CLOSE,element);   
        vector< vector > contours;   
        vector< vector > filterContours; 
        vector< Vec4i > hierarchy;   
        contours.clear();    
        hierarchy.clear();   
        filterContours.clear();  
  
        findContours(output_mask, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);    
        for (size_t i = 0; i < contours.size(); i++)   
        {  
             if (fabs(contourArea(Mat(contours[i]))) > 2000&&fabs(arcLength(Mat(contours[i]),true))>500) 
                 filterContours.push_back(contours[i]);  
        }  
        output_mask.setTo(0);  
        drawContours(output_mask, filterContours, -1, Scalar(255,0,0), CV_FILLED);     
        input_image.copyTo(output_image, output_mask);  
        Mat tempimage=Mat::zeros(input_image.size(), CV_8UC3); 
        threshold(output_mask,output_mask,20, 255, THRESH_BINARY);
        cvtColor(output_mask,output_mask,CV_GRAY2BGR);



        Mat frame=Mat::zeros(input_image.size(), CV_8UC3); 
        output_image.copyTo(frame);
        // imshow("frame",frame);
        // waitKey(0);
        //cout<ybr(imageYCrCb.channels());
        split(imageYCrCb,ybr);
        // namedWindow("test",0);
        // imshow("test",ybr[2]);
        // waitKey(0);
        //分成三个通道,,,
        // imageY,imageCr,imageCb

        Mat imageb=Mat::zeros(frame.size(), CV_8UC1);
        Mat imagec=Mat::zeros(frame.size(), CV_8UC1);
        ybr[1].copyTo(imageb);
        ybr[2].copyTo(imagec);
        Mat  savg,sfangcha;//全局scalar 变量用来放平均值和方差
        meanStdDev(ybr[2],savg,sfangcha);
        // cvAvgSdv(imageb,&savg,&sfangcha,NULL);
        // cout<(0)<(0)<(0);
         cout<<"Mb:  "<(0);//求出第一部分cb的均值和均方差
         cout<<"Db:  "<(0);
        cout<<"Mr:  "<(0);;//求出第一部分cr的均值和均方差
         cout<<"Dr:  "<(i,j)[2]=255
                if (((ybr[2].at(i,j)-b[0])<(1.5*Db[0]))&&((ybr[1].at(i,j)-c[0])<(1.5*Dr[0])))
                {
            
                    double d1=frame.at(i,j)[0];
                    Bbaidian.at(0,n1)=d1;
                    
                    double d2=frame.at(i,j)[1];
                    Gbaidian.at(0,n1)=d2;
                
                    double d3=frame.at(i,j)[2];
                    Rbaidian.at(0,n1)=d3;
                    n1++;
                }
            }
        }

        // cout<<"n1:  "<(i,j)[0];
                int tg=Ggain1*frame.at(i,j)[1];
                int tr=Rgain1*frame.at(i,j)[2];
                if (tb>255)
                {
                    tb=255;
                    // count_out++;
                }
                if (tg>255)
                {
                    tg=255;
                    // count_out++;
                }
                if (tr>255)
                {
                    tr=255;
                    // count_out++;
                }
                frame.at(i,j)[0]=tb;
                frame.at(i,j)[1]=tg;
                frame.at(i,j)[2]=tr;
            }
        }
        // cout<(i);  
            uchar* p2 = (uchar*)input_image.ptr(i);  
            uchar* p3 = (uchar*)frame.ptr(i);  
            for(int j = 0; j < 3*input_image.cols; )  
            {  
                if(p[j] != 0)  
                {
                    // cout<<"p:  "<(i,j)[2]=255;
                    p2[j]=0;
                    p2[j] = p3[j++];  
                    // cout<<"B:   "<


你可能感兴趣的:(opencv)