【阈值分割】最大熵分割法

第一次尝试写博客,希望能坚持下去。。。
最近在做红外小目标检测,用到一个最大熵分割法,ok,下面介绍一下。


最大熵分割法

现在主要用的熵算法有 P 氏熵算法,KSW 熵算法、JM 熵算法下面以经典的 KSW 熵算法为例介绍其原理和计算过程。

KSW熵算法

设分割阈值为设分割阈值为t,

  

T为{0,1,2,...t}的灰度分布,B为{t+1,t+2,...L-1}的灰度分布,则概率分布为:

                                                                                                                         


式中

       

则这两个概率密度相关的熵为:

  

 

定义函数φ(t)为H(T)和H(B)的和,则

 

求出φ(t)最大时的灰度级t即为所求的最佳阈值。

灰度直方图的求法参见 http://blog.csdn.net/xiaowei_cqu/article/details/7600666


代码如下:

 
#include <cv.h>
#include <opencv2/opencv.hpp>  
#include <opencv2/legacy/legacy.hpp>
using namespace cv;

float calc_entropy(CvHistogram *hist, int begin, int end)
{
	float total = 0;  // 总概率
	// 得到总的Pi
	for(int i = begin; i < end; i++)
	{
		total += cvQueryHistValue_1D(hist,i);
	}

	float entropy = 0;  // 熵
	
	for(int i = begin; i < end; i++)
	{
		float probability = cvQueryHistValue_1D(hist, i);
		if(probability == 0)
			continue;
		probability /= total;

		entropy += -probability*log(probability);
	}

	return entropy;
}

int ksw_entropy(IplImage *img)
{
	assert(img != NULL);
	assert(img->depth == 8);  
    assert(img->nChannels == 1);  

	float range[2] = {0,255};
	float *ranges[1] = {&range[0]};
	int sizes = 256;

	// 创建直方图
	CvHistogram *hist = cvCreateHist(1, &sizes, CV_HIST_ARRAY, ranges, 1);
	// 直方图计算
	cvCalcHist(&img, hist, 0, 0);
	// 直方图归一化
	cvNormalizeHist(hist, 1.0); 

	int threshold = 0;
	float max_entropy = 0;
	// 循环计算,得到做大熵以及分割阈值
	for(int i = 0; i < sizes; i++)
	{
		float entropy = calc_entropy(hist, 0, i) + calc_entropy(hist, i+1, sizes);
		if(entropy > max_entropy)
		{
			max_entropy = entropy;
			threshold = i;
		}
	}

	return threshold;
}
int main(int argc, char **argv)
{
	IplImage *img = cvLoadImage("1.bmp", CV_LOAD_IMAGE_GRAYSCALE);
	IplImage *reimg = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 1);

	int threshold = ksw_entropy(img);
	cvThreshold(img, reimg, threshold, 255, CV_THRESH_BINARY); 

	cvNamedWindow("img");
	cvShowImage("img", img);
	cvNamedWindow("reimg");
	cvShowImage("reimg", reimg);

	cvWaitKey(0);
	return 0;
}

在学习获取灰度直方图的时候,有一个函数让我费解了半天,cvNormalizeHist,灰度归一化,刚开始就是搞不懂这个灰度归一化是指的什么,

opencv给出的函数解释如下:



什么叫the sum of the bins becomes equal to factor,好吧,后来明白了,其实意思就是说,把直方图纵坐标的值相加的和等于第二个参数,所以如果设为1的话,那纵坐标的值就是该灰度级的概率了。

下面是实验图片:

             

                                  图1  原图                                          图2   最大熵阈值分割后图片

效果很不理想吧,所以在做阈值分割前需要加入tophat,后面博客会讲到。

全文完。


  • 2
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值