Python热力图用于屏幕坐标和频率字典

3

只是为了好玩,我试图编写一个鼠标跟踪脚本,我已经完成了基础部分,但是我在热力图方面完全没有成功。

我的初始代码是通过PIL保存图像(仅用于检查它是否有效),这很好,但显然它只是单个点。然后我尝试实现自己的热图,但发现这需要半年多的时间才能处理一些非常基本的东西,所以也不会起作用。

我一直在尝试使用不同的matplotlib示例,但我才意识到“热图”在这种情况下有不同的含义。

enter image description here

它不是不工作,但也绝对不是我希望看到的结果。我想知道是否有人知道如何获取另一种类型的热图,其中你可以得到热斑?我一直在谷歌各种术语,但似乎都会导致相同的3个或更多的SO问题。

数据存储在一个字典中{(x, y): frequency},因此要获得上面的结果,我使用了这段代码(matplotlib部分来自在Matplotlib中绘制二维热图):

import matplotlib.pyplot as plt

resolution = (1920, 1080)

total = []
for y in range(resolution[1]):
    row = []
    for x in range(resolution[0]):
        try:
            row.append(data[(x, y)])
        except KeyError:
            row.append(0)
    total.append(row)

plt.imshow(total, cmap='hot', interpolation='nearest')
plt.show()

那个速度并不太重要,因为它将与跟踪分开完成,我只是想要一些最初可以工作的东西。

编辑:只是为了更清楚(如果不清楚,我很抱歉),我想要像这样的东西: enter image description here


只要您的数据字典确实按照您的期望格式进行了格式化,那么该代码应该可以正常工作。在我看来,您只是在绘制零,因此我建议查看try/except语句中发生了什么。 - Sven Rusch
如果你看高分辨率的话,它确实可以工作,但只会绘制单个像素。我想要的是blob样式的热力图。 - Peter
1个回答

2

我针对绘制此类热图的解决方案如下。很容易使用 data[(x, y)] 填充二维 numpy 数组中的数据,然后使用 plot 函数进行绘制。请注意,您可以使用任何想要的颜色映射,我使用了代码中提供的那个。示例应该可以直接使用。

可以使用高斯模糊来实现“blobby”效果。可以调整 sigma 值使其更加清晰或柔和。

import matplotlib.pyplot as plt
from matplotlib.colors import LinearSegmentedColormap
import numpy as np

import scipy.ndimage.filters as filters


def plot(data, title, save_path):
    colors = [(0, 0, 1), (0, 1, 1), (0, 1, 0.75), (0, 1, 0), (0.75, 1, 0),
              (1, 1, 0), (1, 0.8, 0), (1, 0.7, 0), (1, 0, 0)]

    cm = LinearSegmentedColormap.from_list('sample', colors)

    plt.imshow(data, cmap=cm)
    plt.colorbar()
    plt.title(title)
    plt.savefig(save_path)
    plt.close()

if __name__ == "__main__":
    w = 640
    h = 480

    data = np.zeros(h * w)
    data = data.reshape((h, w))

    # Create a sharp square peak, just for example
    for x in range(300, 340):
        for y in range(300, 340):
            data[x][y] = 100

    # Smooth it to create a "blobby" look
    data = filters.gaussian_filter(data, sigma=15)

    plot(data, 'Sample plot', 'sample.jpg')

附注:cmap='jet' 也可以直接得到所需的外观效果。


刚看到你的编辑。嗯,我的定制颜色地图非常接近你所需要的,只是我用白色来着色零密度区域。 我认为你可以将颜色映射调整到类似这样:colors = [(0, 0, 1), (0, 1, 1), (0, 1, 0.75), (0, 1, 0), (0.75, 1, 0), (1, 1, 0), (1, 0.8, 0), (1, 0.7, 0), (1, 0.0, 0)]。只需随意尝试即可 :) - Dmitry Shurov
最后,我编辑了我的答案,以帮助您使用高斯模糊获得“blobby”效果,就像样本图像中一样。 - Dmitry Shurov
好的,谢谢。很不幸,网络又断了,所以我稍后会检查一下 :) - Peter
1
另一种选择是使用OpenCV的cv2.applyColorMap()函数。 - Jeru Luke
1
顺便说一下,我刚意识到 cmap='jet' 也可以直接得到所需的外观。 - Dmitry Shurov
显示剩余3条评论

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