首页 > 解决方案 > OpenCV 检测人脸、裁剪轮廓、使用 grabCut 以编程方式标记和移除背景

问题描述

给定一张随机图片,我成功地检测到了一张脸并裁剪了计算出的 ROI。我要实现的下一件事是删除我目前卡住的背景。

我正在尝试操纵grabcut.py以编程方式标记背景和前景,以获得更好的结果使用grabCut()withGC_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()

现在我得到 error: (-215:Assertion failed) !bgdSamples.empty() && !fgdSamples.empty() in function 'initGMMs'

这基本上是许多不同教程、试验和错误的集合。我将其用作学习经验,因此将不胜感激任何指导。提前致谢!

标签: pythonopencv

解决方案


你可以试试

gray = cv2.cvtColor(cropped, cv2.COLOR_BGR2GRAY)
mask[gray == 0] = 0
mask[gray == 255] = 1

我认为也许掩码不应该在模式下为空cv.GC_INIT_WITH_MASK


推荐阅读