Это небольшое изображение: p
Вот как я подошел к вашей проблеме: сначала я обнаружил края на изображении.Затем я использовал морфологическое закрытие , чтобы соединить линии, которые расположены близко друг к другу.Это очень хорошо работает с внешними краями, контуром формы.Тогда контур этой фигуры может быть обнаружен (cv2.RETR_EXTERNAL возвращает только самый внешний контур).Из-за некоторого шума я добавил порог размера, а оставшийся контур нарисован заполненным на новом изображении.
Я добавил вторую опцию, которая более эффективна, но может не работать для остальной части вашего проекта,потому что он менее гибок для других изображений.Здесь берутся края и делается большое морфологическое закрытие, которое объединяет всю форму.Чтобы удалить шум, выполняется меньшее морфологическое отверстие.Как вы можете видеть ниже, результаты почти идентичны, хотя разница может быть больше для других изображений.
Последнее замечание: если эта маска слишком грубая, вы можете использовать маску, чтобы вырезать соответствующую областьваше изображение и используйте его для создания лучшей маски.
Результат:
Код:
import numpy as np
import cv2
# load image
image = cv2.imread("image.png")
# detect edges in image
edges = cv2.Canny(image,100,100)
#option 1: use contours
# solidify / join edges
kernel = np.ones((10,10),np.uint8)
mask = cv2.morphologyEx(edges, cv2.MORPH_CLOSE, kernel)
# create black image with the size of image
result = np.zeros(image.shape[:2])
# detect contours in the mask (outer edges only)
im, contours, hierarchy = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# draw contour
for cnt in contours:
if cv2.contourArea(cnt) > 100:
# draw filled contour in white on result
cv2.drawContours(result, [cnt], 0, (255), -1)
# draw outline of contour in red on original image
cv2.drawContours(image, [cnt], 0, (0,0,255), 2)
#option 2: morphology only
# solidify / join edges
kernel2 = np.ones((20,20),np.uint8)
mask2 = cv2.morphologyEx(edges, cv2.MORPH_CLOSE, kernel2)
# remove noise
kernel3 = np.ones((5,5),np.uint8)
result2 = cv2.morphologyEx(mask2, cv2.MORPH_OPEN, kernel3)
# show image and results
cv2.imshow("image", image)
cv2.imshow("edges", edges)
cv2.imshow("Result_option1", result)
cv2.imshow("Result_option2", result2)
# release recourses
cv2.waitKey(0)
cv2.destroyAllWindows()