Python 在具有透明度的三维图像上叠加二维热图

Python 在具有透明度的三维图像上叠加二维热图,python,overlay,heatmap,superimpose,Python,Overlay,Heatmap,Superimpose,我有一个3D python图像和它的2D特征向量。我用imshow()显示了每个,如下面的代码所示,我可以清楚地看到它。我现在想要的是将2D特征向量作为热图覆盖在3D图像的顶部。我尝试添加它们,但尺寸问题被提出,我通过添加三维扩展了二维特征向量,但叠加的图像被弄乱了。尺寸如下所示:- 功能>>(32,96), 图像>>(32,96,3) “范围”是指使所有范围以相同的大小显示,并且其大小已定义。 下面是我通过上述代码进行的尝试 我正在寻找的显示器如下所示 下面是实现这一点的pesudo代码(

我有一个3D python图像和它的2D特征向量。我用imshow()显示了每个,如下面的代码所示,我可以清楚地看到它。我现在想要的是将2D特征向量作为热图覆盖在3D图像的顶部。我尝试添加它们,但尺寸问题被提出,我通过添加三维扩展了二维特征向量,但叠加的图像被弄乱了。尺寸如下所示:- 功能>>(32,96), 图像>>(32,96,3)

“范围”是指使所有范围以相同的大小显示,并且其大小已定义。 下面是我通过上述代码进行的尝试

我正在寻找的显示器如下所示

下面是实现这一点的pesudo代码(我正在尝试生成最少的代码来共享,但这需要时间-因此我将分享此代码,以防它有助于解决问题:-

def save_feature_to_img_2(self):

    feature = (
        get_feature()
    )  #  get feature of size -- > torch.Size([1, 256, 32,96])

    feature2 = features[
        :, 0, :, :
    ]  #  I pick one from the 256 feature maps - [1,1,32,96]

    feature2 = (
        feature2.data.numpy()
    )  # convert it to numpy array for later fusion with image array - [1,1,32,96]

    features2 = features2.view(
        features2.shape[1], features2.shape[2]
    )  # reshape into 2D feature map  [32,96]

    img_raw1 = Image.open(self.img_path)  # read raw image size [128,64,3]

    img_raw_np = np.array(img_raw1)  # imge to numpy array

    newsize = (h, w)  # shape to re-size image to same size a feature
    img_raw_resize = img_raw1.resize(newsize)
    img_raw_np_resize = np.array(img_raw_resize)  # size is now [32,96,3]

    # use sigmod to  normalize feature to  [0,1]
    feature2 = 1.0 / (1 + np.exp(-1 * feature2))

    # display setup
    dx, dy = 0.05, 0.05

    y = np.arange(-8, 8, dx)  # Y - axis range
    x = np.arange(-4.0, 4.0, dy)  # X -axis range
    X, Y = np.meshgrid(x, y)  # meshgrid to enclose my display into
    extent = (
        np.min(x),
        np.max(x),
        np.min(y),
        np.max(y),
    )  # extent - the X and Y range  - just to make unifrom display

    feature2 = (255.5 * feature2 / np.amax(feature2)).astype(
        np.uint8
    )  # put feature into [0-255] range for colour image

    # to display img, feature and img_feature
    fig = plt.figure()
    ax0 = fig.add_subplot(131, title="Image")
    ax1 = fig.add_subplot(132, title="Heatmap")
    ax2 = fig.add_subplot(133, title="overlayed")

    # hereunder I used this code share in the answer to fuse
    alpha = 0.5

    img_heatmap = (
        feature2[:, :, None].astype(np.float64) * alpha
        + img_raw_np_resize * (1 - alpha)
    ).astype(np.uint8)

    ax0.imshow(img_raw1, alpha=1.0, interpolation="gaussian", cmap=plt.cm.jet)
    ax1.imshow(feature2, alpha=1.0, interpolation="gaussian", cmap=plt.cm.jet)
    ax2.imshow(
        img_heatmap, alpha=0.7, interpolation="gaussian", cmap=plt.cm.jet
    )

    cv2.imwrite("./img_heatmap.jpg", img_heatmap)
这是我得到的新显示器

我使用以下内容来融合图像和功能

alpha = 0.5         
img_feature = ((plt.cm.jet(feature2)[:, :, :3] * 255) * alpha + (1-alpha)*img_raw_np_resize).astype(np.uint8)  and displaying it with ax2.imshow(img_feature,alpha = 0.7, interpolation = 'gaussian', cmap = plt.cm.jet)

变体1

如果你想只显示图像的加热区域,你必须乘以热图,而不是相加

您的公式将是
img\u feature=(img*(feature[:,:,None.).astype(np.float64)/np.amax(feature)).astype(np.uint8)

完整示例代码(带有我自己的图像和自动生成的示例热图):

输出:


变体2

如果您只想使加热的区域变亮(变白)和未加热的区域变暗(变黑),只需按照以下公式进行alpha混合:
alpha=0.5;img_feature=(feature[:,:,None.).astype(np.float64)*alpha+img*(1-alpha)).astype(np.uint8)

输出:


变体3

与Variant-2(使用alpha混合)相同,但使用基于
matplotlib.pyplot.cm.jet
着色方案的RGB特征数组代替黑白特征数组

从代码中可以看出,您可以在表达式
plt.cm.jet(功能)
中使用,而不是
plt.cm.jet
颜色

输出:


PS。我刚刚注意到Matplotlib在绘制热图时进行了规格化
(feature-min)/(max-min)
,因此我决定在叠加公式时做同样的事情,最终公式如下:

alpha = 0.5; img_feature = ((
    plt.cm.jet(
        (feature - np.amin(feature)).astype(np.float32)
        / (np.amax(feature) - np.amin(feature)).astype(np.float32)
    )[:, :, :3] * 255
) * alpha + img * (1 - alpha)).astype(np.uint8)
使用上述公式(或和)的示例代码。使用上述公式(和)的结果图像。最终覆盖图像:


你想实现什么?如果你只想显示加热的部分,那么你必须乘法,而不是添加热图。执行
img\u功能=(img*(功能[:,:,无])。astype(np.float64)/np.amax(功能)).astype(np.uint8)
谢谢您的回答。我正在尝试将该功能覆盖在图像上。但是,由于该功能是从图像中提取的,因此我希望将其覆盖在原始图像上,并显示在特征提取过程中图像的哪个部分聚焦。我希望在图像上覆盖该功能,而不更改原始图像,但具有控制权我尝试了你的技巧,但没有得到效果。取而代之的是,它改变了原始图像和功能,融合后甚至变得混乱。根据你对问题的更新,你提供的正确覆盖图像示例,我更新了使用变体3(在答案末尾)编辑,该变体3的图片外观与您提供的渲染图片的外观相同。在我的变体3叠加后看不到您的图像的原因是,我希望在我的代码中,图像的值在0-255范围内(作为常规RGB图像),可能您已经规范化为0-1之间的浮点,因此在我的公式中,您必须使用
img*255*(1-alpha)而不是子表达式
在你的情况下。请尝试告诉我。无论如何,我们迟早会找到正确的解决方案,请耐心等待!@user3315422如果不是秘密的话,也许你可以分享你的全部代码,这样我们就可以调试问题了。拥有你的图像也很好。也不是真的需要全部代码,而是只需要将热图覆盖在图像和s上的代码它们是怎样的。@user3315422顺便说一句,你可以通过网站共享你的代码,复制粘贴你的代码,然后单击“共享”。图像可以通过网站共享。@user3315422你能告诉我你想实现什么吗?你希望加热区域如何显示/覆盖在原始图像上?你希望图像的这一部分更清晰还是如何?谢谢关于详细的答案,顺便说一句,祝你新年快乐。我希望功能是半透明的,同时能够看到它的图案,同时能够注意到它所关注的图像的哪个部分。我尝试了你的代码段,正如我在上面的评论中提到的,图像和功能都会改变它们的外观t在结果合并中display@user3315422你能分享你的代码,混合热图和图像,并显示它们吗?可能它包含一些错误,因为它绘制了损坏的图像。因为正如你在我的回答/帖子上面看到的,所有重叠的图像看起来都不错。
import requests, PIL.Image, io, numpy as np, matplotlib.pyplot as plt
# load some image
img = np.array(PIL.Image.open(io.BytesIO(requests.get('https://i.stack.imgur.com/vPlCG.jpg').content)))
# load or compute some features
h, w, _ = img.shape
mg = np.mgrid[:h, :w]
feature = mg[0].astype(np.float64) * mg[1].astype(np.float64)
feature = (255.5 * feature / np.amax(feature)).astype(np.uint8)
# compute heated image
img_feature = (img * (feature[:, :, None].astype(np.float64) / np.amax(feature))).astype(np.uint8)
# show images
fig, (ax0, ax1, ax2) = plt.subplots(1, 3)
ax0.imshow(img)
ax1.imshow(feature, alpha = 1., interpolation = 'gaussian', cmap = plt.cm.jet)
ax2.imshow(img_feature, alpha = 1., interpolation = 'gaussian', cmap = plt.cm.jet)
plt.show()
import requests, PIL.Image, io, numpy as np, matplotlib.pyplot as plt
# load some image
img = np.array(PIL.Image.open(io.BytesIO(requests.get('https://i.stack.imgur.com/vPlCG.jpg').content)))
# load or compute some features
h, w, _ = img.shape
mg = np.mgrid[:h, :w]
feature = mg[0].astype(np.float64) * mg[1].astype(np.float64)
feature = (255.5 * feature / np.amax(feature)).astype(np.uint8)
# compute heated image
alpha = 0.5; img_feature = (feature[:, :, None].astype(np.float64) * alpha + img * (1 - alpha)).astype(np.uint8)
# show images
fig, (ax0, ax1, ax2) = plt.subplots(1, 3)
ax0.imshow(img)
ax1.imshow(feature, alpha = 1., interpolation = 'gaussian', cmap = plt.cm.jet)
ax2.imshow(img_feature, alpha = 1., interpolation = 'gaussian', cmap = plt.cm.jet)
plt.show()
import requests, PIL.Image, io, numpy as np, matplotlib.pyplot as plt
# load some image
img = np.array(PIL.Image.open(io.BytesIO(requests.get('https://i.stack.imgur.com/vPlCG.jpg').content)))
# load or compute some features
h, w, _ = img.shape
mg = np.mgrid[:h, :w]
feature = mg[0].astype(np.float64) * mg[1].astype(np.float64)
feature = (255.5 * feature / np.amax(feature)).astype(np.uint8)
# compute heated image
alpha = 0.5; img_feature = ((plt.cm.jet(feature)[:, :, :3] * 255) * alpha + img * (1 - alpha)).astype(np.uint8)
# show images
fig, axs = plt.subplots(2, 2)
axs[0, 0].imshow(img)
axs[0, 1].imshow(feature, alpha = 1., interpolation = 'gaussian', cmap = plt.cm.jet)
axs[1, 0].imshow(img_feature, alpha = 1., interpolation = 'gaussian', cmap = plt.cm.jet)
axs[1, 1].remove()
plt.show()
alpha = 0.5; img_feature = ((
    plt.cm.jet(
        (feature - np.amin(feature)).astype(np.float32)
        / (np.amax(feature) - np.amin(feature)).astype(np.float32)
    )[:, :, :3] * 255
) * alpha + img * (1 - alpha)).astype(np.uint8)