使用 Python OpenCV 缩小和放大轮廓图像
shrink and enlarge contour image with Python OpenCV
我有一张图片,其中包含如下对象:
我可以检测轮廓并得到一个只有球区域的蒙版,但我的 ROI 是边缘区域,这意味着我需要一个更大和一个更小的蒙版,它们结合起来得到这个:
所以我的问题是:如何 shrink/enlarge 围绕轮廓中心的轮廓蒙版?
这是 Python/OpenCV 中的一种方法。
- Read the input
- Convert to grayscale
- Threshold
- Use morphology close and open to clean up noise and small regions to form a mask
- Dilate the mask
- Erode the mask
- Merge the input and dilated mask
- Merge the eroded mask with the previous result
- Save the result
输入:
import cv2
import numpy as np
# read image
img = cv2.imread("basketball.png")
# convert img to grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# make anything not white into black
mask = gray.copy()
mask[mask!=255] = 0
# invert mask so center is white and outside is black
mask = 255 - mask
# close open mask to clean up small regions and make 3 channels
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5,5))
mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)
mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel)
mask = cv2.cvtColor(mask, cv2.COLOR_GRAY2BGR)
# erode mask
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (51,51))
erode = cv2.morphologyEx(mask, cv2.MORPH_ERODE, kernel)
# dilate mask and make 3 channels
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (51,51))
dilate = cv2.morphologyEx(mask, cv2.MORPH_DILATE, kernel)
# merge image onto dilated mask using mask
result = np.where(mask==(255,255,255), img, dilate)
# merge inverted erode onto result using erode
result = np.where(erode==(255,255,255), (255-erode), result)
# write result to disk
cv2.imwrite("basketball_mask.png", mask)
cv2.imwrite("basketball_eroded_mask.png", erode)
cv2.imwrite("basketball_dilate_mask.png", dilate)
cv2.imwrite("basketball_dilate_mask.png", dilate)
cv2.imwrite("basketball_result.png", result)
# display it
cv2.imshow("image", img)
cv2.imshow("mask", mask)
cv2.imshow("erode", erode)
cv2.imshow("dilate", dilate)
cv2.imshow("result", result)
cv2.waitKey(0)
面具:
侵蚀遮罩:
扩张掩码:
结果:
注意:如果膨胀太多,会到达图像的边缘,然后形状会发生变化。为避免这种情况,请使用足以包含扩大尺寸的背景颜色填充输入。
我有一张图片,其中包含如下对象:
我可以检测轮廓并得到一个只有球区域的蒙版,但我的 ROI 是边缘区域,这意味着我需要一个更大和一个更小的蒙版,它们结合起来得到这个:
所以我的问题是:如何 shrink/enlarge 围绕轮廓中心的轮廓蒙版?
这是 Python/OpenCV 中的一种方法。
- Read the input
- Convert to grayscale
- Threshold
- Use morphology close and open to clean up noise and small regions to form a mask
- Dilate the mask
- Erode the mask
- Merge the input and dilated mask
- Merge the eroded mask with the previous result
- Save the result
输入:
import cv2
import numpy as np
# read image
img = cv2.imread("basketball.png")
# convert img to grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# make anything not white into black
mask = gray.copy()
mask[mask!=255] = 0
# invert mask so center is white and outside is black
mask = 255 - mask
# close open mask to clean up small regions and make 3 channels
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5,5))
mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)
mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel)
mask = cv2.cvtColor(mask, cv2.COLOR_GRAY2BGR)
# erode mask
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (51,51))
erode = cv2.morphologyEx(mask, cv2.MORPH_ERODE, kernel)
# dilate mask and make 3 channels
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (51,51))
dilate = cv2.morphologyEx(mask, cv2.MORPH_DILATE, kernel)
# merge image onto dilated mask using mask
result = np.where(mask==(255,255,255), img, dilate)
# merge inverted erode onto result using erode
result = np.where(erode==(255,255,255), (255-erode), result)
# write result to disk
cv2.imwrite("basketball_mask.png", mask)
cv2.imwrite("basketball_eroded_mask.png", erode)
cv2.imwrite("basketball_dilate_mask.png", dilate)
cv2.imwrite("basketball_dilate_mask.png", dilate)
cv2.imwrite("basketball_result.png", result)
# display it
cv2.imshow("image", img)
cv2.imshow("mask", mask)
cv2.imshow("erode", erode)
cv2.imshow("dilate", dilate)
cv2.imshow("result", result)
cv2.waitKey(0)
面具:
侵蚀遮罩:
扩张掩码:
结果:
注意:如果膨胀太多,会到达图像的边缘,然后形状会发生变化。为避免这种情况,请使用足以包含扩大尺寸的背景颜色填充输入。