去除分叉轮廓
思路来源于https://blog.csdn.net/weixin_39639550/article/details/111624935
,但是使用不同的方法进行实现,实际测试发现仅对特定轮廓有效,不具有通用性,仅供参考。
示例代码
python
import numpy as np
import cv2
from copy import deepcopy
def get_contour_remove_fork(mask_path):
mask = cv2.imread(mask_path, 0)
# 找到轮廓
contours, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
mask_convex = deepcopy(mask)
# 遍历所有轮廓
for contour in contours:
# 计算轮廓的凸包
hull = cv2.convexHull(contour)
# 可以选择绘制凸包
mask_convex = cv2.drawContours(
mask_convex, [hull], -1,
255, -1
)
mask_convex_remove_raw_contour = deepcopy(mask_convex)
mask_convex_remove_raw_contour[mask == 255] = 0
# 腐蚀
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
mask_convex_remove_raw_contour = cv2.erode(
mask_convex_remove_raw_contour,
kernel, iterations=1
)
# # 获取最大的轮廓
contours, _ = cv2.findContours(
mask_convex_remove_raw_contour,
cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE
)
# print(len(contours))
max_contour = max(contours, key=cv2.contourArea)
# 获取最大轮廓
# 绘制最大的轮廓
mask_convex_remove_raw_contour_max_contour = cv2.drawContours(
np.zeros_like(mask_convex_remove_raw_contour),
[max_contour],
-1,
255,
-1
)
# 膨胀
kernel_size = 20
kernel = cv2.getStructuringElement(
cv2.MORPH_RECT, (kernel_size, kernel_size)
)
mask_convex_remove_raw_contour_dilate = cv2.dilate(
mask_convex_remove_raw_contour_max_contour,
kernel, iterations=1
)
# 与原图取交集
mask_dst = cv2.bitwise_and(mask, mask_convex_remove_raw_contour_dilate)
return mask_dst
if __name__ == '__main__':
mask_path = "./test.png"
mask_remove_fork = get_contour_remove_fork(mask_path)
mask_remove_fork_path = ".test_remove_fork.png"
cv2.imwrite(mask_remove_fork_path, mask_remove_fork)