• Opencv SkinOtsu皮肤检测


    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) ||//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;
            }
        }
        cvCopy(dst, _dst);
        cvReleaseImage(&dst);
    }
    // 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;
        for (int h = 0; h<rgb->height; h++)
        {
            unsigned char* pGray = (unsigned char*)gray->imageData + h*gray->widthStep;
            unsigned char* pRGB = (unsigned char*)rgb->imageData + h*rgb->widthStep;
            for (int w = 0; w<rgb->width; w++)
            {
                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++;
                pRGB += 3;
            }
        }
    
    }
    // 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;
        for (int i = 0; i<256; i++)
        {
            avgValue += i*histogram[i];
        }
    
        int threshold;
        float maxVariance = 0;
        float w = 0, u = 0;
        for (int i = 0; i<256; i++)
        {
            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);
        cvCopy(cr, dst);
        cvReleaseImage(&cr);
        cvReleaseImage(&ycrcb);
    }
    
    void cvSkinYUV(IplImage* src, IplImage* dst)
    {
        IplImage* ycrcb = cvCreateImage(cvGetSize(src), 8, 3);
        //IplImage* cr=cvCreateImage(cvGetSize(src),8,1);
        //IplImage* cb=cvCreateImage(cvGetSize(src),8,1);
        cvCvtColor(src, ycrcb, CV_BGR2YCrCb);
        //cvSplit(ycrcb,0,cr,cb,0);
    
        static const int Cb = 2;
        static const int Cr = 1;
        static const int Y = 0;
    
        //IplImage* dst=cvCreateImage(cvGetSize(_dst),8,3);
        cvZero(dst);
    
        for (int h = 0; h<src->height; h++)
        {
            unsigned char* pycrcb = (unsigned char*)ycrcb->imageData + h*ycrcb->widthStep;
            unsigned char* psrc = (unsigned char*)src->imageData + h*src->widthStep;
            unsigned char* pdst = (unsigned char*)dst->imageData + h*dst->widthStep;
            for (int w = 0; w<src->width; w++)
            {
                if (pycrcb[Cr] >= 133 && pycrcb[Cr] <= 173 && pycrcb[Cb] >= 77 && pycrcb[Cb] <= 127)
                {
                    memcpy(pdst, psrc, 3);
                }
                pycrcb += 3;
                psrc += 3;
                pdst += 3;
            }
        }
        //cvCopyImage(dst,_dst);
        //cvReleaseImage(&dst);
    }
    
    void cvSkinHSV(IplImage* src, IplImage* dst)
    {
        IplImage* hsv = cvCreateImage(cvGetSize(src), 8, 3);
        //IplImage* cr=cvCreateImage(cvGetSize(src),8,1);
        //IplImage* cb=cvCreateImage(cvGetSize(src),8,1);
        cvCvtColor(src, hsv, CV_BGR2HSV);
        //cvSplit(ycrcb,0,cr,cb,0);
    
        static const int V = 2;
        static const int S = 1;
        static const int H = 0;
    
        //IplImage* dst=cvCreateImage(cvGetSize(_dst),8,3);
        cvZero(dst);
    
        for (int h = 0; h<src->height; h++)
        {
            unsigned char* phsv = (unsigned char*)hsv->imageData + h*hsv->widthStep;
            unsigned char* psrc = (unsigned char*)src->imageData + h*src->widthStep;
            unsigned char* pdst = (unsigned char*)dst->imageData + h*dst->widthStep;
            for (int w = 0; w<src->width; w++)
            {
                if (phsv[H] >= 7 && phsv[H] <= 29)
                {
                    memcpy(pdst, psrc, 3);
                }
                phsv += 3;
                psrc += 3;
                pdst += 3;
            }
        }
        //cvCopyImage(dst,_dst);
        //cvReleaseImage(&dst);
    }
    
    int main()
    {
    
        //IplImage* img = cvLoadImage("C:\C_C++ code\Photo and video\text009.jpg"); //随便放一张jpg图片在D盘或另行设置目录
        //IplImage* dstRGB = cvCreateImage(cvGetSize(img), 8, 3);
        //IplImage* dstRG = cvCreateImage(cvGetSize(img), 8, 1);
        
        //IplImage* dst_YUV = cvCreateImage(cvGetSize(img), 8, 3);
        //IplImage* dst_HSV = cvCreateImage(cvGetSize(img), 8, 3);
    
    
        
    
        
        cvNamedWindow("inputimage", CV_WINDOW_AUTOSIZE);
        cvShowImage("inputimage", img);
        cvWaitKey(0);
        SkinRGB(img, dstRGB);
        cvNamedWindow("SkinRGB", CV_WINDOW_AUTOSIZE);
        cvShowImage("SkinRGB", dstRGB);
        cvWaitKey(0);
        cvSkinRG(img, dstRG);
        cvNamedWindow("cvSkinRG", CV_WINDOW_AUTOSIZE);
        cvShowImage("cvSkinRG", dstRG);
        cvWaitKey(0);
        cvSkinOtsu(img, dst_crotsu);
        cvNamedWindow("cvSkinOtsu", CV_WINDOW_AUTOSIZE);
        cvShowImage("cvSkinOtsu", dst_crotsu);
        cvWaitKey(0);
        cvSkinYUV(img, dst_YUV);
        cvNamedWindow("cvSkinYUV", CV_WINDOW_AUTOSIZE);
        cvShowImage("cvSkinYUV", dst_YUV);
        cvWaitKey(0);
        cvSkinHSV(img, dst_HSV);
        cvNamedWindow("cvSkinHSV", CV_WINDOW_AUTOSIZE);
        cvShowImage("cvSkinHSV", dst_HSV);
        cvWaitKey(0);
        
        
        
        IplImage *src;
        //VideoCapture video("C:\C_C++ EX8 code\Video\MyVideo.wmv");
        VideoCapture video(0);
        if (!video.isOpened())
        {
            return -1;
        }
        cv::Mat img, dstimg;
        cv::Rect rect(170, 40, 240, 400);
        video >> img;
        src = &(IplImage(img));
        IplImage* dst_crotsu = cvCreateImage(cvGetSize(src), 8, 1);
        while (1)
        {
            video >> img;
            src = &(IplImage(img));
            cvSkinOtsu(src, dst_crotsu);
            cvNamedWindow("cvSkinOtsu", CV_WINDOW_AUTOSIZE);
    
            Mat output = cvarrToMat(dst_crotsu);
            cv::erode(output, output, cv::Mat());
            cv::erode(output, output, cv::Mat());
            cv::erode(output, output, cv::Mat());
            cv::erode(output, output, cv::Mat());
            cv::dilate(output, output, cv::Mat());
    
            imshow("cvSkinOtsu", output);
    
            if (cv::waitKey(40) > 0)
            {
                break;
            }
        }
    
        
        cvWaitKey(0);
        return 0;
    }
  • 相关阅读:
    静态网页
    css
    html
    数据分析器
    初步了解计算机
    如何导出数据库的数据词典
    阅读计划
    python之文件读写
    曾梦想仗剑走天涯,看世界的繁华
    python lambda匿名函数
  • 原文地址:https://www.cnblogs.com/mypsq/p/5020193.html
Copyright © 2020-2023  润新知