Python 将低于CV2颜色贴图特定阈值的值设置为透明

Python 将低于CV2颜色贴图特定阈值的值设置为透明,python,numpy,opencv,cv2,colormap,Python,Numpy,Opencv,Cv2,Colormap,我目前正在尝试对照片应用激活热图 目前,我有原始照片,还有一个概率面具。我将概率乘以255,然后四舍五入到最接近的整数。然后,我使用cv2.applyColorMap和COLORMAP.JET将COLORMAP应用于不透明度为25%的图像 img_cv2 = cv2.cvtColor(np_img, cv2.COLOR_RGB2BGR) heatmapshow = np.uint8(np.floor(mask * 255)) colormap = cv2.COLORMAP_JET heat

我目前正在尝试对照片应用激活热图

目前,我有原始照片,还有一个概率面具。我将概率乘以255,然后四舍五入到最接近的整数。然后,我使用cv2.applyColorMap和COLORMAP.JET将COLORMAP应用于不透明度为25%的图像

img_cv2 = cv2.cvtColor(np_img, cv2.COLOR_RGB2BGR)

heatmapshow = np.uint8(np.floor(mask * 255))

colormap = cv2.COLORMAP_JET

heatmapshow = cv2.applyColorMap(np.uint8(heatmapshow - 255), colormap)

heatmap_opacity = 0.25
image_opacity = 1.0 - heatmap_opacity

heatmap_arr = cv2.addWeighted(heatmapshow, heatmap_opacity, img_cv2, image_opacity, 0)

此当前代码成功生成热图。然而,我希望能够做出两个改变

  • 对于高于某个阈值的所有值,将不透明度保持在25%(可能>0,但我更希望更灵活),但当遮罩低于该阈值时,将这些单元格的不透明度降低到0%。换句话说,如果激活很少,我希望保留原始图像的颜色

  • 如果可能的话,我也希望能够指定一个自定义的颜色映射,因为本地的颜色映射非常有限,尽管如果我可以做自定义的不透明度的事情,我可能不需要这个

  • 我在Stackoverflow上读到,您可能会欺骗cv2,使其不使用NaN值覆盖任何颜色,但也读到这只适用于浮点而不适用于整型,这会使事情变得复杂,因为我使用的是整型8。我还担心这个功能将来可能会改变,因为我不认为这是故意设计的,是故意内置在cv2中的


    有人有实现这些目标的好方法吗?谢谢

    关于你的第二个问题:

    下面是如何在Python/OpenCV中创建一个简单的自定义双色渐变颜色贴图

    输入:


    应用于图像的颜色映射结果:




    关于你的第一个问题:


    使用恒定的“不透明度”值将热图图像与原始图像混合。可以使用图像替换单个不透明度值。您只需手动执行addWeighted作为热图*不透明度\ img+原始*(1-不透明度\ img),其中您的不透明度图像在0到1范围内浮动。然后剪辑并转换回uint8。如果你的不透明度图像是二进制的,那么你可以使用cv2.bitWiseAnd()来代替乘法。

    这本身不是答案,但是你可以在你的
    热图显示中添加一个alpha通道,并对所有值高于25%(或你想要的任何阈值)的像素将其设置为1,对所有其他像素预先设置为0,然后以与现在相同的方式使用
    cv2.addWeighted
    。请告知您是否需要有关如何使用Numpy执行此操作的更多详细信息。您可以将不透明颜色贴图应用于图像。然后创建一个灰度图像,将不透明度表示为灰度值,并将阈值设置为0,其中不需要任何透明度。然后将该图像放入彩色贴图图像的alpha通道。@TheHalf Blood Prince这似乎合理,最好的方法是什么?@fmw42听起来很有希望,但将不透明彩色贴图应用于图像会首先导致信息丢失吗?比如如果它是100%不透明的红色,那么我相信我最终会得到一个没有原始颜色信息的透明红色。除非我弄错了,否则我需要在将颜色贴图应用到原始图像之前修改它?也许我误解了。100%不透明度是完全不透明的。所以红色是完全的红色,没有透明度。使用恒定的“不透明度”值将热图图像与原始图像混合。可以使用图像替换单个不透明度值。您只需手动执行addWeighted作为热图*不透明度\ img+原始*(1-不透明度\ img),其中您的不透明度图像在0到1范围内浮动。然后剪辑并转换回uint8。如果不透明度图像是二进制的,那么可以使用cv2.bitWiseAnd()代替乘法。你能发布你的输入图像和掩码吗?
    import cv2
    import numpy as np
    
    # load image as grayscale
    img = cv2.imread('lena_gray.png', cv2.IMREAD_GRAYSCALE)
    
    # convert to 3 equal channels
    img = cv2.merge((img, img, img))
    
    # create 1 pixel red image
    red = np.full((1, 1, 3), (0,0,255), np.uint8)
    
    # create 1 pixel blue image
    blue = np.full((1, 1, 3), (255,0,0), np.uint8)
    
    # append the two images
    lut = np.concatenate((red, blue), axis=0)
    
    # resize lut to 256 values
    lut = cv2.resize(lut, (1,256), interpolation=cv2.INTER_LINEAR)
    
    # apply lut
    result = cv2.LUT(img, lut)
    
    # save result
    cv2.imwrite('lena_red_blue_lut_mapped.png', result)
    
    # display result
    cv2.imshow('RESULT', result)
    cv2.waitKey(0)
    cv2.destroyAllWindows()