Мне нужно разделить маску таким образом, чтобы в случае несоответствия внутри маски она была разделена. Например, если я рисую маску кошки, я хочу, чтобы широкая часть (тело) была одной маской, а узкая часть (хвост) — другой.
Сейчас у меня есть сплошная маска, включающая в себя как тело кошки, так и ее хвост. Я хочу разделить это на две отдельные маски. Как я могу добиться этого с помощью Python?
оригинальная маска
желаемая маска
Я рассмотрел использование методов, описанных в этом, в которых основное внимание уделяется разбиению многоугольников и разделению контуров на несколько треугольников. Однако этот подход не соответствует моим потребностям, поскольку я хочу разделить маску по размеру и форме, а не создавать несколько треугольных разделов.
Вы можете использовать Дефекты выпуклости, чтобы определить точки, между которыми нужно «разрезать».
Это делается так здесь например.
import cv2
import matplotlib.pyplot as plt
import numpy as np
def split_mask(mask):
_, thresh = cv2.threshold(mask , 120,255, cv2.THRESH_BINARY)
contours, _ = cv2.findContours(thresh, 2, 1)
for contour in contours:
if cv2.contourArea(contour) > 20:
hull = cv2.convexHull(contour, returnPoints = False)
defects = cv2.convexityDefects(contour, hull)
if defects is None:
continue
# Gather all defect points to filter them.
dd = [e[0][3]/256 for e in defects]
points = []
for i in range(len(dd)):
_,_,f,_ = defects[i,0]
if dd[i] > 1.0 and dd[i]/np.max(dd) > 0.2:
points.append(f)
# If there is defect points, erase the mask closest points.
if len(points) >= 2:
for i, f1 in enumerate(points):
p1 = tuple(contour[f1][0])
nearest = min((tuple(contour[f2][0]) for j, f2 in enumerate(points) if i != j),
key=lambda p2: (p1[0] - p2[0])**2 + (p1[1] - p2[1])**2)
cv2.line(thresh, p1, nearest, 0, 20)
return thresh
if __name__= = "__main__":
mask = cv2.imread("<path-to-your-image>", cv2.IMREAD_GRAYSCALE)
mask_splitted = split_mask(mask)
plt.imshow(mask_splitted)
plt.show()
Это даст следующее на вашем изображении:
Пожалуйста, прочитайте информационные руководства в справочном центре (stackoverflow.com/help ), в частности, «Как создать минимальный воспроизводимый пример и показывать код как текст, а не изображение» ( stackoverflow.com/ помощь/минимально-воспроизводимый-пример).