本文主要是介绍【肤色检测 (I)】实测Ycrcb之cr分量+otsu阈值化,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
效果还不错,不过问题就是代码都是用的较老的opencv语法,里面有一些处理不好容易报错。。
#include "cv.h"
#include "highgui.h"#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/core.hpp>#include <iostream>
#include <string>
#include <cstdio>using namespace std;
using namespace cv;// 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;//histogramfloat 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 histogramint size=height*width;for(int i=0;i<256;i++) {histogram[i]=histogram[i]/size;}//average pixel valuefloat 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);//show ycrcbcvShowImage("ycrcb",ycrcb);cvSplit(ycrcb,0,cr,0,0);cvThresholdOtsu(cr,cr);cvShowImage("out2",cr);//cvWaitKey(0);//cvCopyImage(cr,dst);//cvReleaseImage(&cr);cvReleaseImage(&ycrcb);
}int main()
{IplImage* img = cvLoadImage( "earth.jpg" );//out用以保存输出图像IplImage * out = cvCreateImage(cvGetSize(img),IPL_DEPTH_8U,3);cvShowImage("in",img);cvSkinOtsu(img,out);//cvShowImage("out",out);cvWaitKey(0);cvReleaseImage(&img);//用完清理cvReleaseImage(&out);//用完清理cvDestroyWindow("in");cvDestroyWindow("out");return 0;
}
这篇关于【肤色检测 (I)】实测Ycrcb之cr分量+otsu阈值化的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!