opencv圖像融合(給人臉添加一個眼鏡)
阿新 • • 發佈:2019-02-09
msh tar 處理 ans csdn des new bic cto
基於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 cosine21 # (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
opencv圖像融合(給人臉添加一個眼鏡)