我的Python程序中有一个(float32
)热图矩阵,如下所示:
[[0.99782705 0.99782705 0.99782705 0.99782705 0.99782705 0.99782705
0.99782705 0.99782705 0.99782705]
[0.99782705 0.99782705 0.99782705 0.99782705 0.99782705 0.99782705
0.99782705 0.99782705 0.99782705]
[0.99782705 0.99782705 0.99782705 0.99782705 0.99782705 0.99782705
0.99782705 0.99782705 0.99782705]
[0.99782705 0.99782705 0.99782705 0.99782705 0.99782705 0.99782705
0.99782705 0.99782705 0.99782705]
[0.99782705 0.99782705 0.99782705 0.99782705 0.99782705 0.99782705
0.99919313 0.99782705 0.99782705]
[0.99782705 0.99782705 0.99782705 0.99782705 0.99782705 0.99782705
1. 0.99782705 0.99782705]
[0.99782705 0.99782705 0.99782705 0.99782705 0.99782705 0.99782705
0.99782705 0.99782705 0.99782705]
[0.99782705 0.99782705 0.99782705 0.99782705 0.99782705 0.99782705
0.99782705 0.99782705 0.99782705]
[0.99782705 0.99782705 0.99782705 0.99782705 0.99782705 0.99782705
0.99782705 0.99782705 0.99782705]]
以下是通过matplotlib.pyplot.matshow()
打印时的热图外观:
现在,我想将该矩阵的大小调整为图像的大小,并将其作为热图覆盖在该图像上。因此,首先我加载另一张图片,然后将热图调整为图片大小:
img = cv2.imread(image_path)
heatmap = cv2.resize(heatmap, (img.shape[1], img.shape[0]))
调整热图矩阵的大小后,将变为:
好,到目前为止,一切看起来都不错。现在,根据我在网上找到的各种资源,我想将该热图转换为uint8
RGB格式,应用cv2.COLORMAP_JET
色彩图,并将其覆盖到原始图像上:
heatmap = cv2.applyColorMap(np.uint8(255 * heatmap), cv2.COLORMAP_JET)
superimposed = heatmap * 0.4 + img
但这似乎不起作用。当我现在通过cv2.imshow('Heatmap', heatmap)
渲染热图时,它变成了普通的(红色)图像,它失去了原始热图的所有“功能”。因此,我要放置热图的图像也保持与以前相同(即渲染superimposed
的外观与img
完全一样)。
有什么主意我可能会在这里错过吗?
对于其他记录,我想实现以下类似功能:
Grad-CAM implementation for Keras models
答案 0 :(得分:2)
如果用于可视化,则需要在数字之间进行更大的分隔。您基本上有3个数字,并且在缩放它们(乘以255)时,它们基本上变成了2个数字(254和255)。当应用颜色时,两个数字几乎相同,而且真的很难知道哪个是哪个...
解决方案:
使用当前数字创建新的比例。您可以使用cv2.normalize
轻松做到这一点import matplotlib.pyplot as plt
import numpy as np
import cv2
heatmap = np.array([
[0.99782705,0.99782705,0.99782705,0.99782705,0.99782705,0.99782705,0.99782705,0.99782705,0.99782705],
[0.99782705,0.99782705,0.99782705,0.99782705,0.99782705,0.99782705,0.99782705,0.99782705,0.99782705],
[0.99782705,0.99782705,0.99782705,0.99782705,0.99782705,0.99782705,0.99782705,0.99782705,0.99782705],
[0.99782705,0.99782705,0.99782705,0.99782705,0.99782705,0.99782705,0.99782705,0.99782705,0.99782705],
[0.99782705,0.99782705,0.99782705,0.99782705,0.99782705,0.99782705,0.99919313,0.99782705,0.99782705],
[0.99782705,0.99782705,0.99782705,0.99782705,0.99782705,0.99782705,1.00000000,0.99782705,0.99782705],
[0.99782705,0.99782705,0.99782705,0.99782705,0.99782705,0.99782705,0.99782705,0.99782705,0.99782705],
[0.99782705,0.99782705,0.99782705,0.99782705,0.99782705,0.99782705,0.99782705,0.99782705,0.99782705],
[0.99782705,0.99782705,0.99782705,0.99782705,0.99782705,0.99782705,0.99782705,0.99782705,0.99782705]
])
heatmap = cv2.resize(heatmap, (400,300))
plt.matshow(heatmap)
plt.show()
heatmapshow = None
heatmapshow = cv2.normalize(heatmap, heatmapshow, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_8U)
heatmapshow = cv2.applyColorMap(heatmapshow, cv2.COLORMAP_JET)
cv2.imshow("Heatmap", heatmapshow)
cv2.waitKey(0)
您会得到:
注意:由于我没有示例图片,因此我只是将数字放入调整大小中。
但是,这里有一件事情要考虑。使用此解决方案,无论数量有多小,最大的数字都会是红色。如果您需要一个新的固定缩放比例(例如1.红色,而0是最小数字),则需要手动执行以下操作:
newvalue= (maxNew-minNew)/(max-min)*(value-max)+maxNew
其中maxNew= 255
和minNew=0
以及max和min将由您任意决定(例如0.9978和1.0)