如何使用GC_INIT_WITH_MASK获取grabCut以使用opencv python

时间:2017-10-19 08:19:59

标签: python opencv numpy matplotlib

我正在努力让Messi示例工作:https://docs.opencv.org/3.1.0/d8/d83/tutorial_py_grabcut.html

在我的设置中,我希望整个过程自动化。

例如,我从网上抓取一张图片: http://wanderlustandlipstick.com/travel-tips/opting-out-full-body-scanners/

Image Scan - imagescan.png

使用一些opencv工具我自动生成以下掩码:

Image Mask - imagemask.png

黑色应该是某种背景,白色应该是某个前景,灰色应该是未知的。

按照messi教程(https://docs.opencv.org/3.1.0/d8/d83/tutorial_py_grabcut.html),下面是我的代码。但是,它只显示小的白色圆圈区域,就好像它像黑色一样处理灰色(某些背景)

import numpy as np
import cv2
from matplotlib import pyplot as plt

img = cv2.imread("imagescan.png")
dimy = np.shape(img)[0] # seems to be backwards (x,y)
# https://stackoverflow.com/questions/22490721/how-can-i-get-the-x-and-y-dimensions-of-a-ndarray-numpy-python
dimx = np.shape(img)[1]
mask = np.zeros((dimy,dimx),np.uint8) # zeroes as array/matrix size of image
bgdModel = fgdModel = np.zeros((1,65),np.float64)    

newmask = cv2.imread('imagemask.png',0)

# informational purposes
removeBg = (newmask == 0)
removeBg = np.ravel(removeBg)
np.bincount(removeBg)
keepFg = (newmask == 255)
keepFg = np.ravel(keepFg)
np.bincount(keepFg)

#otherEl = (not (newmask == 0 or newmask == 255)) # throws error
#otherEl = np.ravel(otherEl)
#np.bincount(otherEl)

# appears at least one of each elements is required
# otherwise throws bgdSamples.empty error / fgdSamples.empty error
mask[newmask == 0] = 0
mask[newmask == 255] = 1

mask, bgdModel, fgdModel = cv2.grabCut(img,mask,None,bgdModel,fgdModel,5,cv2.GC_INIT_WITH_MASK)

mask2 = np.where((mask==2)|(mask==0),0,1).astype('uint8')
img2 = img*mask2[:,:,np.newaxis]
plt.imshow(img2),plt.colorbar(),plt.show()

结果只是圆圈上的一个遮罩,好像灰色区域被视为黑色。

Output is not what I want!

1 个答案:

答案 0 :(得分:1)

在蒙版图像中,您基本上有3种颜色:黑色,白色,灰色。在以下代码行中,您将设置背景和前景,但不是可能的前景。

mask[newmask == 0] = 0
mask[newmask == 255] = 1

尝试使用OpenCV提供的常量(cv2.GC_BGD等)以避免混淆。

# this line sets the grey areas - meaning any color not 0 and not 255 - to probable foreground.
mask = np.where(((newmask>0) & (newmask<255)),cv2.GC_PR_FGD,0).astype('uint8')
mask[newmask == 0] = cv2.GC_BGD
mask[newmask == 255] = cv2.GC_FGD

Result