在 OpenCV 中将热图矩阵可视化到图像上
Visualizing a heatmap matrix on to an image in OpenCV
我的 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)
渲染热图时,它变成了一个普通(红色)图像,它已经从原始热图中丢失了所有 "features" 。因此,我想要放置热图的图像也与以前相同(即渲染 superimposed
看起来与 img
完全相同)。
有什么想法我可能在这里遗漏了什么吗?
为了其他记录,我想实现与此类似的东西:
Grad-CAM implementation for Keras models
如果是为了可视化,你需要在数字之间做一个更大的分隔。你基本上有 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
以及最大值和最小值将由您任意决定(例如 0.9978 和 1.0)
我的 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)
渲染热图时,它变成了一个普通(红色)图像,它已经从原始热图中丢失了所有 "features" 。因此,我想要放置热图的图像也与以前相同(即渲染 superimposed
看起来与 img
完全相同)。
有什么想法我可能在这里遗漏了什么吗?
为了其他记录,我想实现与此类似的东西:
Grad-CAM implementation for Keras models
如果是为了可视化,你需要在数字之间做一个更大的分隔。你基本上有 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
以及最大值和最小值将由您任意决定(例如 0.9978 和 1.0)