仅将颜色图应用于未遮罩区域(不包括黑色遮罩)
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()
掩码:
彩色映射图像:
结果:
我对 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()
掩码:
彩色映射图像:
结果: