На этом изображении вам необходимо заполнить заливку в нескольких регионах, поскольку весь зеленый фоновый цвет не подключен.
import cv2
import numpy as np
# load image and get dimensions
img = cv2.imread("soccer.jpg")
h, w, c = img.shape
# create zeros mask 2 pixels larger in each dimension
mask = np.zeros([h + 2, w + 2], np.uint8)
# do floodfill
result = img.copy()
cv2.floodFill(result, mask, (0,0), (255,255,255), (3,151,65), (3,151,65), flags=8)
cv2.floodFill(result, mask, (38,313), (255,255,255), (3,151,65), (3,151,65), flags=8)
cv2.floodFill(result, mask, (363,345), (255,255,255), (3,151,65), (3,151,65), flags=8)
cv2.floodFill(result, mask, (619,342), (255,255,255), (3,151,65), (3,151,65), flags=8)
# write result to disk
cv2.imwrite("soccer_floodfill.jpg", result)
# display it
cv2.imshow("result", result)
cv2.waitKey(0)
cv2.destroyAllWindows()
Ввод:
![enter image description here](https://i.stack.imgur.com/nb6e7.jpg)
Результат:
![enter image description here](https://i.stack.imgur.com/8yXI9.jpg)
При необходимости настройте низкие и высокие цветовые диапазоны, чтобы избавиться от большего количествазеленый.
См. floodfill
ADDITION:
Вот код для выполнения порогового значения inRange в HSV, как предлагается из моих комментариев. Но обратите внимание, что глобальный порог затронул некоторые из почти белых в рубашке, чтобы сделать ее чисто белой. Некоторые из них можно было бы удалить, сделав морфологию большого размера близким или заполнив меньшие контуры белым цветом.
import cv2
import numpy as np
import skimage.exposure
# load image and get dimensions
img = cv2.imread("soccer.jpg")
# convert to hsv
hsv = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
# threshold using inRange
range1 = (20,80,80)
range2 = (90,255,255)
mask = cv2.inRange(hsv,range1,range2)
mask = 255 - mask
# apply morphology opening to mask
kernel = np.ones((3,3), np.uint8)
mask = cv2.morphologyEx(mask, cv2.MORPH_ERODE, kernel)
mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel)
# antialias mask
mask = cv2.GaussianBlur(mask, (0,0), sigmaX=3, sigmaY=3, borderType = cv2.BORDER_DEFAULT)
mask = skimage.exposure.rescale_intensity(mask, in_range=(127.5,255), out_range=(0,255))
result = img.copy()
result[mask==0] = (255,255,255)
# write result to disk
cv2.imwrite("soccer_mask.png", mask)
cv2.imwrite("soccer_green2white.jpg", result)
# display it
cv2.imshow("mask", mask)
cv2.imshow("result", result)
cv2.waitKey(0)
cv2.destroyAllWindows()
Маска:
![enter image description here](https://i.stack.imgur.com/UYpYY.png)
Результат:
![enter image description here](https://i.stack.imgur.com/ok6S6.jpg)
ADDITION2:
Вот еще один способ, который я нашел эффективным вделает удаление зеленого экрана. Конвертировать в LAB. Затем отмените A и умножьте его на B. Затем выполните пороговое значение inRange () для этого, чтобы создать маску. Затем используйте маску, чтобы превратить зеленый в белый. Он предотвращает превращение почти белого в рубашках в чисто белый, что лучше, чем в предыдущем методе. Но, к сожалению, немного зеленого цвета позади.
import cv2
import numpy as np
import skimage.exposure
# load image and get dimensions
img = cv2.imread("soccer.jpg")
# convert to hsv
lab = cv2.cvtColor(img,cv2.COLOR_BGR2LAB)
L = lab[:,:,0]
A = lab[:,:,1]
B = lab[:,:,2]
# negate A
A = (255 - A)
# multiply negated A by B
nAB = 255 * (A/255) * (B/255)
nAB = np.clip((nAB), 0, 255)
nAB = np.uint8(nAB)
# threshold using inRange
range1 = 100
range2 = 160
mask = cv2.inRange(nAB,range1,range2)
mask = 255 - mask
# apply morphology opening to mask
kernel = np.ones((3,3), np.uint8)
mask = cv2.morphologyEx(mask, cv2.MORPH_ERODE, kernel)
mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel)
# antialias mask
mask = cv2.GaussianBlur(mask, (0,0), sigmaX=3, sigmaY=3, borderType = cv2.BORDER_DEFAULT)
mask = skimage.exposure.rescale_intensity(mask, in_range=(127.5,255), out_range=(0,255))
# put white where ever the mask is zero
result = img.copy()
result[mask==0] = (255,255,255)
# write result to disk
cv2.imwrite("soccer_green2white_inrange_lab.jpg", result)
# display it
cv2.imshow("nAB", nAB)
cv2.imshow("mask", mask)
cv2.imshow("result", result)
cv2.waitKey(0)
cv2.destroyAllWindows()
Результат:
![enter image description here](https://i.stack.imgur.com/K35bL.jpg)