Python OpenCV 纯白背景

str*_*ker 5 python opencv computer-vision

我有一个DIY的家庭照相馆来拍照。我希望它们处于纯白色背景 (#FFFFFF) 上,并且用户交互最少

这是我的原始图片(没有任何处理,只是来自相机的原始 JPG) 原始图像

我用opencv和Tkinter为UI实现了简单的python程序

1)获取物体的矩形(ROI)

我决定使用 UI 选择 ROI,也许稍后我会编写代码来自动识别照片上的对象。

选择投资回报率

2)使用 cv2.grabCut 函数,我尝试从该矩形中剪切背景

用矩形抓取剪切

cv2.grabCut(image, self.mask, rect, bgdmodel, fgdmodel, 5, cv2.GC_INIT_WITH_RECT)
Run Code Online (Sandbox Code Playgroud)

3)如果有必要,我为抓取创建自定义掩模,它可以提供更准确的对象提取

用面具抓剪

cv2.grabCut(image, self.mask, rect, bgdmodel, fgdmodel, 5, cv2.GC_INIT_WITH_MASK)
Run Code Online (Sandbox Code Playgroud)

4)在此步骤之后,我可以在我的对象所在的位置创建蒙版。我还将蒙版大小调整了 30px

mask = cv2.resize(mask, ( crop_img.shape[1] + 30,  crop_img.shape[0] + 30))
mask = mask[30 : crop_img.shape[0], 30 : crop_img.shape[1]]
Run Code Online (Sandbox Code Playgroud)

所以这个面具有更多的宽度和高度

对象掩码

5)我使用这个掩码进行 SeamlessClone 方法

src_bg = 255 * np.ones(self.src.shape, self.src.dtype)

width, height, channels = src_bg.shape
center = (int(height / 2), int((width / 2)))
output = cv2.seamlessClone(crop_img, src_bg, mask, center, cv2.MIXED_CLONE)
Run Code Online (Sandbox Code Playgroud)

并得到这样的结果: 输出

除了物体右侧的一些伪像之外,看起来不错。看来我的面具不太合适。这不是一个真正的问题。真正的问题是:seamlessClone 给我的不是真正的白色背景。看一下等级:

级别

一些奇怪的渐变和背景在右下角并不是真正的白色。我尝试了很多图像,经常会出现这样的情况。

我的问题是:做我想做的事的正确方法是什么?我的方法是否可以用于此任务以及如何在没有此类渐变的情况下制作真正的白色(#FFFFFF)背景。谢谢

小智 1

如果你提高对比度则可能无需额外的灯光或手动初始化即可消除阴影。

对于如此干净的背景,您可以尝试其他分割,例如Watershed。它也使用标记,但速度更快一些。

您可以从距离变换+阈值获取内部标记,从阈值+膨胀获取外部标记,如果需要它们,您可以使用霍夫变换或活动轮廓从边缘获取线条。

我认为你seamlessClone造成了梯度。“无缝”部分是由于混合。只需将黑色蒙版乘以图像即可去除背景,然后将结果添加到白色图像中。