Python 直方图均衡
文章目录
代码
import numpy as np
def histequalize(X):
if len(X.shape) == 2: # 判断是否为单通道
N = X.shape[0] * X.shape[1]
hist_X = np.bincount(X.reshape((N, )), minlength=256)
XtoY = np.zeros((256, ))
Y = np.zeros(X.shape)
for i in range(256):
XtoY[i] = np.sum(hist_X[0:i]) + hist_X[i]
XtoY = XtoY / N
XtoY = np.round(XtoY * 255) # 如果使用PPT上的公式,结果与opencv不一样
# XtoY = np.round((XtoY - np.min(XtoY)) / (1 - np.min(XtoY)) * 255) # 对映射XtoY进行归一化,得到的结果与opencv相同
for i in range(X.shape[0]):
for j in range(X.shape[1]):
Y[i, j] = XtoY[X[i, j]]
Y = Y.astype('int32')
hist_Y, _ = np.histogram(Y, 255, (0, 255))
return Y, hist_Y
else:
return
测试
对如下矩阵进行均衡化
[[1, 5, 255, 225, 100, 200, 255, 200],
[1, 7, 254, 255, 100, 10, 10, 9],
[3, 7, 10, 100, 100, 2, 9, 6],
[3, 6, 10, 10, 9, 2, 8, 2],
[2, 1, 8, 8, 9, 3, 4, 2],
[1, 0, 7, 8, 8, 3, 2, 1],
[1, 1, 8, 8, 7, 2, 2, 1],
[2, 3, 9, 8, 7, 2, 2, 0]]
- 如果按照一般的公式,结果与opencv库函数的结果有差别。对应代码为
XtoY = np.round(XtoY * 255)
结果为
[[ 40 112 255 239 227 235 255 235]
[ 40 139 243 255 227 211 211 191]
[104 139 211 227 227 84 191 120]
[104 120 211 211 191 84 171 84]
[ 84 40 171 171 191 104 108 84]
[ 40 8 139 171 171 104 84 40]
[ 40 40 171 171 139 84 84 40]
[ 84 104 191 171 139 84 84 8]]
- 如果对映射公式进行归一化,结果与opencv库函数相同。对应代码为
XtoY = np.round((XtoY - np.min(XtoY)) / (1 - np.min(XtoY)) * 255)
结果为
[[ 33 107 255 239 226 234 255 234]
[ 33 136 243 255 226 210 210 189]
[ 99 136 210 226 226 78 189 115]
[ 99 115 210 210 189 78 169 78]
[ 78 33 169 169 189 99 103 78]
[ 33 0 136 169 169 99 78 33]
[ 33 33 169 169 136 78 78 33]
[ 78 99 189 169 136 78 78 0]]