如何使用Python中的OpenCV将图像上的背景色设置为白色

如何使用Python中的OpenCV将图像上的背景色设置为白色,python,opencv,Python,Opencv,我用Python中的OpenCV库阅读了一张图片。 我想知道,我怎样才能把背景颜色改成白色。我只想有人从图像和白色背景 例如: 我想更改为: 我怎么能做这样的事: 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) 在此图像中

我用Python中的OpenCV库阅读了一张图片。 我想知道,我怎样才能把背景颜色改成白色。我只想有人从图像和白色背景

例如:

我想更改为:

我怎么能做这样的事:

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)

在此图像中,您需要在多个区域中进行整体填充,因为所有背景绿色都没有连接

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()

输入:

结果:

根据需要调整低和高颜色范围,以去除更多的绿色

补充:

下面是我在评论中建议的在HSV中执行inRange阈值的代码。但请注意,全局阈值已影响衬衫中的一些近白色,使其成为纯白色。其中一些可以通过做一些大尺寸的形态学处理或用白色填充较小的轮廓来去除

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()

遮罩:

结果:

补充2:

这里有另一种方法,我发现在做绿色屏幕删除有效。转换到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()

结果:


有没有可能去除所有的“绿色”颜色?如果不改变衬衫的白色部分,可能不使用泛光填充。但是您可以尝试更改绿色范围的值。更好的方法可能是对HSV颜色空间中的绿色色调使用泛光填充或inRange()阈值来制作遮罩,然后使用遮罩更改原始图像的绿色颜色。但是衬衫周围可能仍然有绿色的边缘,可能需要一些抗锯齿来去除。你能告诉我为什么在
[h+2,w+2]
中使用数字2吗?你是如何在泛光填充中计算数字的?遮罩必须大2个像素。请参阅文档。我通过一些类似于GIMP或Photoshop的工具在深绿色区域以交互方式测量颜色得到了这些颜色。在Python/OpenCV中,转换为HSV。获取左上角的HSV值。对HSV图像执行inRange()阈值设置以制作遮罩。如果遮罩为白色,则使用遮罩将原始图像颜色更改为白色。只有当背景中没有绿色时,这才有效。或查看以获取全自动在线方式。