在基础图像上叠加热力图 OpenCV Python

26
请看这个GitHub页面。我想用 Python PIL、open cv 或 matplotlib 库以此方式生成热图。有人能帮我弄清楚吗?叠加的热图 我可以创建一个与输入相同大小的网络热图,但是我无法将它们叠加。热图形状为(800,800),底图形状为(800,800,3)。

1
你有没有找到解决方案?我也有相同的要求。 - Ganesh Gudghe
4个回答

34

更新的答案--2022年4月29日。

在多次评论后,我决定用更好的可视化图表更新这篇文章。

请考虑以下图片:

img = cv2.imread('image_path')

enter image description here

在将图像转换为LAB格式后,对其a通道进行二值化处理,得到了一个二进制图像:

lab = cv2.cvtColor(img, cv2.COLOR_BGR2LAB)
a_component = lab[:,:,1]
th = cv2.threshold(a_component,140,255,cv2.THRESH_BINARY)[1]

输入图像描述

应用高斯模糊:

blur = cv2.GaussianBlur(th,(13,13), 11)

在此输入图像描述

生成的热力图:

heatmap_img = cv2.applyColorMap(blur, cv2.COLORMAP_JET)

enter image description here

最后,将热力图叠加在原始图像上:

super_imposed_img = cv2.addWeighted(heatmap_img, 0.5, img, 0.5, 0)

这里输入图像描述

注意: 您可以改变函数cv2.addWeighted中的权重参数并观察差异。


1
我的意思是第二张图片。请纠正它!heated_img和fin看起来一样。 - curio17
4
您的总体方法是正确的。但第二和第三张图片看起来一样,就是这样!请更换第二张图片。 - curio17
让我们在聊天中继续这个讨论 - curio17
答案很好。但是直接创建图像的热力图并将其覆盖在图像上有些奇怪。我认为这就是 @curio1729 感到困惑的原因。通常,叠加的热力图是对图像进行估计/预测/其他处理的结果。 - user3731622
我同意。如果您大幅模糊输入,这将更清晰。我了解您的热图仅是一个示例,但由于它与原始图像具有完全相同的基础数据,它看起来并不像人们所期望的那样。 - Geoff

3
我的代码从一个名为cam的热力图矩阵(224,224)开始,通过opencv应用于原始图像frame;看起来效果还不错。"最初的回答"
import numpy as np
from cv2 import cv2
from skimage import exposure 
...

capture = cv2.VideoCapture(...)
while True:
    ret, frame = capture.read()

    if ret:
        #resize original frame
        frame = cv2.resize(frame, (224, 224)) 

        #get color map
        cam = getMap(frame)
        map_img = exposure.rescale_intensity(cam, out_range=(0, 255))
        map_img = np.uint8(map_img)
        heatmap_img = cv2.applyColorMap(map_img, cv2.COLORMAP_JET)

        #merge map and frame
        fin = cv2.addWeighted(heatmap_img, 0.5, frame, 0.5, 0)

        #show result
        cv2.imshow('frame', fin)

getMap()函数根据帧获取headmap;
我找到了一些有关这个主题的有趣免费视频: https://www.youtube.com/watch?v=vTY58-51XZA&t=14s https://www.youtube.com/watch?v=4v9usdvGU50&t=208s 最初的回答。

0

我在这行代码处理灰度图像时遇到了一些问题

super_imposed_img = cv2.addWeighted(heatmap_img, 0.5, img, 0.5, 0)

但是这个代码对我起作用了

plt.imshow(binary_classification_result * 0.99 + original_gray_image * 0.01)

0
在你分享的页面上,它是通过一个预训练模型完成的。你可以使用像ResNet这样的骨干网络:
加载骨干网络:
resnet_50 = tf.keras.applications.ResNet50(input_shape=(224, 224, 3),
                                           include_top=False,
                                           weights='imagenet')

预处理图像,使其与resnet的默认设置相匹配
img = cv2.imread("/content/your_image.jpg")[:,:,::-1]
img = cv2.resize(image, (224, 224))
ax = plt.imshow(img)

def preprocess(img):
  # use the pre processing function of ResNet50 
  img = preprocess_input(img)
  
  #expand the dimension
  return np.expand_dims(img, 0)

input_image = preprocess(img)

应用本文的建议:
def postprocess_activations(activations):

  output = np.abs(activations)
  output = np.sum(output, axis = -1).squeeze()

  #resize and convert to image 
  output = cv2.resize(output, (224, 224))
  output /= output.max()
  output *= 255
  return 255 - output.astype('uint8')

生成和绘制热力图:
def apply_heatmap(weights, img):

   #generate heat maps 
   heatmap = cv2.applyColorMap(weights, cv2.COLORMAP_JET)
   heatmap = cv2.addWeighted(heatmap, 0.7, img, 0.3, 0)
return heatmap

剧情:
 def plot_heatmaps(rng):
  level_maps = None
  
  #given a range of indices generate the heat maps 
  for i in rng:
    activations = get_activations_at(input_image, i)
    weights = postprocess_activations(activations)
    heatmap = apply_heatmap(weights, img)
    if level_maps is None:
      level_maps = heatmap
    else:
      level_maps = np.concatenate([level_maps, heatmap], axis = 1)
  plt.figure(figsize=(15, 15))
  plt.axis('off')
  ax = plt.imshow(level_maps)
plot_heatmaps(range(164, 169))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接