OpenCV Python绑定的GrabCut算法

7
我一直在尝试使用Python绑定的OpenCV实现grab cut方法。我已经尝试了cv和cv2两个版本,但是我无法找到正确的参数来使该方法正确运行。我已经尝试了多种参数组合,但没有任何效果(基本上我在Github上看到的每一个例子)。以下是我试图遵循的几个示例: 示例1 示例2 以下是该方法的文档和已知的错误报告: 文档 已知的Grabcut错误 我可以使用下面的示例代码运行代码,但它返回一个空白(全黑)图像蒙版。
img = Image("pills.png")
mask = img.getEmpty(1)
bgModel = cv.CreateMat(1, 13*5, cv.CV_64FC1)
fgModel = cv.CreateMat(1, 13*5, cv.CV_64FC1)
for i in range(0, 13*5):
    cv.SetReal2D(fgModel, 0, i, 0)
    cv.SetReal2D(bgModel, 0, i, 0)

rect = (150,70,170,220)
tmp1 = np.zeros((1, 13 * 5))
tmp2 = np.zeros((1, 13 * 5))
cv.GrabCut(img.getBitmap(),mask,rect,tmp1,tmp2,5,cv.GC_INIT_WITH_RECT)

我正在使用SimpleCV加载图像。img.getBitmap()的掩码类型和返回类型如下:
iplimage(nChannels=1 width=730 height=530 widthStep=732 )
iplimage(nChannels=3 width=730 height=530 widthStep=2192 )

如果有人有这段代码的工作示例,我很想看看。值得一提的是,我正在运行OSX Snow Leopard,我的OpenCV版本是从SVN存储库安装的(几周前)。我要处理的输入图像如下: Input Image 我已尝试将结果掩码枚举值更改为更明显的值,但问题并不在于返回值。这将返回一个完全黑色的图像。我将尝试更多的值。
img = Image("pills.png")
mask = img.getEmpty(1)
bgModel = cv.CreateMat(1, 13*5, cv.CV_64FC1)
fgModel = cv.CreateMat(1, 13*5, cv.CV_64FC1)
for i in range(0, 13*5):
    cv.SetReal2D(fgModel, 0, i, 0)
    cv.SetReal2D(bgModel, 0, i, 0)

rect = (150,70,170,220)
tmp1 = np.zeros((1, 13 * 5))
tmp2 = np.zeros((1, 13 * 5))
cv.GrabCut(img.getBitmap(), mask, rect, tmp1, tmp2, 5, cv.GC_INIT_WITH_MASK)
mask[mask == cv.GC_BGD] = 0
mask[mask == cv.GC_PR_BGD] = 0
mask[mask == cv.GC_FGD] = 255
mask[mask == cv.GC_PR_FGD] = 255
result = Image(mask)
result.show()
result.save("result.png")

将示例移动到主线程。 - kscottz
2个回答

5

Kat,你的这个代码版本对我来说似乎可用。

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


filename = "pills.png"
im = cv2.imread(filename)

h,w = im.shape[:2]

mask = np.zeros((h,w),dtype='uint8')
rect = (150,70,170,220)
tmp1 = np.zeros((1, 13 * 5))
tmp2 = np.zeros((1, 13 * 5))

cv2.grabCut(im,mask,rect,tmp1,tmp2,10,mode=cv2.GC_INIT_WITH_RECT)

plt.figure()
plt.imshow(mask)
plt.colorbar()
plt.show()

生成一个如下图所示的图形,标签为0、2和3。 enter image description here

1

您的掩模填充了以下值

  • GC_BGD 定义了明显的背景像素。
  • GC_FGD 定义了明显的前景(对象)像素。
  • GC_PR_BGD 定义了可能的背景像素。
  • GC_PR_FGD 定义了可能的前景像素。

这些都是枚举的一部分:

enum { GC_BGD    = 0,  // background
       GC_FGD    = 1,  // foreground
       GC_PR_BGD = 2,  // most probably background
       GC_PR_FGD = 3   // most probably foreground
     };

这对应的颜色是:完全黑色、非常黑色、深黑色和黑色。我认为如果你添加以下代码(取自你的示例1并稍作修改),你的遮罩将会更美观:

mask[mask == cv.GC_BGD] = 0 //certain background is black
mask[mask == cv.GC_PR_BGD] = 63 //possible background is dark grey
mask[mask == cv.GC_FGD] = 255  //foreground is white
mask[mask == cv.GC_PR_FGD] = 192 //possible foreground is light grey

1
当我尝试让这个工作时,我注意到了这一点。我只是运行了以下代码片段: - kscottz
请查看我上面添加的代码片段,这个也不起作用。感谢您的帮助。如果您能提供您使用的示例图像,我将不胜感激。 - kscottz
如果您尝试下面Jan Erik评论中的代码,会发生什么? - jilles de wit

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接