apply heat map to the opencv rectangle

1k Views Asked by At

iam trying to apply a heat map on a selected portion[people's face] of my picture. Here is what i had done so far... the rectangle will be applied to the face . the face will be cropped heat map will be applied to the cropped image.

 # Draw a rectangle around the faces
    for (x, y, w, h) in faces:
        cv2.rectangle(image, (x, y), (x+w, y+h), (0, 255, 0), 2)
        crop_img = image[y:y+h, x:x+w]

 # Cropping Area
            # Color Mapping Area
            images = cv2.imread(crop_img, 0)
            colormap = plt.get_cmap('inferno')
            heatmap = (colormap(images) * 2**16).astype(np.uint16)[:,:,:3]
            heatmap = cv2.cvtColor(heatmap, cv2.COLOR_RGB2BGR)

# Saving Color Map   
            img_names = "heatimage{}.png".format(i)
            cv2.imwrite(img_names, heatmap)
            print("{} written!".format(img_names))
            img = cv2.imread(img_names,0)
            cv2.imshow('heatmap{}'.format(i),heatmap)

i was able to save the cropped image and rectangle pointing faces separately but i need 1. to make the rectangle to be a heat map ,without cropping separately,in my original image. 2. other part of the image has to be normal

EDITED

Draw a rectangle around the faces

for (x, y, w, h) in faces:
    cv2.rectangle(image, (x, y), (x+w, y+h), (0, 255, 0), 2)
    crop_img = image[y:y+h, x:x+w]
    sample = cv2.imread("sample.jpg",cv2.COLOR_BGR2GRAY)
    colormap = cm.get_cmap('inferno', 256)
    cmp = cm.ScalarMappable(cmap='inferno')
    # create 1D float gradient from 0 to 1 with 256 increments 
    # convert to rgba in range 0 to 255 (via bytes=True)
    # remove alpha channel and reshape to 256x1 3 channel from (256, 4)
    # convert rgb to bgr
    cmap = np.linspace(0, 1, 256, endpoint=True)
    cmap = cmp.to_rgba(cmap, bytes=True)
    cmap = cmap[:, 0:-1].reshape((256, 1, 3))
    cmap = cv2.cvtColor(cmap, cv2.COLOR_RGB2BGR)
    # apply color map to crop
    crop_mapped = cv2.applyColorMap(crop_img, cmap)
    # put color mapped crop back into input
    result = sample.copy()
    result = cv2.cvtColor(result, cv2.COLOR_GRAY2BGR)
    result[y:y+h, x:x+w] = crop_mapped
    # save result
    cv2.imwrite('IRimage.jpg', result)
    # show result
    cv2.imshow("result", result)
    i+=1
    cv2.imshow("Faces found", image)

If i have more than one face , how can i apply color filter to both the faces?

2

There are 2 best solutions below

0
soumith On

If I understand correctly, you're trying to display the portion of a heatmap that's on the face of a person.Try this

alpha = 0.5
image[y:y+h, x:x+w] = alpha * image[y:y+h, x:x+w] + (1 - alpha) * heatmap[y:y+h, x:x+w]
cv2.imshow("preview", image)
4
fmw42 On

I believe that you will have to crop the image, apply the colormap to the cropped image, then put the color mapped crop image back into your original. I do not think there is a way to apply a colormap directly to a portion of an image.

Here is how I do the above in Python/OpenCV.

  • Read the input as grayscale
  • Crop the image where you want it to be color mapped
  • Load the colormap from Matplotlib and convert it to a BGR image
  • Apply the colormap to the cropped image
  • Convert the input to 3 channel gray and insert the color mapped cropped image back in the correct location.
  • Save the results


Input:

enter image description here

import cv2
import numpy as np
import matplotlib.cm as cm

# read image and convert to gray
img = cv2.imread('redhat_gray.jpg', cv2.COLOR_BGR2GRAY)

# crop image
crop = img[140:240, 70:170]

# get colormap from matplotlib and normalize
colormap = cm.get_cmap('inferno', 256)
cmp = cm.ScalarMappable(cmap='inferno')

# create 1D float gradient from 0 to 1 with 256 increments 
# convert to rgba in range 0 to 255 (via bytes=True)
# remove alpha channel and reshape to 256x1 3 channel from (256, 4)
# convert rgb to bgr
cmap = np.linspace(0, 1, 256, endpoint=True)
cmap = cmp.to_rgba(cmap, bytes=True)
cmap = cmap[:, 0:-1].reshape((256, 1, 3))
cmap = cv2.cvtColor(cmap, cv2.COLOR_RGB2BGR)
#print(cmap)

# apply color map to crop
crop_mapped = cv2.applyColorMap(crop, cmap)

# put color mapped crop back into input
result = img.copy()
result = cv2.cvtColor(result, cv2.COLOR_GRAY2BGR)
result[140:240, 70:170] = crop_mapped

# save result
cv2.imwrite('redhat_gray_rectangle_inferno.jpg', result)

# show result
cv2.imshow("result", result)
cv2.waitKey(0)
cv2.destroyAllWindows()


Result:

enter image description here