Как установить цвет фона на изображении на белый с OpenCV в Python - PullRequest
0 голосов
/ 19 октября 2019

У меня есть одна картинка, прочитанная с помощью OpenCV lib в Python. Мне интересно, как я могу изменить цвет фона на белый. Я просто хочу, чтобы люди с изображения и белого фона.

Например:

enter image description here

Я хочу изменить на это:

enter image description here

Как мне сделать такую ​​вещь:

import numpy as np
import cv2

my_image = r'C:\Users\Pc\Desktop\preklapanje4.jpg'
my_image = cv2.imread(my_image, 1)

cv2.imshow('img',my_image)
cv2.waitKey(0)

1 Ответ

0 голосов
/ 19 октября 2019

На этом изображении вам необходимо заполнить заливку в нескольких регионах, поскольку весь зеленый фоновый цвет не подключен.

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

Результат:

enter image description here

При необходимости настройте низкие и высокие цветовые диапазоны, чтобы избавиться от большего количествазеленый.

См. 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

Результат:

enter image description here

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...