直接代码:
#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; Mat ycrcb double sum_Cr=0; for(int i=0;i < ycrcb.rows;i++){ for(int j=0;j < ycrcb.cols;j++){ int sky,skcr,skcb; //三个通道的值 sum_Cr += (int) ycrcb.at<Vec3b>(i,j)[1]; } } //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; } } threshold=131; cout<<"threshold == "<<threshold<<endl; cvThreshold(src,dst,threshold,255,CV_THRESH_BINARY); } void cvSkinOtsu(IplImage* src, IplImage* dst)//Mat & { 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);//cvtColor //show ycrcb cvShowImage("ycrcb",ycrcb); //vector<Point> mv[3]; //split(ycrcb , mv); cvSplit(ycrcb,0,cr,0,0);//split cvThresholdOtsu(cr,cr); cvShowImage("out2",cr);//show cvSaveImage("out.jpg",cr);//imwrite //cvWaitKey(0); //cvCopyImage(cr,dst); //cvReleaseImage(&cr); cvReleaseImage(&ycrcb); } int main() { IplImage* img = cvLoadImage( "zcr.jpg" ); //out用以保存输出图像 /*IplImage * out = cvCreateImage( cvGetSize(img), IPL_DEPTH_8U, 3 );*/ IplImage * out; cvShowImage("in",img); cvSkinOtsu(img,out); //cvShowImage("out",out); cvWaitKey(0); cvReleaseImage(&img);//用完清理 //cvReleaseImage(&out);//用完清理 cvDestroyWindow("in"); cvDestroyWindow("out"); return 0; }