Search code examples
pythonnumpyopencvimage-processingpydicom

How to overlay a heatmap numpy array in red on a gray image?


I have tried first converting the grayscale image and the 2D-heatmap to RGB images. The heatmap is converted by making all except the red dimension zeros.

Then the image is masked with a threshold, where the heatmap is above 0.01, and a new image is created where the images are combined.

But for some reason, this produces a green color on some parts of the image:

green errors


Solution

  • To overlay a heatmap you can use cv2.addWeighted()

    PART I

    Based on similar input images

    Sample input image:

    cv2.imshow('Input image', g1)
    

    enter image description here

    g1 is a BGR image:

    g1.shape
    (158, 99, 3)
    

    Sample mask:

    cv2.imshow('Mask image', gm)
    

    enter image description here

    gm is a binary image:

    gm.shape
    (158, 99)
    

    Heatmap:

    OpenCV allows you to create a heatmap using cv2.applyColorMap() on the binary image gm. In this example, I have chosen the option cv2.COLORMAP_JET.

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

    enter image description here

    Overlaying the heatmap over the original image g1 using cv2.addWeighted():

    overlay_img = cv2.addWeighted(heatmap_img, 0.5, g1, 0.5, 0)
    

    enter image description here

    PART II

    The above image is not what you are looking for. Based on your question, you would like to overlay only the region of interest i.e, the region in white.

    First, select only the ROI in the overlay image using the mask gm

    roi_img = cv2.bitwise_and(overlay_img, overlay_img, mask = gm)
    

    enter image description here

    Finally, preserve the ROI where the mask is white (255); and in every other position where the mask is black (0) place pixel intensities of the original image g1:

    roi_img[gm[:] == 0,...] = g1[gm[:] == 0,...]
    

    enter image description here

    I hope the above is what you are looking for.