实用计算机视觉 -- 一种基于直方图的最优阈值计算方法

来源:互联网 发布:萤石软件下载 编辑:程序博客网 时间:2024/06/17 00:00

按照惯例,首先放上测试图片:


基于直方图概率统计分布的最优阈值计算算法如下:



其中的定义见博客<实用计算机视觉 -- 一种基于直方图的自动阈值计算方法>,经过每一次迭代后,将初始化的灰度水平加1,直到算法收敛,验证代码如下:

int computeOptimalTh(Mat &image, int init_threshold){
CV_Assert(image.channels() == 1 
&& init_threshold>=0 
&& init_threshold<=255);
float channel_range[] = { 0.0, 255.0 };
const float* channel_ranges = channel_range;
bool uniform = true; bool accumulate = false;
int histSize = 256;
Mat hist(histSize,1,CV_32FC1);
calcHist(&image, 1, 0, Mat(), hist,
1, &histSize, &channel_ranges, uniform, accumulate);
// Normalize the result to [ 0, histImage.rows ]
//normalize(hist, hist, 0, image.rows, NORM_MINMAX, -1, Mat());
Mat prob_hist(hist.size(), CV_32FC1);
cout << "HIST:" << hist.rows << " " << hist.cols << endl;

for (int row = 0; row < hist.rows; ++row){
prob_hist.at<float>(row, 0) = hist.at<float>(row, 0) / (image.rows*image.cols);
//cout << "probablity:" << prob_hist.at<float>(row, 0) << endl;
}
float Wb=0.0, Wf=0.0,Ub=0.0,Uf=0.0;
int T_pre, T_now;

T_pre = init_threshold;
for (int value = 0; value < init_threshold; ++value){
Wb += prob_hist.at<float>(value, 0);
}
Wf = 1.0 - Wb;
for (int value = 0; value < init_threshold; ++value){
Ub += (value * prob_hist.at<float>(value, 0)) / Wb;
//cout << "Ub:" << Ub << endl;
}
for (int value = init_threshold; value <= 255; ++value){
Uf += (value * prob_hist.at<float>(value, 0)) / Wf;
}


T_now = (int)(Ub + Uf) / 2;
Wb = 0.0, Wf = 0.0, Ub = 0.0, Uf = 0.0;


while (T_now != T_pre){
++T_pre;
for (int value = 0; value < T_pre; ++value){
Wb += prob_hist.at<float>(value,0);
}


Wf = 1 - Wb;


for (int value = 0; value < T_pre; ++value){
Ub +=(value * prob_hist.at<float>(value,0)) / Wb;
//cout << "Ub:" << Ub << endl;
}
for (int value = T_pre; value <= 255; ++value){
Uf += (value * prob_hist.at<float>(value,0)) / Wf;
}
T_now = int((Ub + Uf) / 2);
Wb = 0.0, Wf = 0.0, Ub = 0.0, Uf = 0.0;
}


return (int)T_now;
}

因为测试图片中,皮肤像素所占比例很大,猜想与之前的博客中实现的皮肤检测效果相差不大,二者的效果如下:


阅读全文
1 0