2

I have two images: A grayscale image, and a binary mask with the same dimensions. How do I color the image on the mask, while the rest of the image remains grayscale?

Here's and example:

enter image description here

  • 3
    Convert your `gray` image to 3-channel color image. Now for every white (255) pixel in the mask, assign the color (255, 255, 0): `gray[mask==255]=(255, 255, 0)` – Jeru Luke May 06 '22 at 18:49
  • How do I convert my gray image to a 3-channel color image? I'm using pydicom.dcmread.pixel_array, which reads the image as a 2D numpy array – Frederik Faarup May 06 '22 at 18:52
  • `gray = cv2.merge((gray, gray, gray))` express the pixel intensities of original gray image across three channels – Jeru Luke May 06 '22 at 18:56
  • Another way is `gray = cv2.cvtColor(grey, cv2.COLOR_GRAY2RGB)`. Note that it doesn't matter which method you use when you're converting from gray to RGB but it does matter when converting RGB to gray. [link to doc](https://docs.opencv.org/3.4/de/d25/imgproc_color_conversions.html#color_convert_rgb_gray) – pu239 Feb 03 '23 at 16:14

1 Answers1

1

Expressing your grey image pixel values across 3-channels gives you a color image. The result would look the same but when you check the dimensions it would be 3.

gray_3_channel = cv2.merge((gray, gray, gray))

gray.shape
>>> (158, 99)
gray_3_channel.shape
>>> (158, 99, 3)

For every white (255) pixel in the mask, assign the color (255, 255, 0) in gray_3_channel:

gray_3_channel[mask==255]=(255, 255, 0)

enter image description here

Jeru Luke
  • 20,118
  • 13
  • 80
  • 87
  • Cheers. Would I have to normalise the pixels of the gray image before? As they go up to 65535 atm. Also, which function would you use to show the image? As it's a mix of grayscale and color, so plt.imshow(img_array, cmap="gray") is probably not valid – Frederik Faarup May 06 '22 at 19:14
  • @FrederikFaarup To show a color image avoid `cmap` just use `plt.imshow(img_array)` – Jeru Luke May 06 '22 at 19:20
  • 1
    Also if you want to restrict the pixel values to unsigned 8-bit integer (0 - 255) you can normalize – Jeru Luke May 06 '22 at 19:20
  • Cheers. As an addition, how do I make the overlay transparent, for example 0.5 opacity? I have another heatmap (np array of probabilities), which I want to overlay an image – Frederik Faarup May 07 '22 at 18:42
  • 1
    @FrederikFaarup You can search for `cv2.addWeighted()` function – Jeru Luke May 07 '22 at 18:45
  • 1
    Ah nice! I couldn't get it to work, so I create the overlay (like you've showed), and then cv2.addWeighted() the original image with the image with overlay. It works :-)) – Frederik Faarup May 07 '22 at 19:27