1. 最大熵是什么?

这里所说的熵是指信息熵信息熵是来自于信息论的一个词,它是对系统所含信息的一种度量。通俗的讲,系统的不确定性越大,那么系统的信息熵就越大。反之,一个系统如果确定性高(系统越有序),那么整个系统的信息熵就越小。其数学定义表述如下: $$ H = -\int_{\-\infty}^{+\infty}p(x)log[p(x)]dx $$ 上式中,$p(x)$ 表示灰度 $x$ 出现的频率。$H$ 则表示信息熵。

2. 最大熵图像分割

算法描述如下:

  1. 选取一个阈值$T$,使用该阈值将图像中的所有像素点分成两类,低于阈值$T$的所有像素记为背景B,高于阈值$T$的所有像素记为物体O。
  2. 计算每个灰度级在B或者O类中所占的概率。 背景:$$\frac{p_{i}}{p_{T}}, i=1,2,…,T$$ 物体: $$\frac{p_{i}}{1 - p_{T}}, i=T+1,T+2,…,L$$ 其中$$p_{T} = \sum_{i=0}^{T}{p(i)}$$。
  3. 分别计算背景和物体的信息熵 $$H_{B} = -\sum_{i}{\frac{p_{i}}{p_{t}}*log[\frac{p_{i}}{p_{t}}]}, i=1,2,…,T$$ $$H_{O} = -\sum_{i}{\frac{p_{i}}{1-p_{t}}*log[\frac{p_{i}}{1-p_{t}}]}, i=T+1,T+2,…,L$$
  4. 对图像中的每一个灰度级进行步骤1-3运算,得到使$max{(H_{O}+H_{B})}$时的T值,该值即为最大熵的分割点。

3.在OpenCV平台进行实现

/***************************************************************************************
Function: 最大熵分割算法
Input:    Mat 待分割的原图像
Output:   分割后图像
***************************************************************************************/
Mat EntropySeg(Mat src)
{
	int tbHist[256] = {0};											//每个像素值个数
	int index = 0;													//最大熵对应的灰度
	double Property = 0.0;											//像素所占概率
	double maxEntropy = -1.0;										//最大熵
	double frontEntropy = 0.0;										//前景熵
	double backEntropy = 0.0;										//背景熵
	//纳入计算的总像素数
	int TotalPixel = 0;												
	int nCol = src.cols * src.channels();							//每行的像素个数
	for (int i = 0; i < src.rows; i++)
	{
		uchar* pData = src.ptr<uchar>(i);
		for (int j = 0; j < nCol; ++j)
		{
			++TotalPixel;
			tbHist[pData[j]] += 1;
		}
	}

	for (int i = 0; i < 256; i++) 
	{
		//计算背景像素数
		double backTotal = 0;
		for (int j = 0; j < i; j++)
		{
			backTotal += tbHist[j];
		}

		//背景熵
		for (int j = 0; j < i; j++)
		{
			if (tbHist[j] != 0)
			{
				Property = tbHist[j] / backTotal;
				backEntropy += -Property * logf((float)Property);
			}
		}
		//前景熵
		for (int k = i; k < 256; k++)
		{
			if (tbHist[k] != 0)
			{
				Property = tbHist[k] / (TotalPixel - backTotal);
				frontEntropy += -Property * logf((float)Property);
			}
		}

		if (frontEntropy + backEntropy > maxEntropy)	//得到最大熵
		{
			maxEntropy = frontEntropy + backEntropy;
			index = i;
		}
		//清空本次计算熵值
		frontEntropy = 0.0;
		backEntropy = 0.0;
	}
	Mat dst;
	//index += 20;
	cv::threshold(src, dst, index, 255, 0);				//进行阈值分割
	return dst.clone();
}

这里写图片描述