如何在抓取中删除带有阴影的白色背景?

时间:2019-06-28 13:32:46

标签: opencv image-processing opencv3.0 opencv-contour

我正在使用抓取功能从图像中删除白色背景。边缘的背景部分仍然保留。您能帮我去除阴影部分吗?

输入图片

Input image

输出图像

output image

尝试抓取,轮廓,正常阈值但阴影仍然存在

img_ray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
ret, thresh = cv.threshold(img_ray, 127, 255, cv.THRESH_BINARY+cv.THRESH_OTSU)
contours, hierarchy = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_NONE)
cnt = contours[4]
cv.drawContours(img, [cnt], 0, (0, 255, 0), 3)
mask = np.zeros(img.shape[:2], np.uint8)
bgdmodel = np.zeros((1, 65), np.float64)
fgdmodel = np.zeros((1, 65), np.float64)
height = img.shape[0]
width = img.shape[1]
rect = (50, 0, width, height)
cv.grabCut(img, mask, rect, bgdmodel, fgdmodel, 10, cv.GC_INIT_WITH_RECT)
mask2 = np.where((mask == 2) | (mask == 0), 0, 1).astype('uint8')
img = img * mask2[:, :, np.newaxis]
img[np.where((img == [230, 230, 230]).all(axis=2))] = [0, 0, 0]
cv.bitwise_not(img)

它应该删除整个背景

1 个答案:

答案 0 :(得分:1)

此答案说明了如何使用Grabcut和遮罩提取前景。此答案有两个步骤。第一步是创建一个将像素标记为肯定前景,肯定背景或未知像素的蒙版。第二步是应用Grabcut算法。

使用Canny边缘滤镜和两个morphological transformations创建遮罩。

edges = cv.Canny(img, 80,150)
kernel = np.ones((5,5), np.uint8)
closing = cv.morphologyEx(edges, cv.MORPH_CLOSE, kernel, iterations=3)
erosion = cv.morphologyEx(closing, cv.MORPH_ERODE, kernel, iterations=1)

# When using Grabcut the mask image should be:
#    0 - sure background
#    1 - sure foreground
#    2 - unknown

mask = np.zeros(img.shape[:2], np.uint8)
mask[:] = 2
mask[erosion == 255] = 1

此蒙版将为Grabcut算法提供有关什么是肯定前景和什么是肯定背景的提示。接下来,在面具上应用Grabcut:

bgdmodel = np.zeros((1, 65), np.float64)
fgdmodel = np.zeros((1, 65), np.float64)

out_mask = mask.copy()
out_mask, _, _ = cv.grabCut(img,out_mask,None,bgdmodel,fgdmodel,1,cv.GC_INIT_WITH_MASK)
out_mask = np.where((out_mask==2)|(out_mask==0),0,1).astype('uint8')
out_img = img*out_mask[:,:,np.newaxis]

mask显示为mask*123,以确保前景为灰色,背景为黑色,未知背景为白色: output