仅将颜色图应用于未遮罩区域(不包括黑色遮罩)

Apply a colormap only to unmasked region (excluding the black mask)

我对 cv2 和 python 还是很陌生,所以如果这是基本的或重复的,请原谅我。我试过搜索但无济于事。我有一个图像,比如说这个 penguin,我已经使用 cv2.inRange() 函数屏蔽了它。然后我尝试将 Viridis 颜色图应用于图像,但它适用于所有内容,包括蒙版。我希望颜色图 应用于未屏蔽区域以突出值的细微差异。本质上,我希望未屏蔽区域中的最低值映射到 Viridis 的紫色,未屏蔽区域中的最高值映射到 Viridis 的黄色,线性映射之间的值。

这是我的尝试和 resulting image。请注意之前黑色的蒙版区域如何包含在映射中并且现在是紫色的。我什至不确定这是否可能。也许需要自定义颜色图?

import cv2
import numpy as np 

img = cv2.imread('penguin.jpg') #Read in image
img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) #Change to HSV

# define range of white color in HSV
lower_white = np.array([0,0,210])
upper_white = np.array([255,255,255])


mask = cv2.inRange(img, lower_white, upper_white) # Create the mask
bitwise_mask = cv2.bitwise_and(img,img,mask=mask) # Apply mask
masked_core = cv2.cvtColor(bitwise_mask, cv2.COLOR_HSV2BGR) #Change to BGR

#But how do I get it to apply only to unmasked area?
not_desired = cv2.applyColorMap(masked_core, cv2.COLORMAP_VIRIDIS) #Viridis Colormap

#Display and write image
cv2.imwrite('penguin_masked.jpg', not_desired)
cv2.imshow('penguin', not_desired)
cv2.waitKey()

这是 Python/OpenCV 中的一种方法。

  • 阅读图片
  • 转换为 HSV
  • 使用 inRange() 对 HSV 进行阈值制作掩码
  • 将图像转换为灰度
  • 将颜色图应用于灰度图像
  • 将蒙版应用于输入图像
  • 将反转贴图应用到颜色映射图像
  • 将两个蒙版图像相加得到结果
  • 保存结果

输入:

import cv2
import numpy as np 

img = cv2.imread('penguin.jpg') #Read in image
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) #Change to HSV

# define range of white color in HSV
lower_white = np.array([0,0,210])
upper_white = np.array([255,255,255])

mask = cv2.inRange(hsv, lower_white, upper_white) # Create the mask
print(mask.shape, np.amax(mask))

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) #Change img to GRAY

colormap = cv2.applyColorMap(gray, cv2.COLORMAP_VIRIDIS) #Viridis Colormap to gray image

img_masked = cv2.bitwise_and(img, img, mask=mask) # Apply mask to img

colormap_masked = cv2.bitwise_and(colormap, colormap, mask=(255-mask)) # Apply inverse mask to colormapped

result = cv2.add(img_masked, colormap_masked) # Merge original and colormapped using mask

#Display and write image
cv2.imwrite('penguin_mask.jpg', mask)
cv2.imwrite('penguin_colormapped.jpg', colormap)
cv2.imwrite('penguin_result.jpg', result)

cv2.imshow('mask', mask)
cv2.imshow('colormapped', colormap)
cv2.imshow('result', result)
cv2.waitKey()

蒙版图片:

彩色图像:

结果:

注意:如果我误解了你想要映射企鹅颜色,那么只需在 bitwise_and 操作中交换掩码和反掩码即可。

针对您的评论,也许这就是您想要的Python/OpenCV。除了我如何计算要进行颜色映射的灰度图像外,我的答案几乎相同。我将您的低色和高色转换为强度值。然后将彩色图像转换为强度灰度。然后将 [0,0,210] 等效强度拉伸为黑色,将 [255,255,255] 等效强度 (255) 拉伸为白色,所有值在两者之间线性拉伸。

输入:

import cv2
import numpy as np 
from skimage.exposure import rescale_intensity

img = cv2.imread('penguin.jpg') #Read in image
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) #Change to HSV

# define range of white color in HSV
lower_white = np.array([0,0,210])
upper_white = np.array([255,255,255])

mask = cv2.inRange(hsv, lower_white, upper_white) # Create the mask

# Y = 0.299 R + 0.587 G + 0.114 B
# convert [0,0,210] to intensity = 0.299*210 = 63
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) #Change to gray (intensity)
gray = rescale_intensity(gray, in_range=(63,255), out_range=(0,255)).astype(np.uint8) # linearly stretch 63 to black and 255 to white

colormap = cv2.applyColorMap(gray, cv2.COLORMAP_VIRIDIS) #Viridis Colormap to gray image

img_masked = cv2.bitwise_and(img, img, mask=mask) # Apply mask to img

colormap_masked = cv2.bitwise_and(colormap, colormap, mask=(255-mask)) # Apply inverse mask to colormapped

result = cv2.add(img_masked, colormap_masked) # Merge original and colormapped using mask

#Display and write image
cv2.imwrite('penguin_mask.jpg', mask)
cv2.imwrite('penguin_colormapped2.jpg', colormap)
cv2.imwrite('penguin_result.jpg', result)

cv2.imshow('mask', mask)
cv2.imshow('colormapped2', colormap)
cv2.imshow('result', result)
cv2.waitKey()

掩码:

彩色映射图像:

结果: