Opencv2.4学习::(二维)最大熵阈值分割----信息量最大化分割

一维最大熵阈值分割应该比较好理解,可参见:http://blog.sina.com.cn/s/blog_159aff7940102xbm4.html


二维

一、灰度直方图


二、熵(这里实在看不懂,请大神赐教)


虽然看不懂,但还是按书上敲一次,代码实现:

#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<iostream>
using namespace std;
using namespace cv;
//计算当前位置的能量熵
float caculateCurrentEntropy(Mat hist, int threshold)
{
	float BackgroundSum = 0, targetSum = 0;
	const float*pDataHist = (float*)hist.ptr<float>(0);
	for (int i = 0; i < 256; i++){
		//累计背景值
		if (i < threshold){
			BackgroundSum += pDataHist[i];
		}
		else{//累计前景目标值
			targetSum += pDataHist[i];
		}
	}
	//输出
	//cout << BackgroundSum << " " << targetSum << endl;
	float BackgroundEntropy = 0, targetEntropy = 0;
	for (int i = 0; i < 256; i++){
		//计算背景熵
		if (i < threshold){
			if (pDataHist[i] == 0)
				continue;
			float ratiol = pDataHist[i] / BackgroundSum;
			//计算当前背景熵
			BackgroundEntropy += (-ratiol)*logf(ratiol);
		}
		else{//计算前景目标熵
			if (pDataHist[i] == 0)
				continue;
			float ratio2 = pDataHist[i] / targetSum;
			targetEntropy += (-ratio2)*logf(ratio2);
		}
	}
	return (targetEntropy + BackgroundEntropy);
}
//寻找最大熵值并分割
Mat maxEntropySegMentation(Mat inputImage)
{
	//初始化直方图参数
	const int channels[1] = { 0 };
	const int histSize[1] = { 256 };
	float pranges[2] = { 0, 256 };
	const float * ranges[1] = { pranges };
	MatND hist;
	//计算直方图
	calcHist(&inputImage, 1, channels,
		Mat(), hist, 1, histSize, ranges);
	float maxentropy = 0;
	int max_index = 0;
	Mat result;
	//遍历分割阈值,并求取最大熵下的分割阈值
	for (int i = 0; i < 256; i++){
		float cur_entropy = caculateCurrentEntropy(hist, i);
		//取最大熵下的分割阈值
		if (cur_entropy > maxentropy) {
			maxentropy = cur_entropy;
			max_index = i;
		}
	}
	//二值化分割
	threshold(inputImage, result, max_index, 255,
		CV_THRESH_BINARY);
	return result;
}
int main()
{
	Mat srcImage = imread("F:\\opencv_re_learn\\2.jpg");
	if (!srcImage.data){
		cout << "failed to read" << endl;
		system("pause");
		return -1;
	}
	Mat srcGray;
	cvtColor(srcImage, srcGray, CV_BGR2GRAY);
	//最大熵阈值分割
	Mat result = maxEntropySegMentation(srcGray);
	imshow("srcImage", srcImage);
	imshow("result", result);
	waitKey(0);
	return 0;
}

实现效果:

展开阅读全文

没有更多推荐了,返回首页