Расширяя пороговое изображение, я смог вынуть немного больший фрагмент изображения и удалить весь белый, но в некоторых невинных областях был удален край в 1 пиксель.
Вот результат:
![enter image description here](https://i.stack.imgur.com/LQ1F4.png)
А вот код, основанный на этом ответе :
import cv2
import numpy as np
# Create binary threshold
img = cv2.imread('shirt.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
_, gray = cv2.threshold(gray, 220, 255, cv2.THRESH_BINARY)
# Dilate the image to join small pieces to the larger white sections
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
gray = cv2.dilate(gray, kernel)
# Create the mask by filling in all the contours of the dilated edges
mask = np.zeros(gray.shape, np.uint8)
_, contours, _ = cv2.findContours(gray, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
for cnt in contours:
if 10 < cv2.contourArea(cnt) < 5000:
# cv2.drawContours(img, [cnt], 0, (0, 255, 0), 2)
cv2.drawContours(mask, [cnt], 0, 255, -1)
# Erode the edges back to their orig. size
# Leaving this out creates a more greedy bite of the edges, removing the single strands
# mask = cv2.erode(mask, kernel)
cv2.imwrite('im.png', img)
cv2.imwrite('ma.png', mask)
mask = cv2.cvtColor(255 - mask, cv2.COLOR_GRAY2BGR)
img = img & mask
cv2.imwrite('fi.png', img)
Этот ответ имеет преимущество в части контуровпозволяя вам сохранять белые области меньших размеров, если вы возитесь с магическим числом 10 (я предполагаю, что это может быть не единственное изображение, над которым вы хотите запустить этот код.) Если это не нужно, тогда код может бытьнамного проще, просто 1) взяв исходный порог, 2) расширив его 3) замаскировав его на исходном изображении.