数字图像处理–实验二B图像的一维熵与二维熵算法
本文主要是对图像进行一维熵以及二维熵的计算,下面附有实现的代码
文章目录
- 数字图像处理--实验二B图像的一维熵与二维熵算法
- 一、 实验内容
- 二、 一维熵
- 1. 一维熵的定义
- 2. 一维熵的C++代码实现
- 三、 二维熵
- 1. 二维熵的定义
- 2. 二维熵的C++代码实现
一、 实验内容
B实验:使用VC++设计程序:对于一幅256级灰度图像,求其一元熵值、二维熵值
实验现象:
二、 一维熵
1. 一维熵的定义
一元灰度熵的定义:
-
概念: 图像熵是一种特征的统计形式,用于反映图像中平均信息量的多少。
-
一维熵: 表示图像中灰度分布的聚集特征所包含的信息量。
-
概率 (p_i): 用于描述某个灰度值 (i) 在图像中出现的概率,其取值范围是 (0 \leq p_i \leq 1)。这个概率可以通过灰度直方图获得。
-
一元灰度熵 (H_1): 通过以下公式定义:
H 1 = − ∑ i = 0 L − 1 p i ⋅ log 2 ( p i ) H_1 = - \sum_{i=0}^{L-1} p_i \cdot \log_2(p_i) H1=−i=0∑L−1pi⋅log2(pi)
其中,(L) 是灰度级别的数量, p i p_i pi 是灰度值为 (i) 的像素在图像中出现的概率。
这个一元灰度熵的计算利用了香农熵的概念,衡量了图像中灰度分布的聚集特征所包含的信息量。高一元灰度熵通常表示图像的灰度分布较分散,低一元灰度熵表示图像的灰度分布较集中。
2. 一维熵的C++代码实现
double entropy_1 = 0.0; //一维熵
double entropy_2 = 0.0; //二维熵
//获取图高
int height = pDoc->m_pDibInit->GetHeight();
//获取图宽
int width = pDoc->m_pDibInit->GetWidth();
int pixelGray[256] = { 0 };
for(int i=0;i<height;i++) //统计各灰度值的像素点的个数
for (int j = 0; j < width; j++)
{
int grey = pDoc->m_pDibInit->GetPixelGray(i, j);
pixelGray[grey]++;
}
//将各灰度值个数转换成概率
double PixGray[256] = { 0.0 };
for (int i = 0; i < 256; i++)
{
PixGray[i] = (pixelGray[i]+0.0) / width /height;
if (PixGray[i])
entropy_1 += PixGray[i] * (log(PixGray[i]) / log(2)); //将log(e)转换成log(2)
}
entropy_1 = -entropy_1;
三、 二维熵
1. 二维熵的定义
图像的一维熵可以表示图像灰度分布的聚集特征,却不能反映图像灰度分布的空间特征,为了表征这种空间特征,可以在一维熵的基础上引入能够反映灰度分布空间特征的特征量来组成图像的二维熵。
选择图像的邻域灰度均值作为灰度分布的空间特征量,与图像的像素灰度组成特征二元组,记为(i, j),其中i表示像素的灰度值(0 ≤ i≤ 255),j表示邻域灰度均值(0≤j≤255):
P
i
j
=
f
(
i
,
j
)
/
(
M
∗
N
)
P_{ij}=f(i,j)/(M*N)
Pij=f(i,j)/(M∗N)
上式能反应某像素位置上的灰度值与其周围像素灰度分布的
综合特征,其中f(i, j)为特征二元组(i, j)出现的频数,M、N分别为图像的宽度和高度,定义离散的图像二维熵为:
H
=
−
∑
i
=
0
L
−
1
∑
j
=
0
L
−
1
p
i
⋅
log
2
(
p
i
)
H = - \sum_{i=0}^{L-1}\sum_{j=0}^{L-1} p_i \cdot \log_2(p_i)
H=−i=0∑L−1j=0∑L−1pi⋅log2(pi)
其中,(L) 是灰度级别的数量,
p
i
p_i
pi 是灰度值为 (i) 的像素在图像中出现的概率。
构造的图像二维熵可以在图像所包含信息量的前提下,突出反映图像中像素位置的灰度信息和像素邻域内灰度分布的综合特征。
2. 二维熵的C++代码实现
//二维熵
int val[256][256] = { 0 }; //存储每一个像素点的领域灰度均值
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
int sum = 0; //记录领域灰度之和
int num = 0; //统计领域取点的数量
for (int k = -1; k <= 1; k++)
{
for (int m = -1; m <= 1; m++)
{
if (i + k >= 0 && i + k < 256 && j + m >= 0 && j + m < 255)
{
sum += pDoc->m_pDibInit->GetPixelGray(i + k, j + m);
num++;
}
}
}
val[i][j] = sum / num;
}
}
int F[256][256] = { 0 }; //统计f[i][j]的频数,i为该点灰度值,j为该点领域灰度均值
float p_F[256][256] = { 0.0 }; //将频数转换成概率
for(int i=0;i<height;i++)
for (int j = 0; j < width; j++)
{
int gray = pDoc->m_pDibInit->GetPixelGray(i, j);
F[gray][val[i][j]]++;
}
for (int k = 0; k < height; k++)
for (int m = 0; m < width; m++)
{
p_F[k][m] = (F[k][m]+0.0) / height /width;
if (p_F[k][m])
{
entropy_2 += p_F[k][m] * (log(p_F[k][m]) / log(2)); //将log(e)转换成log(2)
}
}
entropy_2 = -entropy_2;
CString str1;
// 显示信息
str1.Format("图像一维熵:%f,图像二维熵:%f", entropy_1, entropy_2);
MessageBox(str1);