我用 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)
Run Code Online (Sandbox Code Playgroud)
在此图像中,您需要对多个区域进行泛光填充,因为所有背景绿色均未连接。
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()
Run Code Online (Sandbox Code Playgroud)
输入:
结果:
根据需要调整低和高颜色范围以去除更多绿色。
见漫灌
添加:
这是根据我的评论建议在 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()
Run Code Online (Sandbox Code Playgroud)
面具:
结果:
附加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()
Run Code Online (Sandbox Code Playgroud)
结果:
| 归档时间: |
|
| 查看次数: |
12153 次 |
| 最近记录: |