通过迭代方法选择阈值, 计算方法如下:
(1)选择灰度图的平均值作为初始阈值T0 ;
(2)计算小于等于T0的平均值T1, 和大于T0的平均值T2;
(3)新的阈值为T = (T1 + T2)/ 2;
(4)比较T和T0,若相等,则返回T,即为迭代阈值; 否则 T0 = T,重复(1)-(3)
#include"cv.h" #include "highgui.h" int IterationThreshold(CvMat* gray); int main() { IplImage *src = cvLoadImage("flower.jpg",1); const int width = src->width; const int height = src->height; CvMat *gray = cvCreateMat(height, width, CV_8UC1); cvCvtColor(src, gray, CV_BGR2GRAY); int thres = IterationThreshold(gray); cvThreshold(gray, gray, thres, 255, CV_THRESH_BINARY); cvShowImage("SRC", src); cvShowImage("GRAY", gray); cvWaitKey(0); cvCvtColor(gray, src, CV_GRAY2BGR); cvSaveImage("DST.bmp", src); cvReleaseMat(&gray); return 0; } int IterationThreshold(CvMat* gray) { int width = gray->width; int height = gray->height; //直方图统计 int histData[256] = {0}; for(int j = 0; j < height; j ++) { uchar*data = (uchar*)(gray->data.ptr + j * gray->step); for (int i = 0; i < width; i ++) { histData[data[i]]++; } } //求图像的平均灰度值作为初始阈值 int T0 = 0; for (int i = 0; i < 256; i ++) { T0 += i * histData[i]; } T0 /= width * height; //迭代 int T1 = 0, T2 = 0; int num1 = 0, num2 = 0; int T = 0; while (1) { for ( int i = 0; i < T0+1; i ++) { T1 += i * histData[i]; num1 += histData[i]; } if (num1 == 0) continue; for ( int i = T0 + 1; i < 256; i ++) { T2 += i * histData[i]; num2 += histData[i]; } if (num2 == 0) continue; T = (T1 / num1 + T2 / num2) / 2; if ( T == T0 ) break; else T0 = T; } return T; }
源图和效果图如下:


发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/177265.html原文链接:https://javaforall.net
