2

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

Jeru Luke
  • 20,118
  • 13
  • 80
  • 87

1 Answers1

4

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.

Jeru Luke
  • 20,118
  • 13
  • 80
  • 87
  • Cheers, thanks again buddy :-)) Just a follow-up: I have a heatmap (similar to a ROI, except it is probabilities. So floats from 0 to 1, instead of binary). The heatmap has identical probabilities in patches (squares) of the image, so it looks grainy. How can i interpolate the heatmap (numpy array)? – Frederik Faarup May 08 '22 at 19:41
  • @FrederikFaarup You can use `cv2.normalize()` to rescale values between 0 - 1 to 0 - 255. – Jeru Luke May 08 '22 at 19:46
  • They are scaled, the problem is that the classified patches are in squares. I would like to even it more out, so it's more of a continuous heatmap - if that makes sense :-)) The heatmap is generated from an ML model – Frederik Faarup May 08 '22 at 19:49
  • @FrederikFaarup can you please share the array of a sample heatmap generated by the model? – Jeru Luke May 08 '22 at 20:27
  • Or have you tried smoothing the heatmap? – Jeru Luke May 08 '22 at 20:28
  • I wish I could attach an image to comment, but the heatmaps are basically a 2D numpy array where each 256x256 "patch" (square) has the same values (i.e. probabilities of a class). So in the first square, all 256x256 cells have the same same value. In the next square, all the cells have the same values (which could be different than the previous square). Untill it fills up a whole image. Does this make sense? I kind just want to smooth this, so that the probabilities of each square are more smooth – Frederik Faarup May 08 '22 at 20:47
  • You can try smoothing with a sufficiently large kernel size – Jeru Luke May 09 '22 at 07:02