有没有办法在减去背景的同时减少图像中的噪声?

Is there a way to reduce noise in image while subtracting background?

我正在尝试减去图像的背景以创建剪影图像以供进一步处理。我的图像数据集如下图所示:

这是我到目前为止所做的:

import cv2
import numpy as np

frame = cv2.imread("test.png")
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
lower_blue = np.array([0, 0, 120])
upper_blue = np.array([180, 38, 255])
mask = cv2.inRange(hsv, lower_blue, upper_blue)
result = cv2.bitwise_and(frame, frame, mask=mask)
b, g, r = cv2.split(result)  
filter = g.copy()

ret,mask = cv2.threshold(filter,10,255, 1)
frame[ mask == 0] = 255

cv2.imwrite("123.png", mask)

我得到的结果是:

现在我试图找到并应用等高线,但它不起作用

contours_mask, hierachy = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

for contour in range(len(contours_mask)):
    # create mask
    if contour != 1:
        cv2.fillConvexPoly(mask_b, contours_mask[contour], (0, 0, 0))

有没有办法去除噪点并得到像这张图片这样的结果?

在这种情况下,要获得人物的大概轮廓,可以使用OSTU的方法。

import cv2
import numpy as np

# load image, convert to grayscale
frame = cv2.imread("test.png")
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

# binarize image using OSTU's method
*_, mask = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)

输出蒙版非常接近实际结果,但是,如果您想细化蒙版,我建议使用 cv2.grabCut 函数,提取前景和背景部分。

# get the bounding box of the silhouette
contours, *_ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
c = max(contours, key=cv2.contourArea)
rect = cv2.boundingRect(c)

# initialize grabCut's parameters
mask_refined = np.empty_like(mask)
fgd_model = np.zeros((1, 65))
bgd_model = np.zeros((1, 65))
iter_count = 10
mode = cv2.GC_INIT_WITH_RECT

# segment image
mask_refined, bgd_model, fgd_model = cv2.grabCut(frame, mask_refined, rect, bgd_model, fgd_model, iter_count, mode)

# select foreground and background
output = np.where((mask_refined == cv2.GC_BGD) | (mask_refined == cv2.GC_PR_BGD), 0, 255).astype(np.uint8)