denikov
denikov

Reputation: 869

OpenCV detecting a face, cropping a profile, programmatically marking and removing background with grabCut

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

Answers (1)

monkeyking9528
monkeyking9528

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

Related Questions