我正在尝试使用opencv从图像中提取面部。最初,我将图像转换为灰度像这样
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
然后我使用dlib为我生成脸部点,然后将其转换为numpy数组,并使用fillconvexpoly方法将脸部获取到脸部多边形内
#detect facial landmarks
shape = predictor(gray, rect)
#convert facial landmarks to numpy array
shape = face_utils.shape_to_np(shape)
#initialize new array layout as shape
remapped_shape = np.zeros_like(shape)
xmin, ymin = shape.min(axis=0)
xmax, ymax = shape.max(axis=0)
feature_mask=np.zeros((image.shape[0],image.shape[1],3),np.uint8)
feature_mask[:]=(0,0,0)
remapped_shape = face_remap(shape)
cv2.fillConvexPoly(feature_mask, remapped_shape[0:27], [255, 255, 255])
feature_mask = feature_mask.astype(np.bool)
out_face[feature_mask] = image[feature_mask]
cv2.imwrite("out_face.png", out_face)
我试着用
np.zeros((image.shape[0],image.shape[1],4),np.uint8)
但这给我一个错误
ValueError: could not broadcast input array from shape (3) into shape (500,500,4)
如何调整代码以获得预期的输出
这是示例输入
这是我得到的输出
我希望背景透明而不是黑色
最佳答案
您需要4通道BGRA
或RGBA
图像才能具有透明度。我对您的代码进行了一些调整以适合此要求。
feature_mask=np.zeros((image.shape[0],image.shape[1]),np.uint8)
remapped_shape = face_remap(shape)
cv2.fillConvexPoly(feature_mask, remapped_shape, [255])
out_face = cv2.bitwise_and(image, image, mask=feature_mask)
(x,y,w,h) = cv2.boundingRect(remapped_shape)
alpha = np.zeros((h,w), dtype=np.uint8)
feature_mask = feature_mask[y:y+h,x:x+w]
out_face = out_face[y:y+h,x:x+w]
alpha[feature_mask == 255] = 255
mv = []
mv.append(out_face)
mv.append(alpha)
out_face = cv2.merge(mv)