How to convert grayscale png with transparency to heatmap? - python

The heatmap package isn't supported by Python 3, and cv2 doesn't support the following for PNG images with an alpha channel:
cv2.applyColorMap(img, cv2.COLORMAP_JET)
I want to convert a grayscale PNG image into a heatmap; in other words, colorize the darker pixels as blue and the brighter pixels as red.
Every pixel's transparency should remain unaffected.

Try using matplotlib.pyplot.get_cmap.
colormap = plt.get_cmap('plasma')
heatmap = (colormap(image) * 2**16).astype(np.uint16)[:,:,:3]
heatmap = cv2.cvtColor(heatmap, cv2.COLOR_RGB2BGR)
You can choose the color maps according to your desired output.

Related

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:
To overlay a heatmap you can use cv2.addWeighted()
PART I
Based on similar input images
Sample input image:
cv2.imshow('Input image', g1)
g1 is a BGR image:
g1.shape
(158, 99, 3)
Sample mask:
cv2.imshow('Mask image', gm)
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)
Overlaying the heatmap over the original image g1 using cv2.addWeighted():
overlay_img = cv2.addWeighted(heatmap_img, 0.5, g1, 0.5, 0)
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)
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,...]
I hope the above is what you are looking for.

Create a grayscale image from a color coded source image in Python

I want to convert a color-coded image to grayscale. The colors in that image correspond to given values (e.g. black is 0 and red is 25) like on this color scale.
Is there a way to convert this image to grayscale and keep that color gradient, so that 0 on the scale remains black and 25 is shown as white?
I tried to convert it with matplotlib and also cv2 but ended up with grayscale images, that did not respect my given color gradient. I would appreciate an answer very much. Thank you!
Depending on the tools you use you can
read/convert the color-coded image as RGB,
convert RGB to grayscale
or
convert the colors in the gradient to grayscale,
read/convert the color-coded image using that grayscale palette.
The second approach is more efficient.
Update:
Upon reading your last comment (which should be in the original question), the options become
read/convert the color-coded image as RGB,
convert RGB to grayscale,
rescale by multiplying the pixel values by 10
or
convert the colors in the gradient to grayscale, rescaled to 0-255,
read/convert the color-coded image using that grayscale palette.

Adding colour overlay to greyscale image

I'm wanting to add pre-generated heatmaps over photographs. The colours in the images aren't important and to make the heatmap colours stand out I'm making the images greyscale. I've done this using
grey = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
However the greyscale image now has one fewer dimensions compared to the heatmap (which is BRG). How can I overlay the heatmap on top of the grey image?
With the two identical size and mode images in place, execute the following code.
from PIL import Images
im_1 = Image.open("/constr/pics1/100_canary.png")
# mode is RGBA
im_2 = Image.open("/constr/pics1/100_cockcrow.png")
# Check on mode, size and format first for compatibility.
# Make both modes the same
im_4 = Image.blend(im_1, im_2, 0.5)
im_4.show()

How to show the overlay of an object on an image with only borders in python?

I saw a very nice representation of overlaying results on image in a paper and trying to do a similar approach on my data. Here ground truth is the object overlayed with red borderlines and segmentation result is with green color.
I have 3 images: MRI, ground truth (gt) and results obtained from an algorithm (res). How should I write the code for this similar representation in python? Or if there is any free code available to use, please share here.
Thanks
If the ground-truth and res are 2D masks, you can create a RGB image from your grayscale image and change the color of pixels where res indicates to. Here is an example of highlighting edges extracted using Canny edge detector on a sample image:
import cv2
from matplotlib import pyplot as plt
img = cv2.imread('brain.png',0)
edges = cv2.Canny(img,50,200) # canny edge detector
img = cv2.merge((img,img,img)) # creat RGB image from grayscale
img2 = img.copy()
img2[edges == 255] = [255, 0, 0] # turn edges to red
plt.subplot(121),plt.imshow(img)
plt.title('Original Image'), plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(img2)
plt.title('Edge Highlighted'), plt.xticks([]), plt.yticks([])
plt.show()
Assuming the ground truth is a binary segmentation mask,
this skimage find contour should work. Multiple contours may be found and you can choose to only plot one of them. Set different values for parameter 'level' to extract contours from multiclass segmentation mask.

Correct way for converting RGB heatmap image to Grayscale heatmap

I am trying to convert a RGB heatmap image to grayscale heatmap image. First I thought It was a simple rgb to grayscale conversion. But it isn't.
For example, blue color may represent soft things and red color may represent hard things.
Using commonly used simple rgb to grayscale conversion method, I found red and blue color has converted to save gray color although they had very different nature of representation.
But What I want something like this where blue is deep gray, and red is bright gray.
I had searched a lot. Unfortunately I did't find (or maybe I couldn't understand). After reading some article on rgb color model, I have found a way to generate grayscale image. My code is
import colorsys
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
img = mpimg.imread('input_image/abnormal_hi_res.png')
img = img[ : , : , 0:3] # keep only r, g, b channels
new_image = np.zeros((img.shape[0], img.shape[1]))
for y_pos in range(img.shape[0]):
for x_pos in range (img.shape[1]):
color = img[y_pos, x_pos]
r,g,b = color
h, _, _ = colorsys.rgb_to_hls(r, g, b)
new_image[y_pos, x_pos] = 1.0 - h
plt.imshow(new_image, cmap='gray')
plt.show()
But I believe there should exists a good method backed by proven mathematics.
Please help me to find out the correct one for this problem.
You can follow these links. They have got some good notes on heatmaps and grayscale
https://docs.opencv.org/3.1.0/de/d25/imgproc_color_conversions.html
https://matplotlib.org/users/colormaps.html
*UPDATE
First, you need to convert your BGR image to LUV then convert it to a grayscale image. Use opencv.
Code for converting BGR to LUV in opencv.
gray = cv2.cvtColor(img, cv2.COLOR_BGR2LUV)
I think it what you are looking for

Categories