применить тепловую карту к прямоугольнику opencv - PullRequest
0 голосов
/ 26 мая 2020

Я пытаюсь применить тепловую карту к выбранной части [лица людей] моей фотографии. Вот что я сделал до сих пор ... прямоугольник будет применен к лицу. лицо будет обрезано, тепловая карта будет применена к обрезанному изображению.

 # 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)

Мне удалось сохранить кадрированное изображение и прямоугольные грани отдельно, но мне нужно 1. сделать прямоугольник тепловой картой без отдельной обрезки в моем исходном изображении. 2. другая часть изображения должна быть нормальной

EDITED

Нарисуйте прямоугольник вокруг лиц

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)

Если у меня больше, чем одно лицо, как применить цветной фильтр к обоим лицам?

Ответы [ 2 ]

0 голосов
/ 27 мая 2020

Я считаю, что вам нужно будет обрезать изображение, применить цветовую карту к обрезанному изображению, а затем снова вставить обрезанное изображение с цветовым картированием в ваш оригинал. Я не думаю, что есть способ применить цветовую карту непосредственно к части изображения.

Вот как я делаю это в Python / OpenCV.

  • Прочтите ввод как оттенки серого
  • Обрезать изображение там, где вы хотите, чтобы оно отображалось по цвету
  • Загрузить цветовую карту из Matplotlib и преобразовать ее в изображение BGR
  • Применить цветовую карту к обрезанному изображению
  • Преобразуйте входной сигнал в 3-канальный серый и вставьте обрезанное изображение с цветовым картированием обратно в правильное место.
  • Сохраните результаты


Ввод:

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()


Результат:

enter image description here

0 голосов
/ 26 мая 2020

Если я правильно понимаю, вы пытаетесь отобразить часть тепловой карты, которая находится на лице человека. Попробуйте это

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)
...