我在网上找了写熵的计算,感觉都是计算色彩值出现的概率,没有找到二维空间有联系的计算。折腾了一上午,想到一个直线回归的方式来做二维图形色彩熵计算。下面是我简单的python代码。
def custom_sort(x):
return x[0]
mat = [ [ [70,70,70,70,71,71,72,72,71,69],
[69,68,68,68,68,68,69,69,69,68],
[68,68,67,67,67,66,66,66,67,67],
[67,66,66,65,65,65,63,64,66,67],
[67,66,66,65,65,64,62,63,65,66],
[67,65,64,64,65,66,65,65,64,63],
[65,64,63,63,64,64,64,63,62,62],
[64,63,62,62,62,61,63,62,61,61],
[63,63,62,61,61,61,61,61,60,59],
[65,64,63,63,62,61,60,59,59,58] ],
[ [4,4,2,2,3,3,3,2,2,3],
[3,3,3,2,2,3,3,2,2,3],
[3,3,3,2,2,2,3,2,2,2],
[4,3,3,3,2,2,3,3,2,2],
[4,3,3,2,2,2,3,3,3,3],
[5,4,3,3,2,2,3,3,3,3],
[4,4,3,3,2,2,2,2,2,2],
[3,4,4,3,2,2,2,2,2,2],
[3,4,4,3,3,3,3,3,3,3],
[4,4,4,3,4,3,3,3,3,2] ],
[ [6,6,5,5,5,5,5,5,5,5],
[6,6,5,5,5,5,5,5,5,6],
[5,5,5,5,5,5,6,6,6,6],
[5,5,6,6,6,6,6,5,5,6],
[6,6,6,6,6,6,6,5,5,5],
[6,7,6,6,6,6,5,5,5,5],
[5,5,6,6,6,6,5,5,5,5],
[5,6,5,5,6,6,5,5,4,5],
[6,5,5,5,6,6,5,5,5,4],
[6,6,6,6,6,5,5,6,6,5] ],
[ [194,195,195,195,195,195,195,196,196,196],
[195,195,195,195,195,196,196,196,196,196],
[195,195,195,195,195,196,196,196,196,196],
[195,195,195,195,195,196,196,196,196,196],
[195,195,195,195,195,195,196,196,196,196],
[194,194,194,194,195,195,195,195,195,195],
[193,193,193,194,194,194,195,195,195,195],
[193,193,193,193,193,194,194,194,195,195],
[194,194,194,194,194,194,194,195,193,193],
[193,194,194,194,194,194,194,194,193,193] ],
[ [47,46,46,45,44,42,41,40,39,39],
[48,47,46,45,44,42,41,40,39,40],
[49,47,47,46,44,43,41,40,39,41],
[49,48,47,46,44,43,41,40,39,41],
[41,45,45,44,44,44,41,40,40,39],
[41,46,45,44,44,44,41,40,40,39],
[42,46,46,44,43,42,42,41,40,40],
[43,47,46,44,43,42,42,41,41,40],
[44,47,45,45,43,42,41,42,41,39],
[45,47,46,44,42,42,41,41,42,40] ],
[[0,1,2,3,4,5,6,7,8,9],
[10,11,12,13,14,15,16,17,18,19],
[20,21,99,23,24,25,26,27,28,99],
[30,31,32,33,34,35,36,37,38,39],
[40,41,42,43,44,45,46,47,48,49],
[50,51,52,53,99,55,56,57,58,59],
[60,61,62,63,64,65,66,67,68,69],
[70,71,72,73,74,75,76,77,78,79],
[80,81,82,83,84,85,86,87,88,89],
[90,99,92,93,94,95,96,97,99,99]]
]
m = mat[5]
b = []
s = []
r = len(m)
i,j = 0,0
shape = [r, r]
entropy = 0
for p in range(r):
i_c = i+p
if i_c < 0 or i_c >= shape[0]:
continue
for q in range(r):
i_r = j+q
if i_r < 0 or i_r >= shape[1] :
continue
t = m[i_r][i_c]
# print(t, end=', ')
if t not in b:
s.append([t, 1, [[i_c, i_r]], i_c, i_r])
b.append(t)
else:
b_i = b.index(t)
s[b_i][1] += 1
s[b_i][2].append([i_c, i_r])
s[b_i][3] += i_c
s[b_i][4] += i_r
s.sort(key = custom_sort, reverse=False)
# print('t[%s]:'%len(s), end = ' ')
# for t in s:
# print( str(t[0])+'['+str(t[1])+']', end = ' ')
# print()
s_e = 0
for t in s:
e = 10
if t[1] <= 2 or t[4] == 0: #点少有两个或者点分布在一条竖线上就退出
s_e += e
continue
slop = t[3]/t[4] # t_c/t_r
# print(slop)
for t2 in t[2]:
e += abs(slop *t2[1] -t2[0])
# print(t[0], t2, slop *t2[1] -t2[0])
s_e += e
print(s_e/1000)
# 输出如下
# 0.4035127231265122
# 0.32725136126550436
# 0.3539429733471789
# 0.2816649667117608
# 0.3688488764702341
# 0.9661666666666666
我测试数据一共有六个矩阵,前面5个是我在图片上采集的数据,最后一个是我手动制造的矩阵数据,当矩阵中的点离散性越大,计算出来的值也就越大。
但还是有一些问题,我将点全部设置为相同的时候,算出来的值为0.34,虽然比较小,但这不是理论上的最小值,我目前够用了,没有在做优化。
有几个死数据的由来
- 由于矩阵是10*10的,所以上面代码e初始值为10。
- 最后除以1000是10的3次方。
更新
哈哈,上面相同的最小值,找到一个比较简单的解决方法:
# 将上面代码中的
for t2 in t[2]:
e += abs(slop *t2[1] -t2[0])
# 改为
for t2 in t[2]:
e += abs(slop *t2[1] -t2[0])/2
#减少直线归一化后的权重,将相同的值降低
# 上面倒数第一个矩阵的值为:0.9580833333333334
# 当色彩值完全相同的时候为:0.175