Этот ответ объясняет, как использовать Grabcut и маску для извлечения переднего плана. В этом ответе есть два шага. Первым шагом является создание маски, которая маркирует пиксели как уверенный передний план, верный фон или неизвестный Второй шаг - применение алгоритма Grabcut.
Маска создается с использованием Canny
краевого фильтра и двух морфологических преобразований .
edges = cv.Canny(img, 80,150)
kernel = np.ones((5,5), np.uint8)
closing = cv.morphologyEx(edges, cv.MORPH_CLOSE, kernel, iterations=3)
erosion = cv.morphologyEx(closing, cv.MORPH_ERODE, kernel, iterations=1)
# When using Grabcut the mask image should be:
# 0 - sure background
# 1 - sure foreground
# 2 - unknown
mask = np.zeros(img.shape[:2], np.uint8)
mask[:] = 2
mask[erosion == 255] = 1
Эта маска даст алгоритму Grabcut подсказки о том, что является верным передним планом и каков верный фон. Затем примените Grabcut с маской:
bgdmodel = np.zeros((1, 65), np.float64)
fgdmodel = np.zeros((1, 65), np.float64)
out_mask = mask.copy()
out_mask, _, _ = cv.grabCut(img,out_mask,None,bgdmodel,fgdmodel,1,cv.GC_INIT_WITH_MASK)
out_mask = np.where((out_mask==2)|(out_mask==0),0,1).astype('uint8')
out_img = img*out_mask[:,:,np.newaxis]
mask
отображается как mask*123
, так что передний план серого цвета, задний фон черного цвета, а неизвестный белый: