欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2024-02-11 12:41:10
...

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


二维

一、灰度直方图

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


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

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


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

#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;
}

实现效果:

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