【问题标题】:OpenCV Python Bindings for GrabCut Algorithm用于 GrabCut 算法的 OpenCV Python 绑定
【发布时间】:2012-03-17 04:12:32
【问题描述】:

我一直在尝试通过 Python 绑定使用抓取方法的 OpenCV 实现。我曾尝试在 cv 和 cv2 中使用该版本,但我无法找到正确的参数以使该方法正确运行。我已经尝试了参数的几种排列,但似乎没有任何效果(基本上我在 Github 上看到的每个示例)。以下是我尝试过的几个示例:

Example 1

Example 2

这里是该方法的文档和一个已知的错误报告:

Documentation

Known Grabcut Bug

我可以使用下面的示例执行代码,但它返回一个空白(全黑)图像掩码。

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 存储库安装的(截至几周前)。作为参考,我的输入图像是这样的:

我尝试将结果掩码枚举值更改为更明显的值。问题不是返回值。这将返回一个完全黑色的图像。我会尝试更多的值。

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")

【问题讨论】:

  • 将示例移至主线程。

标签: python opencv computer-vision


【解决方案1】:

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。

【讨论】:

    【解决方案2】:

    你的面具上填满了following values

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

    它们都是enum 的一部分:

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

    这意味着颜色:全黑、非常黑、深黑和黑色。我想您会发现,如果您添加以下代码(取自您的 example 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
    

    【讨论】:

    • 所以当我试图让它工作时,我注意到了这一点。我刚刚运行了以下 sn-p:
    • 看我上面加的sn-p,这也行不通。谢谢您的帮助。如果您能摆出您使用的示例图片,我将不胜感激。
    • 如果您尝试下面 Jan Erik 评论中的代码会发生什么?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-17
    • 2018-10-09
    • 1970-01-01
    • 2014-11-20
    • 1970-01-01
    • 2016-10-29
    • 1970-01-01
    相关资源
    最近更新 更多