如何填充等高线图掩码并保留等高线内的数据并涂黑其余部分
How to fill a contour plot mask and retain data inside the contour and blackout the rest
我有这样一张图片,
通过使用以下代码,
import numpy as np
import cv2
# load the image
image = cv2.imread("frame50.jpg", 1)
#color boundaries [B, G, R]
lower = [0, 3, 30]
upper = [30, 117, 253]
# create NumPy arrays from the boundaries
lower = np.array(lower, dtype="uint8")
upper = np.array(upper, dtype="uint8")
# find the colors within the specified boundaries and apply
# the mask
mask = cv2.inRange(image, lower, upper)
output = cv2.bitwise_and(image, image, mask=mask)
ret,thresh = cv2.threshold(mask, 50, 255, 0)
if (int(cv2.__version__[0]) > 3):
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
else:
im2, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
if len(contours) != 0:
# find the biggest countour (c) by the area
c = max(contours, key = cv2.contourArea)
x,y,w,h = cv2.boundingRect(c)
ROI = image[y:y+h, x:x+w]
cv2.imshow('ROI',ROI)
cv2.imwrite('ROI.png',ROI)
cv2.waitKey(0)
我得到以下裁剪图像,
我想保留橙色手绘边界内的所有数据,包括边界本身,并将其余部分涂黑。
在上图中,橙色边界外的数据仍然存在。我不要那个。我现在如何填充像这样的掩码,以便我可以保留橙色边界内的数据,
我仍然想保留其他属性,例如矩形边界框。我不想改变任何其他事情。我该怎么做?
谢谢
这是 Python/OpenCV 中的一种方法。
- 读取输入
- 橙色的门槛
- 找到(最大的)轮廓并得到它的边界框
- 在黑色背景上绘制白色填充轮廓作为遮罩
- 使用 alpha 通道创建输入副本
- 将蒙版复制到 alpha 通道中
- 裁剪 ROI
- 保存结果
输入:
import numpy as np
import cv2
# load the image
image = cv2.imread("frame50.jpg")
#color boundaries [B, G, R]
lower = (0, 70, 210)
upper = (50, 130, 255)
# threshold on orange color
thresh = cv2.inRange(image, lower, upper)
# get largest contour
contours = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]
big_contour = max(contours, key=cv2.contourArea)
x,y,w,h = cv2.boundingRect(big_contour)
# draw filled contour on black background
mask = np.zeros_like(image)
cv2.drawContours(mask, [big_contour], 0, (255,255,255), -1)
# put mask into alpha channel of input
new_image = cv2.cvtColor(image, cv2.COLOR_BGR2BGRA)
new_image[:,:,3] = mask[:,:,0]
# crop
ROI = new_image[y:y+h, x:x+w]
# save result
cv2.imwrite('frame50_thresh.jpg',thresh)
cv2.imwrite('frame50_mask.jpg',mask)
cv2.imwrite('frame50_new_image.jpg',new_image)
cv2.imwrite('frame50_roi.png',ROI)
# show images
cv2.imshow('thresh',thresh)
cv2.imshow('mask',mask)
cv2.imshow('new_image',new_image)
cv2.imshow('ROI',ROI)
cv2.waitKey(0)
阈值图像:
蒙版图片:
在 alpha 通道中带有遮罩的新图像:
裁剪后的投资回报率
如您希望(在您对我之前的回答的评论中)使外部区域为黑色而不是透明,您可以按照 Python/OpenCV 中的以下方式进行操作,并更改几行以乘以通过输入掩码而不是将掩码放入 alpha 通道。
输入:
import numpy as np
import cv2
# load the image
image = cv2.imread("frame50.jpg")
#color boundaries [B, G, R]
lower = (0, 70, 210)
upper = (50, 130, 255)
# threshold on orange color
thresh = cv2.inRange(image, lower, upper)
# get largest contour
contours = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]
big_contour = max(contours, key=cv2.contourArea)
x,y,w,h = cv2.boundingRect(big_contour)
# draw filled contour on black background
mask = np.zeros_like(image)
cv2.drawContours(mask, [big_contour], 0, (255,255,255), -1)
# apply mask to input image
new_image = cv2.bitwise_and(image, mask)
# crop
ROI = new_image[y:y+h, x:x+w]
# save result
cv2.imwrite('frame50_thresh.jpg',thresh)
cv2.imwrite('frame50_mask.jpg',mask)
cv2.imwrite('frame50_new_image2.jpg',new_image)
cv2.imwrite('frame50_roi2.jpg',ROI)
# show images
cv2.imshow('thresh',thresh)
cv2.imshow('mask',mask)
cv2.imshow('new_image',new_image)
cv2.imshow('ROI',ROI)
cv2.waitKey(0)
new_image敷面膜后:
裁剪后的 roi 图像:
我有这样一张图片,
通过使用以下代码,
import numpy as np
import cv2
# load the image
image = cv2.imread("frame50.jpg", 1)
#color boundaries [B, G, R]
lower = [0, 3, 30]
upper = [30, 117, 253]
# create NumPy arrays from the boundaries
lower = np.array(lower, dtype="uint8")
upper = np.array(upper, dtype="uint8")
# find the colors within the specified boundaries and apply
# the mask
mask = cv2.inRange(image, lower, upper)
output = cv2.bitwise_and(image, image, mask=mask)
ret,thresh = cv2.threshold(mask, 50, 255, 0)
if (int(cv2.__version__[0]) > 3):
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
else:
im2, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
if len(contours) != 0:
# find the biggest countour (c) by the area
c = max(contours, key = cv2.contourArea)
x,y,w,h = cv2.boundingRect(c)
ROI = image[y:y+h, x:x+w]
cv2.imshow('ROI',ROI)
cv2.imwrite('ROI.png',ROI)
cv2.waitKey(0)
我得到以下裁剪图像,
我想保留橙色手绘边界内的所有数据,包括边界本身,并将其余部分涂黑。 在上图中,橙色边界外的数据仍然存在。我不要那个。我现在如何填充像这样的掩码,以便我可以保留橙色边界内的数据,
我仍然想保留其他属性,例如矩形边界框。我不想改变任何其他事情。我该怎么做? 谢谢
这是 Python/OpenCV 中的一种方法。
- 读取输入
- 橙色的门槛
- 找到(最大的)轮廓并得到它的边界框
- 在黑色背景上绘制白色填充轮廓作为遮罩
- 使用 alpha 通道创建输入副本
- 将蒙版复制到 alpha 通道中
- 裁剪 ROI
- 保存结果
输入:
import numpy as np
import cv2
# load the image
image = cv2.imread("frame50.jpg")
#color boundaries [B, G, R]
lower = (0, 70, 210)
upper = (50, 130, 255)
# threshold on orange color
thresh = cv2.inRange(image, lower, upper)
# get largest contour
contours = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]
big_contour = max(contours, key=cv2.contourArea)
x,y,w,h = cv2.boundingRect(big_contour)
# draw filled contour on black background
mask = np.zeros_like(image)
cv2.drawContours(mask, [big_contour], 0, (255,255,255), -1)
# put mask into alpha channel of input
new_image = cv2.cvtColor(image, cv2.COLOR_BGR2BGRA)
new_image[:,:,3] = mask[:,:,0]
# crop
ROI = new_image[y:y+h, x:x+w]
# save result
cv2.imwrite('frame50_thresh.jpg',thresh)
cv2.imwrite('frame50_mask.jpg',mask)
cv2.imwrite('frame50_new_image.jpg',new_image)
cv2.imwrite('frame50_roi.png',ROI)
# show images
cv2.imshow('thresh',thresh)
cv2.imshow('mask',mask)
cv2.imshow('new_image',new_image)
cv2.imshow('ROI',ROI)
cv2.waitKey(0)
阈值图像:
蒙版图片:
在 alpha 通道中带有遮罩的新图像:
裁剪后的投资回报率
如您希望(在您对我之前的回答的评论中)使外部区域为黑色而不是透明,您可以按照 Python/OpenCV 中的以下方式进行操作,并更改几行以乘以通过输入掩码而不是将掩码放入 alpha 通道。
输入:
import numpy as np
import cv2
# load the image
image = cv2.imread("frame50.jpg")
#color boundaries [B, G, R]
lower = (0, 70, 210)
upper = (50, 130, 255)
# threshold on orange color
thresh = cv2.inRange(image, lower, upper)
# get largest contour
contours = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]
big_contour = max(contours, key=cv2.contourArea)
x,y,w,h = cv2.boundingRect(big_contour)
# draw filled contour on black background
mask = np.zeros_like(image)
cv2.drawContours(mask, [big_contour], 0, (255,255,255), -1)
# apply mask to input image
new_image = cv2.bitwise_and(image, mask)
# crop
ROI = new_image[y:y+h, x:x+w]
# save result
cv2.imwrite('frame50_thresh.jpg',thresh)
cv2.imwrite('frame50_mask.jpg',mask)
cv2.imwrite('frame50_new_image2.jpg',new_image)
cv2.imwrite('frame50_roi2.jpg',ROI)
# show images
cv2.imshow('thresh',thresh)
cv2.imshow('mask',mask)
cv2.imshow('new_image',new_image)
cv2.imshow('ROI',ROI)
cv2.waitKey(0)
new_image敷面膜后:
裁剪后的 roi 图像: