效果还不错,不过问题就是代码都是用的较老的opencv语法,里面有一些处理不好容易报错。。

#include "cv.h"

#include "highgui.h"

#include

#include

#include

#include

#include

#include

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;

//histogram

float histogram[256]={0};

for(int i=0;i

unsigned char* p=(unsigned char*)src->imageData+src->widthStep*i;

for(int j=0;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);

//show ycrcb

cvShowImage("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;

}

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐