首页 > 解决方案 > 如何使用 Opencv 缩小/扩展面部特征?

问题描述

我正在尝试编写一个应用程序,使用 opencv 和 dlib 使部分面部图像变大或变小。我使用shape_predictor_68_face_landmarks.dat. 在下面的函数中,tmp变量应该以这样一种方式进行转换,即在图像上缩放鼻子或左眼。

def visualize_facial_landmarks(image, shape, colors=None, alpha=0.75):
# create two copies of the input image -- one for the
# overlay and one for the final output image
overlay = image.copy()
output = image.copy()

# if the colors list is None, initialize it with a unique
# color for each facial landmark region
if colors is None:
    colors = [(19, 199, 109), (79, 76, 240), (230, 159, 23),
              (168, 100, 168), (158, 163, 32),
              (163, 38, 32), (180, 42, 220)]

# loop over the facial landmark regions individually
for (i, name) in enumerate(FACIAL_LANDMARKS_INDEXES.keys()):
    # grab the (x, y)-coordinates associated with the
    # face landmark
    (j, k) = FACIAL_LANDMARKS_INDEXES[name]
    pts = shape[j:k]
 
    facial_features_cordinates[name] = pts
    if name != "Jaw" and name == "Left_Eye" or name == "Nose":
        minX = min(pts[:,0])
        maxX = max(pts[:,0])
        minY = min(pts[:,1])
        maxY = max(pts[:,1]) 

        rect = []
        rect.append([minX, minY])
        rect.append([minX, maxY])
        rect.append([maxX, minY])
        rect.append([maxX, maxY])
        rect = np.array(rect)

        hull = cv2.convexHull(rect)
        # print(hull)
        # output = cv2.resize(overlay, dsize)
        # print(overlay[minX:maxX,minY:maxX,:])
        tmp = overlay[minY:maxY, minX:maxX, :]
        print(tmp.shape)
        s = 2

        Affine_Mat_w = [s, 0, tmp.shape[0]/2.0 - s*tmp.shape[0]/2.0]
        Affine_Mat_h = [0, s, tmp.shape[1]/2.0 - s*tmp.shape[1]/2.0]


        M = np.c_[ Affine_Mat_w, Affine_Mat_h].T 

        tmp = cv2.warpAffine(tmp, M, (tmp.shape[1], tmp.shape[0]))
        overlay[minY:maxY, minX:maxX, :] = tmp

return overlay

作为示例,附上以下图片: 在此处输入图像描述

标签: pythonopencvimage-processingcomputer-vision

解决方案


更新 #1

pinch and bulge distortion在眼睛和鼻子周围少量沿着面部标志应用可能会提供不错的结果,而无需转向其他方法。虽然如果它影响更大的区域,它也有可能会明显扭曲眼镜。这些应该有帮助,


我不确定如何单独在 opencv 中做到这一点,而不会看起来不自然。以下是基于我自己的探索的一般解释。如果我犯了任何错误,请随时纠正我。

3D 网格

我认为当前的面部美化方法(例如 Android 相机上的方法)的一种方法是将 3d 面部网格或整个头部模型对齐到原始面部之上。

它使用面部标志提取面部纹理,并将它们与相应的 3d 网格对齐,并应用纹理。这样可以调整 3d 网格,并且纹理将遵循面部几何形状。可能还有其他步骤,例如将结果传递给另一个网络,涉及后处理以使其看起来更自然。

Mediapipe Face Mesh也可能会有所帮助,因为它提供了密集的 3D 人脸地标和3D 人脸模型、UV 可视化、坐标。这是关于媒体管道中面的 UV 展开的讨论。

在此处输入图像描述

来自https://github.com/YadiraF/DECA的示例。

在此处输入图像描述

来自https://github.com/sicxu/Deep3DFaceRecon_pytorch的示例。

在此处输入图像描述

GAN

另一种方法是使用 GAN 来编辑面部特征、应用照明、化妆等。

来自https://github.com/run-youngjoo/SC-FEGAN的示例。

在此处输入图像描述

另一个例子,https://github.com/genforce/idinvert_pytorch

在此处输入图像描述


推荐阅读