<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
python3.9.6
pycharm 2021
庫環境:
dlib
opencv-python
視訊圖片效果如下:
攝像頭實時換臉,老師都不認識我了!!
使用dlib的shape_predictor_68_face_landmarks.dat模型獲取一張有正臉的圖片(1.png)和攝像頭的自己的68個人臉特徵點。
根據人臉特徵點獲取分別獲取人臉掩模
對第一個圖片仿射變換使其臉部對準攝像頭圖片中的臉部得到新的圖片
對人臉掩模執行相同的操作仿射
將兩個性的得到圖取並集(不能讓別的地方空了)
用opencv對兩上面操作,對仿射變換後的a圖片和攝像頭圖片進行泊松融合
# -*- coding: utf-8 -*- import cv2 import dlib import numpy as np detector = dlib.get_frontal_face_detector() # dlib的正向人臉檢測器 predictor = dlib.shape_predictor(r'shape_predictor_68_face_landmarks.dat') # dlib的人臉形狀檢測器 def get_image_size(image): """ 獲取圖片大小(高度,寬度) :param image: image :return: (高度,寬度) """ image_size = (image.shape[0], image.shape[1]) return image_size def get_face_landmarks(image, face_detector, shape_predictor): """ 獲取人臉標誌,68個特徵點 :param image: image :param face_detector: dlib.get_frontal_face_detector :param shape_predictor: dlib.shape_predictor :return: np.array([[],[]]), 68個特徵點 """ dets = face_detector(image, 1) shape = shape_predictor(image, dets[0]) face_landmarks = np.array([[p.x, p.y] for p in shape.parts()]) return face_landmarks def get_face_mask(image_size, face_landmarks): """ 獲取人臉掩模 :param image_size: 圖片大小 :param face_landmarks: 68個特徵點 :return: image_mask, 掩模圖片 """ mask = np.zeros(image_size, dtype=np.uint8) points = np.concatenate([face_landmarks[0:16], face_landmarks[26:17:-1]]) cv2.fillPoly(img=mask, pts=[points], color=255) return mask def get_affine_image(image1, image2, face_landmarks1, face_landmarks2): """ 獲取圖片1仿射變換後的圖片 :param image1: 圖片1, 要進行仿射變換的圖片 :param image2: 圖片2, 只要用來獲取圖片大小,生成與之大小相同的仿射變換圖片 :param face_landmarks1: 圖片1的人臉特徵點 :param face_landmarks2: 圖片2的人臉特徵點 :return: 仿射變換後的圖片 """ three_points_index = [18, 8, 25] M = cv2.getAffineTransform(face_landmarks1[three_points_index].astype(np.float32), face_landmarks2[three_points_index].astype(np.float32)) dsize = (image2.shape[1], image2.shape[0]) affine_image = cv2.warpAffine(image1, M, dsize) return affine_image.astype(np.uint8) def get_mask_center_point(image_mask): """ 獲取掩模的中心點座標 :param image_mask: 掩模圖片 :return: 掩模中心 """ image_mask_index = np.argwhere(image_mask > 0) miny, minx = np.min(image_mask_index, axis=0) maxy, maxx = np.max(image_mask_index, axis=0) center_point = ((maxx + minx) // 2, (maxy + miny) // 2) return center_point def get_mask_union(mask1, mask2): """ 獲取兩個掩模掩蓋部分的並集 :param mask1: mask_image, 掩模1 :param mask2: mask_image, 掩模2 :return: 兩個掩模掩蓋部分的並集 """ mask = np.min([mask1, mask2], axis=0) # 掩蓋部分並集 mask = ((cv2.blur(mask, (5, 5)) == 255) * 255).astype(np.uint8) # 縮小掩模大小 mask = cv2.blur(mask, (3, 3)).astype(np.uint8) # 模糊掩模 return mask def skin_color_adjustment(im1, im2, mask=None): """ 膚色調整 :param im1: 圖片1 :param im2: 圖片2 :param mask: 人臉 mask. 如果存在,使用人臉部分均值來求膚色變換系數;否則,使用高斯模糊來求膚色變換系數 :return: 根據圖片2的顏色調整的圖片1 """ if mask is None: im1_ksize = 55 im2_ksize = 55 im1_factor = cv2.GaussianBlur(im1, (im1_ksize, im1_ksize), 0).astype(np.float) im2_factor = cv2.GaussianBlur(im2, (im2_ksize, im2_ksize), 0).astype(np.float) else: im1_face_image = cv2.bitwise_and(im1, im1, mask=mask) im2_face_image = cv2.bitwise_and(im2, im2, mask=mask) im1_factor = np.mean(im1_face_image, axis=(0, 1)) im2_factor = np.mean(im2_face_image, axis=(0, 1)) im1 = np.clip((im1.astype(np.float) * im2_factor / np.clip(im1_factor, 1e-6, None)), 0, 255).astype(np.uint8) return im1 def main(): im1 = cv2.imread('1.png') # face_image im1 = cv2.resize(im1, (600, im1.shape[0] * 600 // im1.shape[1])) landmarks1 = get_face_landmarks(im1, detector, predictor) # 68_face_landmarks if landmarks1 is None: print('{}:檢測不到人臉'.format(image_face_path)) exit(1) im1_size = get_image_size(im1) # 臉圖大小 im1_mask = get_face_mask(im1_size, landmarks1) # 臉圖人臉掩模 cam = cv2.VideoCapture(0) while True: ret_val, im2 = cam.read() # camera_image landmarks2 = get_face_landmarks(im2, detector, predictor) # 68_face_landmarks if landmarks2 is not None: im2_size = get_image_size(im2) # 攝像頭圖片大小 im2_mask = get_face_mask(im2_size, landmarks2) # 攝像頭圖片人臉掩模 affine_im1 = get_affine_image(im1, im2, landmarks1, landmarks2) # im1(臉圖)仿射變換後的圖片 affine_im1_mask = get_affine_image(im1_mask, im2, landmarks1, landmarks2) # im1(臉圖)仿射變換後的圖片的人臉掩模 union_mask = get_mask_union(im2_mask, affine_im1_mask) # 掩模合併 affine_im1 = skin_color_adjustment(affine_im1, im2, mask=union_mask) # 膚色調整 point = get_mask_center_point(affine_im1_mask) # im1(臉圖)仿射變換後的圖片的人臉掩模的中心點 seamless_im = cv2.seamlessClone(affine_im1, im2, mask=union_mask, p=point, flags=cv2.NORMAL_CLONE) # 進行泊松融合 cv2.imshow('seamless_im', seamless_im) else: cv2.imshow('seamless_im', im2) if cv2.waitKey(1) == 27: # 按Esc退出 break cv2.destroyAllWindows() if __name__ == '__main__': main()
到此這篇關於Python實現攝像頭實時換臉詳解的文章就介紹到這了,更多相關Python實時換臉內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45