# 一维熵二维熵局部熵的Python实现 **Repository Path**: YongXiang24Hao/applets ## Basic Information - **Project Name**: 一维熵二维熵局部熵的Python实现 - **Description**: 一维熵,二维熵,局部熵 - **Primary Language**: Python - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 2 - **Forks**: 0 - **Created**: 2021-01-15 - **Last Updated**: 2023-12-01 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 注意2022/5/8日补充 代码部分更新,详情参考:https://blog.csdn.net/YH_24H/article/details/112664232?spm=1001.2014.3001.5502 # 图像一维熵二维熵及python实现 ## 1 基础 熵年岁很大,建国前一年香农提出来的的,成精了。熵指的是体系的混乱的程度,越乱越大。图像熵是图像特征的一种统计形式,反映了图像中平均信息量的多少,能够反映图像各像素点的分布复杂程度。 ### 1.1 图像一维熵 只能表示图像灰度值的聚集特征,不能表征空间特征。公式: $$ H = - \sum_{i=0}^{255}log_2p_i $$ 其中Pi表示图像中灰度值为i(0≤i≤255)的像素所占的比例,熵非负 ### 1.2 二维熵 为表征灰度信息的空间特征,引入图像的像素点与该点的邻域信息,构成一个新的二元组,记为(i,j);其中i表示像素的灰度值(0≤i≤255), j表示邻域灰度均值(0≤j≤255),$P_{ij}=f(i,j)/WH$即可反映某像素位置上的灰度值与其周围像素的灰度分布的综合特征,其中f(i,j)为特征二元组(i,j)出现的次数,W,H为图像尺寸,公式: $$ j = {{\sum_{k=1}^8j(k)}\over{8}} $$ $$ H = - \sum_{i=0}^{255}\sum_{j=0}^{255}p_{ij}log_2p_{ij} $$ 邻域随便一点,反正求个均值就行了,九宫格,菱形,近圆,得为奇数,不理解就画图...(本文按九宫格火锅来写的) ### 1.3 局部熵 就是把图分成一个个区域,分别计算再融合成信息分布图,有点类似heatmap. ## 2 python 实现 ### 2.1 一维熵 ``` import cv2 import matplotlib.pyplot as plt import numpy as np import math def calc_array(): # img = cv2.imread('20201210_3.bmp',0) # img = np.zeros([16,16]).astype(np.uint8) a= [i for i in range(256)] img = np.array(a).astype(np.uint8).reshape(16,16) hist_cv = cv2.calcHist([img],[0],None,[256],[0,256]) #[0,256]的范围是0~255.返回值是每个灰度值出现的次数 # plt.subplot(111) # plt.plot(hist_cv) # plt.show() p = hist_cv/(len(img)*len(img[0])) #概率 E = 0 for i in range(len(p)): if(p[i] == 0): E = E else: E = float(E - p[i] * (math.log(p[i]) / math.log(2.0))) print(E) #熵 calc_array() ``` ### 2.2 二维熵 ``` import cv2 import matplotlib.pyplot as plt import numpy as np import math def calc_2D_Entropy(): ''' 邻域 3*3的小格子 __ __ __ |__|__|__| |__||||__| |__|__|__| 角点 __ __ ||||__| |__|__| 边 __ __ | |__| ||||__| |__|__| ''' a= [i for i in range(256)] img = np.array(a).astype(np.uint8).reshape(16,16) N = 1 S=img.shape IJ = [] #计算j for row in range(S[0]): for col in range(S[1]): Left_x=np.max([0,col-N]) Right_x=np.min([S[1],col+N+1]) up_y=np.max([0,row-N]) down_y=np.min([S[0],row+N+1]) region=img[up_y:down_y,Left_x:Right_x] # 九宫格区域 j = (np.sum(region) - img[row][col])/((2*N+1)**2-1) IJ.append([img[row][col],j]) print(IJ) # 计算F(i,j) F=[] arr = [list(i) for i in set(tuple(j) for j in IJ)] #去重,会改变顺序,不过此处不影响 for i in range(len(arr)): F.append(IJ.count(arr[i])) print(F) # 计算pij P=np.array(F)/len(F) # 计算熵 E = 0 for i in range(len(P)): if(P[i] == 0): E = E else: E = float(E - P[i] * (math.log(P[i]) / math.log(2.0))) print(E) calc_2D_Entropy() ``` ### 2.3 局部熵 可以当作是局部的确的一维熵,再拼起来。如下图(N=3,计算的是6*6这个局域),注意边缘点边界 ![20210115102248](https://yonhang-pic.oss-cn-chengdu.aliyuncs.com/pic/20210115102248.png) ``` from PIL import Image import numpy as np from matplotlib import pyplot as plt def entropy(signal): lensig=signal.size symset=list(set(signal)) propab=[np.size(signal[signal==i])/(1.0*lensig) for i in symset]#每个值的概率 ent=np.sum([p*np.log2(1.0/p) for p in propab]) return ent colorIm=Image.open('20201210_3.bmp') colorIm=np.array(colorIm) greyIm=colorIm.convert('L') greyIm=np.array(greyIm) N=3 S=greyIm.shape E=np.array(greyIm) #以图像左上角为坐标0点 for row in range(S[0]): for col in range(S[1]): Left_x=np.max([0,col-N]) Right_x=np.min([S[1],col+N]) up_y=np.max([0,row-N]) down_y=np.min([S[0],row+N]) region=greyIm[up_y:down_y,Left_x:Right_x].flatten() # 返回一维数组 E[row,col]=entropy(region) plt.subplot(1,3,1) plt.imshow(colorIm) plt.subplot(1,3,2) plt.imshow(greyIm, cmap=plt.cm.gray) plt.subplot(1,3,3) plt.imshow(E, cmap=plt.cm.jet) plt.xlabel('6x6 邻域熵') plt.colorbar() plt.show() ``` 结果如图,可知同内容部分熵较低 ![20210115141015](https://yonhang-pic.oss-cn-chengdu.aliyuncs.com/pic/20210115141015.png)