opencv - 如何在grabcut中删除带有一些阴影的白色背景?
问题描述
我正在使用grabcut从图像中删除白色背景。边缘的部分背景仍然存在。你能帮我把阴影部分也去掉吗?
输入图像
输出图像
尝试抓取、轮廓、正常阈值,但阴影仍然存在
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)
它应该删除完整的背景
解决方案
这个答案解释了如何使用 Grabcut 和蒙版来提取前景。这个答案有两个步骤。第一步是创建一个掩码,将像素标记为确定前景、确定背景或未知。第二步是应用 Grabcut 算法。
使用Canny
边缘过滤器和两个形态变换创建蒙版。
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]
推荐阅读
- php - 从 HTML 表中获取数据以删除 MySQL 中的记录
- php - 如何在 magento 2.x 中使用 TransportBuilder 发送 iCal 会议请求
- android - 屏幕尺寸无效?
- webpack - webpack 4 - 文件加载器不工作
- javascript - 在 JavaScript 中单击删除多个项目
- php - 与 Laravel Eloquent 类似的文章和排除结果
- java - 从redis转换json对象并从中提取List
- node.js - Nodejs代理不流式传输帖子数据
- sql-server - 如何使用 SQL Server 中的连接表更新更多条件?
- python - 使用搜索功能进行网页抓取并存储返回页面的结果