Привязки 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 (по состоянию на несколько недель назад). Для справки мое входное изображение таково:
Я попытался изменить значения перечисления маски результата на что-то более видимое. Проблема не в возвращаемых значениях. Это возвращает полностью черное изображение. Я попробую еще пару ценности.
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 ответов
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.
ваша маска заполнена следующие значения:
- 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