Если я правильно понимаю, вы хотите удалить фон и извлечь объект. Вместо использования Canny, вот альтернативный подход. Поскольку вы не предоставили исходное изображение, я сделал снимок экрана, чтобы использовать его в качестве входных данных. В общем, существует несколько способов получения бинарного изображения для выделения границ. Они включают в себя регулярное определение порога, определение порога Оцу, адаптивное определение порога и обнаружение края Канни. В этом случае Otsu, вероятно, лучший, так как есть фоновый шум
Сначала мы конвертируем изображение в оттенки серого, затем выполняем пороговое значение Otsu для получения двоичного изображения
Есть нежелательные секции, поэтому для их удаления мы выполняем морфинг, открывающий для разделения суставов
Теперь, когда суставыразделены, мы находим контуры и фильтруем, используя область контура. Мы извлекаем самый большой контур, представляющий желаемый объект, затем рисуем этот контур на маске
Мы почти на месте, но есть недостатки, поэтому мы приближаемся, чтобы заполнить отверстия
Далее мы побитовые - и с исходным изображением
Наконец, чтобы получить желаемый результат, мы окрашиваем во все черноепикселей на маске до белого цвета
Отсюда вы можете использовать Numpy Slicing для извлечения ROI, но я не совсем уверен, что вы пытались сделать. Я оставлю это на ваше усмотрение
import cv2
import numpy as np
image = cv2.imread("1.png")
original = image.copy()
mask = np.zeros(image.shape, dtype=np.uint8)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))
opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=3)
cnts = cv2.findContours(opening, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
cnts = sorted(cnts, key=cv2.contourArea, reverse=True)
for c in cnts:
cv2.drawContours(mask, [c], -1, (255,255,255), -1)
break
close = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel, iterations=4)
close = cv2.cvtColor(close, cv2.COLOR_BGR2GRAY)
result = cv2.bitwise_and(original, original, mask=close)
result[close==0] = (255,255,255)
cv2.imshow('result', result)
cv2.waitKey()