进行人脸简单的颜色融合方法,和使用MSL

1、获取人脸的roi的mask区域,主要通过获取边缘点的凸包,然后填充凸边缘即可达到相应的mask,其代码代码如下:

def mask_from_points(size, points, erode_flag=1):
    #其中points是(68,2)的检测到人脸关键点坐标矩阵
    radius = 10  # 腐蚀的核大小
    kernel = np.ones((radius, radius), np.uint8)

    mask = np.zeros(size, np.uint8)
    cv2.fillConvexPoly(mask, cv2.convexHull(points), 255)
    if erode_flag:
        mask = cv2.erode(mask, kernel, iterations=1)

    return mask

 

2、当进行一些图像融合的时候,需要解决两张图像之间的颜色的差距,这个可以使用类似局部颜色矫正的方法来进行两张图的颜色合并,示例代码如下:

def correct_colours(im1, im2, landmarks1):
    #这里使用左右眼睛的中心距离作为高斯滤波的核大小。其中这个核要越大越好。这样子就不容易受边缘的过渡影响。
    COLOUR_CORRECT_BLUR_FRAC = 0.75
    LEFT_EYE_POINTS = list(range(42, 48))
    RIGHT_EYE_POINTS = list(range(36, 42))

    blur_amount = COLOUR_CORRECT_BLUR_FRAC * np.linalg.norm(
        np.mean(landmarks1[LEFT_EYE_POINTS], axis=0) -
        np.mean(landmarks1[RIGHT_EYE_POINTS], axis=0))
    blur_amount = int(blur_amount)
    if blur_amount % 2 == 0:
        blur_amount += 1
    blur_amount=61
     #其中这里的im1_blur、im2_blur就相当于掩膜
    im1_blur = cv2.GaussianBlur(im1, (blur_amount, blur_amount), 0)
    im2_blur = cv2.GaussianBlur(im2, (blur_amount, blur_amount), 0)

    # 避免出现除于0的情况
    im2_blur = im2_blur.astype(int)
    im2_blur += 128 * (im2_blur <= 1)

    result = im2.astype(np.float64) * im1_blur.astype(np.float64) / im2_blur.astype(np.float64)
    result = np.clip(result, 0, 255).astype(np.uint8)

    return result

再上面的roi颜色融合完成后,后面就可以把这个roi进行贴图到原图上可以使用opencv自带的seamlessClone函数来平滑边缘。其代码为:

    def fast_face_swap(self, dst_img, dst_face_rect: dlib.rectangle):
        success = 1
        failed = 0
        dst_points = face_points_detection(dst_img, dst_face_rect)
        if not check_points(dst_img, dst_points):
            logging.error("part of Face")
            return (failed, dst_img)

        dst_mask = mask_from_points(
            dst_img.shape[:2], dst_points, erode_flag=1)

        r = cv2.boundingRect(dst_points)
        (x, y, w, h) = r

        if y + h > dst_img.shape[0] or x + w > dst_img.shape[1]:
            return (failed, dst_img)

        dst_roi = dst_img[y:y + h, x:x + w]
        dst_mask = dst_mask[y:y + h, x:x + w]
        dst_points -= (x, y)
        dst_only_face = apply_mask(dst_roi, dst_mask)

        warped_src_face = warp_image_3d(
            self.src_only_face, self.src_points[:48], dst_points[:48], dst_roi.shape[:2])
        #进行对应roi区域进行颜色融合
        new_src_face = correct_colours(
            dst_only_face, warped_src_face, dst_points)

        center = (int(x + w / 2), int(y + h / 2))
        #进行roi区域贴合到原图上
        output = cv2.seamlessClone(
            new_src_face, dst_img, dst_mask, center, cv2.NORMAL_CLONE)
        return (success, output)

其中warp_image_3d()函数主要是通过把48个人脸外围点包围成的roi进行分割成很多小的三角形。然后对每一个三角形区域进行求其旋转矩阵,对每个小块进行仿射变换,最后把原图变换成跟模板图一样的形状区域。

注意:其进行颜色融合的主要方法是参考了:局部颜色矫正的算法(Local Color Correction Using Non-Linear Masking)

3、MSL移动最小二乘变形算法变形图像:

imgwarp-opencv

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值