Reputation: 869
Given a random picture, I'm successfully detecting a face and cropping out the calculated ROI. Next thing I'm trying to achieve is to remove the background, where I'm currently stuck.
I'm trying to manipulate grabcut.py to mark the background and foreground programmatically to get better results using grabCut()
with GC_WITH_INIT_MASK
import cv2 as cv
import numpy as np
img = cv.imread('./man.jpeg', cv.IMREAD_UNCHANGED)
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
profile = cv.CascadeClassifier('/usr/local/Cellar/opencv/4.1.0_2/share/opencv4/haarcascades/haarcascade_frontalface_default.xml')
faces = profile.detectMultiScale(gray, 1.3, 5)
print(len(faces))
if len(faces) > 1 or len(faces) == 0:
print('more than one or zero found')
exit()
for (x, y, w, h) in faces:
y1 = int(y - h/2)
y2 = int(y + h*2)
x1 = int(x - w/2)
x2 = int(x + w*2)
//TODO: check if dimensions outside original img
cropped = img[y1:y2, x1:x2]
//estimate marking sections which are BG and FG
cv.line(cropped, (int(cropped.shape[0]/6), 0), (int(cropped.shape[0]/6), int(cropped.shape[1]/3)), (0), 5)
cv.line(cropped, (int(cropped.shape[0]), 0), (int(cropped.shape[0] - cropped.shape[0]/4), int(cropped.shape[1]/3)), (0), 5)
cv.line(cropped, (int(cropped.shape[0]/6), int(cropped.shape[1] - cropped.shape[1]/6)), (int(cropped.shape[0] - cropped.shape[0]/6*2), int(cropped.shape[1] - cropped.shape[1]/6)), (255), 5)
mask = np.zeros(cropped.shape[:2], np.uint8)
bgModel = np.zeros((1, 65), np.float64)
fgModel = np.zeros((1, 65), np.float64)
//getting an error of incorrect indicies?
#mask[cropped == 0] = 0
#mask[cropped == 255] = 1
cv.grabCut(cropped, mask, None, bgModel, fgModel, 5, cv.GC_INIT_WITH_MASK)
//tried both...second from grabcut.py
#mask2 = np.where((mask==2) | (mask==0), 0, 1).astype('uint8')
mask2 = np.where((mask==1) + (mask==3), 255, 0).astype('uint8')
output = cv.bitwise_and(cropped, cropped, mask=mask2)
cv.imshow('img', output)
cv.waitKey(0)
cv.destroyAllWindows()
Right now I'm getting
error: (-215:Assertion failed) !bgdSamples.empty() && !fgdSamples.empty() in function 'initGMMs'
This is basically a collection of many different tutorials, trial and errors. I am using this as a learning experience so any guidance will be greatly appreciated. Thanks in advance!
Upvotes: 1
Views: 244
Reputation: 126
you can try
gray = cv2.cvtColor(cropped, cv2.COLOR_BGR2GRAY)
mask[gray == 0] = 0
mask[gray == 255] = 1
I think maybe the mask should not be empty in the mode of cv.GC_INIT_WITH_MASK
Upvotes: 1