zoukankan      html  css  js  c++  java
  • opencv图像融合(给人脸添加一个眼镜)

    基于dlib68点人脸检测的小功能实现

    图像旋转找的现成的方法,稍稍麻烦点的地方就是mask处理,虽然目的达到了,但是效果一般

     1 import numpy as np
     2 import cv2 as cv
     3 import dlib
     4 import math
     5 
     6 # 做一个戴眼镜的滤镜效果
     7 
     8 detector = dlib.get_frontal_face_detector()
     9 predictor = dlib.shape_predictor('dlib/shape_predictor_68_face_landmarks.dat')
    10 
    11 
    12 # 图像旋转,保持原来大小
    13 def rotate_bound(image, angle):
    14     # grab the dimensions of the image and then determine the
    15     # center
    16     (h, w) = image.shape[:2]
    17     (cX, cY) = (w // 2, h // 2)
    18 
    19     # grab the rotation matrix (applying the negative of the
    20     # angle to rotate clockwise), then grab the sine and cosine
    21     # (i.e., the rotation components of the matrix)
    22     M = cv.getRotationMatrix2D((cX, cY), -angle, 1.0)
    23     cos = np.abs(M[0, 0])
    24     sin = np.abs(M[0, 1])
    25 
    26     # compute the new bounding dimensions of the image
    27     nW = int((h * sin) + (w * cos))
    28     nH = int((h * cos) + (w * sin))
    29 
    30     # adjust the rotation matrix to take into account translation
    31     M[0, 2] += (nW / 2) - cX
    32     M[1, 2] += (nH / 2) - cY
    33 
    34     # perform the actual rotation and return the image
    35     return cv.warpAffine(image, M, (nW, nH))
    36 
    37 
    38 def detect_face(camera_idx):
    39     # camera_idx: 电脑自带摄像头或者usb摄像头
    40     cv.namedWindow('detect')
    41     cap = cv.VideoCapture(camera_idx)
    42 
    43     while cap.isOpened():
    44         cv.namedWindow('detect', cv.WINDOW_AUTOSIZE)
    45         ok, frame = cap.read()
    46         # 为摄像头的时候,翻转画面
    47         if camera_idx == 0 or camera_idx == 1:
    48             frame = cv.flip(frame, 1, dst=None)
    49         if not ok:
    50             break
    51         gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
    52         rects = detector(gray, 0)
    53         for i in range(len(rects)):
    54             landmarks = np.matrix([[p.x, p.y] for p in predictor(frame, rects[i]).parts()])
    55             # 脸轮廓:1~17
    56             # 眉毛:18~22, 23~27
    57             # 鼻梁:28~31
    58             # 鼻子:31~36
    59             # 眼睛:37~42, 43~48
    60             # 嘴唇:49~68
    61             # 左眼角和右眼角的位置
    62             pos_left = (landmarks[0][0, 0], landmarks[36][0, 1])
    63             pos_right = (landmarks[16][0, 0], landmarks[45][0, 1])
    64             face_center = (landmarks[27][0, 0], landmarks[27][0, 1])
    65             src = cv.imread('images/glasses.jpg')
    66             # 433x187眼镜图片原始大小,按人脸比例缩放一下
    67             length = pos_right[0] - pos_left[0]
    68             width = int(187/(433/length))
    69             src = cv.resize(src, (length, width), interpolation=cv.INTER_CUBIC)
    70 
    71             # 角度旋转,通过计算两个眼角和水平方向的夹角来旋转眼镜
    72             sx = landmarks[36][0, 0] - landmarks[45][0, 0]
    73             sy = landmarks[36][0, 1] - landmarks[45][0, 1]
    74             # 夹角正切值
    75             r = sy/sx
    76             # 求正切角,弧度转为度
    77             degree = math.degrees(math.atan(r))
    78             # 调用旋转方法
    79             src = rotate_bound(src, degree)
    80 
    81             # mask处理,去掉旋转后的无关区域,初始化一个全0mask,用或运算处理mask
    82             src_mask = np.zeros(src.shape, src.dtype)
    83             src_mask = cv.bitwise_or(src, src_mask)
    84             # 泊松融合
    85             output = cv.seamlessClone(src, frame, src_mask, face_center, cv.MIXED_CLONE)
    86         cv.imshow('detect', output)
    87         c = cv.waitKey(10)
    88         if c & 0xFF == ord('q'):
    89             break
    90     cap.release()
    91     cv.destroyAllWindows()
    92 
    93 
    94 if __name__ == '__main__':
    95     video = 'video/face.mp4'
    96     detect_face(video)

    眼镜图片

    效果

    泊松融合三种参数效果在这里一样

    除了眼镜图片较浅其他的还算可以吧

    还可以扩展面部其他装饰

    参考:

    泊松融合:https://www.smwenku.com/a/5b7aec012b7177392c97200d

    图像旋转:https://blog.csdn.net/hui3909/article/details/78854387

  • 相关阅读:
    numpy、torch:[ ]里传函数,数组过滤
    torch:torch.sort
    torch : transpose,transpose_
    托管堆和垃圾回收笔记
    UdpClient类客户端和服务端demo
    JavaScript阻止事件冒泡
    单元测试初接触
    CSS选择器
    文档onload处理程序
    TASKKILL命令使用方法
  • 原文地址:https://www.cnblogs.com/MC-Curry/p/10357233.html
Copyright © 2011-2022 走看看