【发布时间】:2017-12-25 00:27:01
【问题描述】:
我使用 OpenCV 示例中的交互式 grabcut.py 来分割图像并保存前景和背景模型。然后我使用这些模型来分割更多相同类型的图像,因为我不想每次都重新训练模型。
运行抓取算法后,掩码全为零(全为背景),因此它不会分割任何内容。
from matplotlib import pyplot as plt
import numpy as np
import cv2
img = cv2.imread('usimg1.jpg')
mask = np.zeros(img.shape[:2], np.uint8)
bgdModel = np.load('bgdmodel.npy')
fgdModel = np.load('fgdmodel.npy')
cv2.grabCut(img, mask, None, bgdModel, fgdModel, 5, cv2.GC_EVAL)
mask = np.where((mask==2) | (mask==0), 0, 1).astype('uint8')
img = img * mask[:, :, np.newaxis]
plt.imshow(img)
plt.show()
我尝试使用掩码或矩形初始化算法,但这会产生错误,因为模型不是空的(这是我真正想要的)。
我如何必须将预训练的模型传递给算法,这样每次我分割图像时它们就不会从头开始重新训练?
编辑 在 rayryeng 发表评论后,我实现了以下代码:
cv2.grabCut(img, mask, rect, bgdModel, fgdModel, 0, cv2.GC_INIT_WITH_RECT)
cv2.grabCut(img, mask, rect, bgdModel, fgdModel, 2, cv2.GC_EVAL)
它似乎有效,但第一次调用现在改变了我的模型。在源代码中它调用learnGMMs 而不检查是否提供了预训练模型。
【问题讨论】:
-
Bgdmodel.npy 是你想要并重用的?
-
是的,bgdmodel.npy 和 fgdmodel.npy
-
这很奇怪...
cv2.GC_EVAL的目的是已经使用预训练模型。您甚至可以在源代码中看到这一点。 github.com/opencv/opencv/blob/master/modules/imgproc/src/…。当遇到GC_EVAL时,它会在实际进行分割之前对掩码进行简单的错误检查,而无需实际进行学习。您应该能够使用cv2.GC_EVAL并将前景掩码指定为None应该可以正常工作。 -
另外,
grabcut的测试用例也很好奇:github.com/opencv/opencv/blob/…。您会看到他们首先调用grabcut进行 0 次迭代来学习模型,然后他们再次重用这些相同的模型来实际进行分割 - 2 次迭代。试试看?尝试先用 0 次迭代学习模型,然后使用带有GC_EVAL的预计算模型进行最终分割。 -
@rayryeng 是的,它成功了,谢谢!
标签: python opencv image-processing image-segmentation