//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; } }
return threshold; }
我在手的自动检测中使用这个方法,效果很好。
下面是使用上述两个函数的简单的主程序,可以试运行一下,如果处理视频,要保证第一帧时,手要在图像中。
#include
#pragma comment(lib,\#pragma comment(lib,\#pragma comment(lib,\
#include
int main(int argc, char** argv) {
#ifdef VIDEO //video process
CvCapture* capture=cvCreateCameraCapture(-1); if (!capture) {
cout<<\ exit(0); }
int threshold=-1; IplImage* img;
while (img=cvQueryFrame(capture)) {
cvShowImage(\
cvCvtColor(img,img,CV_RGB2YCrCb);
IplImage* imgCb=cvCreateImage(cvGetSize(img),8,1); cvSplit(img,NULL,NULL,imgCb,NULL); if (threshold<0) {
threshold=cvThresholdOtsu(imgCb); }
//cvThresholdOtsu(imgCb,imgCb);
cvThreshold(imgCb,imgCb,threshold,255,CV_THRESH_BINARY); cvErode(imgCb,imgCb); cvDilate(imgCb,imgCb);
cvShowImage(\ cvReleaseImage(&imgCb);
if (cvWaitKey(3)==27) //esc {
break; } }
cvReleaseCapture(&capture);
#else //single image process
const char* filename=(argc>=2?argv[1]:\
IplImage* img=cvLoadImage(filename,CV_LOAD_IMAGE_GRAYSCALE);
cvThresholdOtsu(img,img); cvShowImage( \ char buf[256];
sprintf_s(buf,256,\ cvSaveImage(buf,img);
cvErode(img,img); cvDilate(img,img); cvShowImage( \
sprintf_s(buf,256,\ cvSaveImage(buf,img);
cvWaitKey(0); #endif
return 0; }
#include
#pragma comment(lib,\#pragma comment(lib,\#pragma comment(lib,\#include
using namespace std; int main(int argc, char** argv) {
#ifdef VIDEO //video process
CvCapture* capture=cvCreateCameraCapture(-1); if (!capture) {
cout<<\ exit(0); }
int threshold=-1; IplImage* img;
while (img=cvQueryFrame(capture)) {
cvShowImage(\
cvCvtColor(img,img,CV_RGB2YCrCb);
IplImage* imgCb=cvCreateImage(cvGetSize(img),8,1); cvSplit(img,NULL,NULL,imgCb,NULL); if (threshold<0) {
threshold=cvThresholdOtsu(imgCb); }
//cvThresholdOtsu(imgCb,imgCb);
cvThreshold(imgCb,imgCb,threshold,255,CV_THRESH_BINARY); cvErode(imgCb,imgCb); cvDilate(imgCb,imgCb);
cvShowImage(\ cvReleaseImage(&imgCb); if (cvWaitKey(3)==27) //esc {
break; } }
cvReleaseCapture(&capture);
#else //single image process
const char* filename=(argc>=2?argv[1]:\
IplImage* img=cvLoadImage(filename,CV_LOAD_IMAGE_GRAYSCALE); cvThresholdOtsu(img,img); cvShowImage( \ char buf[256];
sprintf_s(buf,256,\ cvSaveImage(buf,img); cvErode(img,img); cvDilate(img,img); cvShowImage( \
sprintf_s(buf,256,\ cvSaveImage(buf,img); cvWaitKey(0); #endif
return 0; }