Привязки OpenCV Python для алгоритма GrabCut
Я пытался использовать реализацию OpenCV метода grab cut через привязки Python. Я пробовал использовать версию как в cv, так и в cv2, но у меня возникли проблемы с поиском правильных параметров для использования, чтобы заставить метод работать правильно. Я попробовал несколько перестановок параметров, и ничего не работает (в основном каждый пример, который я видел на Github). Вот несколько примеров, которым я попытался следовать:
А вот документация по методу и известный отчет об ошибке:
Я могу получить код для выполнения, используя приведенный ниже пример, но он возвращает пустую (полностью черную) маску изображения.
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 (по состоянию на несколько недель назад). Для справки мой входной образ таков:

Я попытался изменить значения enum маски результата на что-то более заметное. Проблема заключается не в возвращаемых значениях. Это возвращает полностью черное изображение. Я попробую еще пару значений.
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")
2 ответов:
Кэт, эта версия твоего кода, кажется, работает на меня.
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.
Ваша маска заполняется следующими значениями :
- GC_BGD определяет очевидные пиксели фона.
- GC_FGD определяет очевидный пиксель переднего плана (объекта).
- GC_PR_BGD определяет возможный пиксель фона.
- GC_PR_FGD определяет возможный пиксель переднего плана.
Которые все являются частью перечисления:
Что переводится как цвета: полностью черный, Очень черный, темно-черный и черный. Я думаю, вы найдете это, если вы ... добавьте следующий код (взятый из вашего Примера 1 и слегка измененный), ваша маска будет выглядеть лучше:enum { GC_BGD = 0, // background GC_FGD = 1, // foreground GC_PR_BGD = 2, // most probably background GC_PR_FGD = 3 // most probably foreground };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

Comments