python:faces swap

# encoding: utf-8
# 版权所有 2024 涂聚文有限公司
# 许可信息查看:pip install boost
# 描述:pip install boost
# pip install dlib
# pip install cmake==3.25.2
# pip install dlib==19.24.2  如果安装不上,按此法
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : PyCharm 2023.1 python 3.11
# Datetime  : 2024/6/13 22:09
# User      : geovindu
# Product   : PyCharm
# Project   : pyBaiduAi
# File      : FaceSwaFun.py
# explain   : 学习
import cv2
import numpy as np
import dlib
from PIL import Image as imclass FaceSwaFun(object):"""换脸类"""def __init__(self, SOURCEPATH, DESTPATH):"""实例化:param SOURCEPATH: 需要用脸的图片:param DESTPATH: 用脸目标图片"""self.SOURCE_PATH = SOURCEPATHself.DEST_PATH = DESTPATHdef index_from_array(self, numpyarray):""":param numpyarray::return:"""index = Nonefor n in numpyarray[0]:index = nbreakreturn indexdef getImage(self) -> tuple:""":return: 返回 (图片的数组,保存的文件名)"""frontal_face_detector = dlib.get_frontal_face_detector()frontal_face_predictor = dlib.shape_predictor("dataset/shape_predictor_68_face_landmarks.dat")source_image = cv2.imread(self.SOURCE_PATH)source_image_grayscale = cv2.cvtColor(source_image, cv2.COLOR_BGR2GRAY)#destination_image = cv2.imread(self.DEST_PATH)destination_image_grayscale = cv2.cvtColor(destination_image, cv2.COLOR_BGR2GRAY)source_image_canvas = np.zeros_like(source_image_grayscale)height, width, no_of_channels = destination_image.shapedestination_image_canvas = np.zeros((height, width, no_of_channels), np.uint8)source_faces = frontal_face_detector(source_image_grayscale)# Obtaining source face landmark points, convex hull, creating mask and also getting delaunay triangle face landmark indices for every facefor source_face in source_faces:source_face_landmarks = frontal_face_predictor(source_image_grayscale, source_face)source_face_landmark_points = []for landmark_no in range(68):x_point = source_face_landmarks.part(landmark_no).xy_point = source_face_landmarks.part(landmark_no).ysource_face_landmark_points.append((x_point, y_point))source_face_landmark_points_array = np.array(source_face_landmark_points, np.int32)source_face_convexhull = cv2.convexHull(source_face_landmark_points_array)cv2.fillConvexPoly(source_image_canvas, source_face_convexhull, 255)source_face_image = cv2.bitwise_and(source_image, source_image, mask=source_image_canvas)# DELAUNAY TRIANGULATIONbounding_rectangle = cv2.boundingRect(source_face_convexhull)subdivisions = cv2.Subdiv2D(bounding_rectangle)subdivisions.insert(source_face_landmark_points)triangles_vector = subdivisions.getTriangleList()triangles_array = np.array(triangles_vector, dtype=np.int32)triangle_landmark_points_list = []source_face_image_copy = source_face_image.copy()for triangle in triangles_array:index_point_1 = (triangle[0], triangle[1])index_point_2 = (triangle[2], triangle[3])index_point_3 = (triangle[4], triangle[5])index_1 = np.where((source_face_landmark_points_array == index_point_1).all(axis=1))index_1 = self.index_from_array(index_1)index_2 = np.where((source_face_landmark_points_array == index_point_2).all(axis=1))index_2 = self.index_from_array(index_2)index_3 = np.where((source_face_landmark_points_array == index_point_3).all(axis=1))index_3 = self.index_from_array(index_3)triangle = [index_1, index_2, index_3]triangle_landmark_points_list.append(triangle)destination_faces = frontal_face_detector(destination_image_grayscale)# Obtaining destination face landmark points and also convex hull for every facefor destination_face in destination_faces:destination_face_landmarks = frontal_face_predictor(destination_image_grayscale, destination_face)destination_face_landmark_points = []for landmark_no in range(68):x_point = destination_face_landmarks.part(landmark_no).xy_point = destination_face_landmarks.part(landmark_no).ydestination_face_landmark_points.append((x_point, y_point))destination_face_landmark_points_array = np.array(destination_face_landmark_points, np.int32)destination_face_convexhull = cv2.convexHull(destination_face_landmark_points_array)# Iterating through all source delaunay triangle and superimposing source triangles in empty destination canvas after warping to same size as destination triangles' shapefor i, triangle_index_points in enumerate(triangle_landmark_points_list):# Cropping source triangle's bounding rectanglesource_triangle_point_1 = source_face_landmark_points[triangle_index_points[0]]source_triangle_point_2 = source_face_landmark_points[triangle_index_points[1]]source_triangle_point_3 = source_face_landmark_points[triangle_index_points[2]]source_triangle = np.array([source_triangle_point_1, source_triangle_point_2, source_triangle_point_3],np.int32)source_rectangle = cv2.boundingRect(source_triangle)(x, y, w, h) = source_rectanglecropped_source_rectangle = source_image[y:y + h, x:x + w]source_triangle_points = np.array([[source_triangle_point_1[0] - x, source_triangle_point_1[1] - y],[source_triangle_point_2[0] - x, source_triangle_point_2[1] - y],[source_triangle_point_3[0] - x, source_triangle_point_3[1] - y]],np.int32)# Create a mask using cropped destination triangle's bounding rectangle(for same landmark points as used for source triangle)destination_triangle_point_1 = destination_face_landmark_points[triangle_index_points[0]]destination_triangle_point_2 = destination_face_landmark_points[triangle_index_points[1]]destination_triangle_point_3 = destination_face_landmark_points[triangle_index_points[2]]destination_triangle = np.array([destination_triangle_point_1, destination_triangle_point_2, destination_triangle_point_3], np.int32)destination_rectangle = cv2.boundingRect(destination_triangle)(x, y, w, h) = destination_rectanglecropped_destination_rectangle_mask = np.zeros((h, w), np.uint8)destination_triangle_points = np.array([[destination_triangle_point_1[0] - x, destination_triangle_point_1[1] - y],[destination_triangle_point_2[0] - x, destination_triangle_point_2[1] - y],[destination_triangle_point_3[0] - x, destination_triangle_point_3[1] - y]],np.int32)cv2.fillConvexPoly(cropped_destination_rectangle_mask, destination_triangle_points, 255)# Warp source triangle to match shape of destination triangle and put it over destination triangle masksource_triangle_points = np.float32(source_triangle_points)destination_triangle_points = np.float32(destination_triangle_points)matrix = cv2.getAffineTransform(source_triangle_points, destination_triangle_points)warped_rectangle = cv2.warpAffine(cropped_source_rectangle, matrix, (w, h))warped_triangle = cv2.bitwise_and(warped_rectangle, warped_rectangle,mask=cropped_destination_rectangle_mask)# Reconstructing destination face in empty canvas of destination image# removing white lines in triangle using maskingnew_dest_face_canvas_area = destination_image_canvas[y:y + h, x:x + w]new_dest_face_canvas_area_gray = cv2.cvtColor(new_dest_face_canvas_area, cv2.COLOR_BGR2GRAY)_, mask_created_triangle = cv2.threshold(new_dest_face_canvas_area_gray, 1, 255, cv2.THRESH_BINARY_INV)warped_triangle = cv2.bitwise_and(warped_triangle, warped_triangle, mask=mask_created_triangle)new_dest_face_canvas_area = cv2.add(new_dest_face_canvas_area, warped_triangle)destination_image_canvas[y:y + h, x:x + w] = new_dest_face_canvas_area# Put reconstructed face on the destination imagefinal_destination_canvas = np.zeros_like(destination_image_grayscale)final_destination_face_mask = cv2.fillConvexPoly(final_destination_canvas, destination_face_convexhull, 255)final_destination_canvas = cv2.bitwise_not(final_destination_face_mask)destination_face_masked = cv2.bitwise_and(destination_image, destination_image, mask=final_destination_canvas)destination_with_face = cv2.add(destination_face_masked, destination_image_canvas)# Seamless cloning to make attachment blend with surrounding pixels# we have to find center point of reconstructed convex hull to pass into seamlessClone()(x, y, w, h) = cv2.boundingRect(destination_face_convexhull)destination_face_center_point = (int((x + x + w) / 2), int((y + y + h) / 2))seamless_cloned_face = cv2.seamlessClone(destination_with_face, destination_image, final_destination_face_mask,destination_face_center_point, cv2.NORMAL_CLONE)data = im.fromarray(seamless_cloned_face)# saving the final output# as a PNG filefile = 'geovindu.png'data.save(file)# cv2.imshow("Destination image with source face 2", seamless_cloned_face)# cv2.waitKey(0)# cv2.destroyAllWindows()print(type(seamless_cloned_face))return (seamless_cloned_face, file)'''1.import cv2cv2.imwrite("geovindu.jpg", seamless_cloned_face)2.from PIL import Imageim = Image.fromarray(seamless_cloned_face)im.save("geovindu.jpg")3.import scipy.miscscipy.misc.imsave('geovindu.jpg', seamless_cloned_face)4.import scipy.miscscipy.misc.toimage(seamless_cloned_face, cmin=0.0, cmax=...).save('geovindu.jpg')5.import matplotlibmatplotlib.image.imsave('geovindu.png', seamless_cloned_face)'''

調用:

# 调用du= BLL.imageFaceSwapFun.FaceSwaFun("media/images/modi.jpg","media/images/viplav.jpeg")#du.SOURCE_PATH="media/images/modi.jpg"# du.DEST_PATH="media/images/viplav.jpeg"geovindu=du.getImage()print(geovindu)cv2.imwrite("geovindu20.png", geovindu[0])

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/26825.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

实用软件下载:MathType最新安装包及详细安装教程

MathType是强大的数学公式编辑器,与常见的文字处理软件和演示程序配合使用,能够在各种文档中加入复杂的数学公式和符号,可用在编辑数学试卷、书籍、报刊、论文、幻灯演示等方面,是编辑数学资料的得力工具。MathType与常见文字处理…

【乐吾乐2D可视化组态编辑器】条件变化,触发告警动画

条件触发告警动画 乐吾乐2D可视化组态编辑器地址:https://2d.le5le.com/ 如图所示,左侧文本图元数值一直在变化,当数值大于等于50的时候,右侧矩形图元执行告警动画,当数值小于50的时候,右侧图元恢复正常。…

Java--数组小结

1.其长度是确定的。数组一旦被创建,它的大小就是不可以改变的。 2.其元素必须是相同类型,不允许出现混合类型 3.数组中的元素可以是任何数据类型,包括基本类型和引用类型 4.数组变量属于引用类型,数组也可以看成是对象&#xf…

Aspose将doc,ppt转成pdf

1.需要引入的jar包 链接: https://pan.baidu.com/s/1t3wqq7KrHi50K9KX3-Eb9A?pwd=u4se 提取码: u4se <dependency><groupId>com.aspose</groupId><artifactId>aspose-words-jdk16</artifactId><version>15.8.0</version><sco…

【Spring EL<二>✈️✈️ 】SL 表达式结合 AOP 注解实现鉴权

目录 &#x1f37b;前言 &#x1f378;一、鉴权&#xff08;Authorization&#xff09; &#x1f37a;二、功能实现 2.1 环境准备 2.2 代码实现 2.3 测试接口 &#x1f379;三、测试功能 3.1 传递 admin 请求 ​ 3.2 传递普通 user 请求 &#x1f37b;四、章末 &a…

Arduino 项目:太阳能跟踪器

在本文中&#xff0c;您将逐步学习如何使用 光敏电阻和舵机制作双轴太阳能跟踪器 Arduino 项目。在这个项目中&#xff0c;我们将使用一些光敏传感器来跟踪阳光&#xff0c;并将利用舵机将太阳能电池板引导到可提高其效率的区域。 此项目所需的组件 序号部件名称描述数量备注…

Excel根据身份证号提取信息

概览 本篇文章主要对根据身份证号码提取出生年月日、年龄、性别、退休年龄这三项进行讲解。 一. 提取出生年月日 公式&#xff1a;TEXT(MID(B2,7,8),“0000-00-00”) MID(B2,7,8)&#xff1a;表示从单元格 B2 中的字符串&#xff08;这里是身份证号&#xff09;&#xff0c…

《web应用技术》第十一次作业

1、验证过滤器进行权限验证的原理。 代码展示&#xff1a; Slf4j WebFilter(urlPatterns "/*") public class LoginCheckFilter implements Filter { Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) thro…

未来工作场所:数字化转型的无限可能

探索技术如何重塑我们的工作环境与协作方式 引言 在21世纪的第三个十年&#xff0c;数字化转型已不再仅仅是科技公司的专利&#xff0c;它如同一股不可阻挡的潮流&#xff0c;深刻地渗透到了每一个行业的血脉之中。从灵活的远程办公模式到工作流程的智能化重构&#xff0c;技术…

Java高级技术探索:深入理解JVM内存分区与GC机制

文章目录 引言JVM内存分区概览垃圾回收机制&#xff08;GC&#xff09;GC算法基础常见垃圾回收器ParNew /Serial old 收集器运行示意图 优化实践结语 引言 Java作为一门广泛应用于企业级开发的编程语言&#xff0c;其背后的Java虚拟机&#xff08;JVM&#xff09;扮演着至关重…

html的网页制作代码分享

<!-- prj_8_2.html --> <!DOCTYPE html> <html lang "EN"><head><meta charset"utf-8" /><title>页面布局设计</title><style type "text/css">*{padding: 0px;margin:0px;}#header{back…

Web端在线/离线Stomp服务测试与WebSocket服务测试

Stomp服务测试 支持连接、发送、订阅、接收&#xff0c;可设置请求头、自动重连 低配置云服务器&#xff0c;首次加载速度较慢&#xff0c;请耐心等候 预览页面&#xff1a;http://www.daelui.com/#/tigerlair/saas/preview/lxbho9lkzvgc 演练页面&#xff1a;http://www.da…

11_从注意力机制到序列处理的革命:Transformer原理详解

1.1 简介 Transformer是一种深度学习模型&#xff0c;主要用于处理序列数据&#xff0c;尤其是自然语言处理任务&#xff0c;如机器翻译、文本摘要等。该模型由Vaswani等人在2017年的论文《Attention is All You Need》中首次提出&#xff0c;它的出现极大地推动了自然语言处理…

【推荐算法的评估与调试】离线评估+在线A/B Test

文章目录 1、离线评估1.1、评估排序算法1.1.1、AUC和GAUC1.1.2、NDCG 1.2、评估召回算法1.2.1、Precision&Recall1.2.2、MAP1.2.3、Hit Rate1.2.4、持续评估 2、在线评估2.1、线上&#xff1a;流量划分2.1.1、根据User ID划分流量2.1.2、分层重叠划分流量2.1.3、A/A实验的重…

没那么简单!浅析伦敦金与美元的关系

伦敦金价与美元的关系可以被比喻为跷跷板的两端&#xff0c;它们的价格走势往往呈现出此消彼长的关系&#xff1a;当美元表现强势的时候&#xff0c;伦敦金的价格可能承受到压力&#xff1b;相反&#xff0c;当美元疲软时&#xff0c;黄金往往会成为避险资产&#xff0c;令伦敦…

YOLOv10涨点改进|引入BoTNet结构与CA注意力机制,打造高效轻量级检测器

📚 专栏地址:《YOLOv10算法改进实战》 👉 独家改进,对现有YOLOv10进行二次创新,提升检测精度,适合科研创新度十足,强烈推荐 🌟 统一使用 YOLOv10 代码框架,结合不同模块来构建不同的YOLO目标检测模型。 💥 本博客包含大量的改进方式,降低改进难度,改进点包含【B…

数据结构(一):绪论——数据结构基本概念真题

1&#xff1a;&#xff08;2017暨南大学&#xff09;计算机内部数据处理的基本单元是&#xff08;B&#xff09; A&#xff1a;数据 B&#xff1a;数据元素 C&#xff1a;数据项 D&#xff1a;数据库 解析&#xff1a;计算机内部数据处理的基本单元是数据…

安装操作系统1-Win10版本介绍及硬件要求

注意&#xff1a;安装系统&#xff0c;首先弄清有哪些版本及所需硬件环境。 1.Win10有哪些版本 微软将 Win10为以下7个版本&#xff1a; Windows 10 家庭版&#xff08;Home&#xff09; 面向所有普通用户&#xff0c;提供Win 10的基本功能。此版本适合个人家庭用户使用&am…

6-7 最大子段和(分治法)

6-7 最大子段和&#xff08;分治法&#xff09; 分数 15 全屏浏览 作者 王东 单位 贵州师范学院 最大子段和问题。给定由n个整数组成的序列&#xff0c;求序列中子段的最大和&#xff0c;若所有整数均为负整数时定义最大子段和为0。 函数接口定义&#xff1a; long long …

Qt 焦点系统关键点总结

1.1 焦点窗口 指的是当前时刻拥有键盘输入的窗口。 Qt提供了如下接口&#xff0c;用于设置窗口是否是”可获取焦点“窗口&#xff1a; void QWidget::setFocusPolicy(Qt::FocusPolicy policy); Qt::FocusPolicy Qt::TabFocus 与焦点链相关&#xff0c;详解见下一…