熵
熵(entropy)指的是体系的混乱的程度,它在控制论、概率论、数论、天体物理、生命科学等领域都有重要应用,在不同的学科中也有引申出的更为具体的 定义,是各领域十分重要的参量。熵由鲁道夫·克劳修斯(Rudolf Clausius)提出,并应用在热力学中。后来在,克劳德·艾尔伍德·香农(Claude Elwood Shannon)第一次将熵的概念引入到信息论中来。
信息熵
利用信息论中信息熵概念,求出任意一个离散信源的熵(平均自信息量)。自信息是一个随机变量,它是指某一信源发出某一消息所含有的信息量。一条信息的信息量和它的不确定性有着直接的关系。所发出的消息不同,它们所含有的信息量也就不同。任何一个消息的自信息量都代表不了信源所包含的平均自信息量。不能作为整个信源的信息测度,因此定义自信息量的数学期望为信源的平均自信息量:
信息熵的意义:信源的信息熵H是从整个信源的统计特性来考虑的。它是从平均意义上来表征信源的总体特性的。对于某特定的信源,其信息熵只有一个。不同的信源因统计特性不同,其熵也不同。信息熵一般用符号H表示,单位是比特。变量的不确定性越大,熵也就越大。
图像熵
1.一维熵
图像熵是一种特征的统计形式,它反映了图像中平均信息量的多少。图像的一维熵表示图像中灰度分布的聚集特征所包含的信息量,令Pi 表示图像中灰度值为i的像素所占的比例,则定义灰度图像的一元灰度熵为:
其中Pi是某个灰度在该图像中出现的概率,可由灰度直方图获得。
2.二维熵
图像的一维熵可以表示图像灰度分布的聚集特征,却不能反映图像灰度分布的空间特征,为了表征这种空间特征,可以在一维熵的基础上引入能够反映灰度分布空间特征的特征量来组成图像的二维熵。选择图像的邻域灰度均值作为灰度分布的空间特征量,与图像的像素灰度组成特征二元组,记为( i, j ),其中i 表示像素的灰度值(0 <= i <= 255),j 表示邻域灰度均值(0 <= j <= 255):
式能反应某像素位置上的灰度值与其周围像素灰度分布的综合特征,其中f(i, j)为特征二元组(i, j)出现的频数,N 为图像的尺度。
源码
求一元灰度熵
%方法一
[M,N]=size(im);
temp=zeros(1,256);
%对图像的灰度值在[0,255]上做统计
for m=1:M;
for n=1:N;
if im(m,n)==0;
i=1;
else
i=im(m,n)+1;
end
temp(i)=temp(i)+1;
end
end
temp=temp./(M*N);
%由熵的定义做计算
result=0;
for i=1:length(temp)
if temp(i)==0;
result=result;
else
result=result-temp(i)*log2(temp(i));
end
end
求二维熵
%随机生成图像
A=floor(rand(8,8).*255);
[M,N]=size(A);
temp=zeros(256,256);
%均值滤波器,实现计算邻域灰度均值
h=fspecial('average') ;%默认3*3
y=filter2(h,A) ;
%对图像的灰度值和邻域均值在[0,255]上做统计
for m=1:M;
for n=1:N;
if A(m,n)==0;
i=1;
else
i=A(m,n)+1;
end
j = ceil(y(m,n));
temp(i,j)=temp(i,j)+1;
end
end
temp=temp./(M*N);
%由熵的定义做计算
result=0;
for i=1:size(temp,1)
for j=1:size(temp,2)
if temp(i,j)==0;
result=result;
else
result=result-temp(i,j)*log2(temp(i,j));
end
end
end
直方图均衡化原理
我们知道提高图像对比度的变换函数f(x)需要满足一下条件:
- f(x)在0<=x<=L−1上单调递增(不要求严格单调递增),其中L表示灰度级(L=256)
- f(x)的范围是[0,L−1]
我们知道当图像直方图完全均匀分布的时候,此时图像的熵是最大的(随机变量每个值的概率都相同时,概率最大),图像对比度是最大的。所以,理想情况下,图像经过变换函数f(x)
变换后,直方图能够均匀分布,此时对比度是最大的。
那问题来了?怎样的变换函数具有如此神奇的功能呢?[1]P74中给出了答案。
在图像处理中,有一个重要的函数,能够满足上面的条件:
其中px(x)表示概率密度函数,在离散的图像中,表示直方图的每个灰度级的概率(在图像中,灰度级就可以看成是一个随机变量,而直方图就是该随机变量的概率密度函数),由概率论的知识,我们可以知道,变换函数f(x)其实就是连续型随机变量x的分布函数,表示的是函数下方的面积。
分布函数的两个性质:1.单调不减 2.值域为[0,1],我们可以知道f(x)满足条件1和2
有人可能会有这个疑问?图像是离散的,为什么可以用连续的来表示呢?从数学角度来看,离散是连续的一种特例(图像就是一个很好的例子)。
下面我们证明变换后的直方图是均匀的。
由概率论知识,变换后的概率密度:
由变上限函数求导法则可知
反函数的导数等于原函数导数的倒数,所以
所以
看到了吧,变换后的概率密度函数是一个均匀分布,对于图像来说,就是每个灰度级概率都是相等的,达到了我们的目的。
下面我们需要将这个变换函数转换为图像中的表达,图像中,我们可以知道,可以使用求和代替积分,差分代替微分,所以上述的变换函数就是:
其中h(xi)表示直方图中每个灰度级像素的个数, w和 h分别表示图像的宽和高。
//不支持OpenCV的ROI
void GetHistogram(const Mat &image, int *histogram)
{
memset(histogram, 0, 256 * sizeof(int));
//计算直方图
int pixelCount = image.cols*image.rows;
uchar *imageData = image.data;
for (int i = 0; i <= pixelCount - 1; ++i)
{
int gray = imageData[i];
histogram[gray]++;
}
}
void EqualizeHistogram(const Mat &srcImage, Mat &dstImage)
{
CV_Assert(srcImage.type() == CV_8UC1);
dstImage.create(srcImage.size(), srcImage.type());
// 计算直方图
int histogram[256];
GetHistogram(srcImage, histogram);
// 计算分布函数(也就是变换函数f(x))
int numberOfPixel = srcImage.rows*srcImage.cols;
int LUT[256];
LUT[0] = 1.0*histogram[0] / numberOfPixel*255;
int sum = histogram[0];
for (int i = 1; i <= 255; ++i)
{
sum += histogram[i];
LUT[i] = 1.0*sum / numberOfPixel * 255;
}
// 灰度变换
uchar *dataOfSrc = srcImage.data;
uchar *dataOfDst = dstImage.data;
for (int i = 0; i <= numberOfPixel - 1; ++i)
dataOfDst[i] = LUT[dataOfSrc[i]];
}
Opencv Python 实现
import cv2
import numpy as np
img = cv2.imread('test1.jpg',1)
cv2.imshow('src',img)
cv2.waitKey(0)
#转换单通道灰度图
gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
cv2.imshow('gray',gray)
cv2.waitKey(0)
#均衡化
dst = cv2.equalizeHist(gray)
cv2.imshow('dst',dst)
cv2.waitKey(0)