当前位置: 首页 > news >正文

python:faces swap

# encoding: utf-8
# 版权所有 2024 ©涂聚文有限公司
# 许可信息查看: 两个头像图片之间换脸
# 描述: https://stackoverflow.com/questions/902761/saving-a-numpy-array-as-an-image?answertab=votes
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : PyCharm 2023.1 python 311
# Datetime  : 2024/6/13 10:25
# User      : geovindu
# Product   : PyCharm
# Project   : EssentialAlgorithms
# File      : imageFaceSwapFun.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])

相关文章:

python:faces swap

# encoding: utf-8 # 版权所有 2024 ©涂聚文有限公司 # 许可信息查看: 两个头像图片之间换脸 # 描述: https://stackoverflow.com/questions/902761/saving-a-numpy-array-as-an-image?answertabvotes # Author : geovindu,Geovin Du 涂聚文. #…...

Android开发之音乐播放器添加排行需求

Music统计功能需求 1.记录歌曲名称与次数(歌曲播放结束算一次),根据播放次数制作一个排行列表;(开始说要记录歌手,后面debug发现这个字段没有,暂时不记录) 2.记录播放歌曲的时长,时间累加;&…...

latex 方括号编号

最近在做简历,需要列出发表的论文。 论文编号一般是采用[1]这种样式,但是找了几个简历模板里头没有直接包含这种编号样式。 我只好求助网络。 在CSDN上找了一圈,这篇博客给了一个思路:在\begin{enumerate}后面添加对应的样式即…...

Vue CLI 4与项目构建实战指南

title: Vue CLI 4与项目构建实战指南 date: 2024/6/9 updated: 2024/6/9 excerpt: 这篇文章介绍了如何使用Vue CLI优化项目构建配置,提高开发效率,涉及配置管理、项目部署策略、插件系统定制以及Webpack和TypeScript的深度集成技巧。 categories: 前端…...

深入解析Web通信 HTTP、HTTPS 和 WebSocket

在现代Web开发中,了解和掌握HTTP、HTTPS以及WebSocket协议是非常重要的。这些协议是实现Web应用程序之间通信的基石。本文将详细介绍这三种协议,包括它们的基本概念、工作原理、优缺点以及适用场景。通过深入解析它们的特点和应用,帮助读者更好地理解和使用这些协议。 一、…...

FISCO BCOS x GitLink,为国产开源技术生态注入新活力

作为中国领先的区块链底层平台之一,FISCO BCOS 自成立以来始终致力于推动国产开源区块链技术的应用和普及。近期,FISCO BCOS 将开源代码托管到CCF官方代码托管平台 GitLink (确实开源),为国产开源技术生态注入新活力。…...

Linux crontabs定时执行任务

文章目录 前言一、安装二、服务1. 启动crond服务2. 关闭crond服务3. 重启crond服务4. 设置crond开机启动5. 禁用crond开机启动6. 查看crond是否开机启动7. 重新载入配置8. 查看crond运行状态 三、使用1. 查看当前用户的crontab2. 编辑用户的crontab3. 删除用户的crontab的内容 …...

QNX简述

文章目录 前言1. QNX简介1.1 什么是QNX1.2 QNX的应用场景1.3 QNX的优点1.4 QNX的发展史1.5 QNX的商业模式 2. QNX的技术特点3. QNX和其它操作系统的比较3.1 QNX VS LINUX3.2 QNX VS FreeRTOS3.3 QNX VS 鸿蒙操作系统 4. 我的疑问4.1 微内核看起来又稳定又容易调试,为…...

[Llama3] ReAct Prompt 测试实验

ReAct 是一种 LLM 提示和结果处理方法,结合了推理、行动计划和知识源整合,使 LLM 超越其语言模型,并在预测中使用来自现实世界的信息。 ReAct 是推理和行动的结合。 介绍 ReAct 的论文表明它比思维链提示更好。与后者不同的是,Re…...

nodejs 某音douyin网页端搜索接口及x_bogus、a_bogus(包含完整源码)(2024-06-13)

前言 x_bogus或a_bogus算法大概是对数据、ua、时间戳、浏览器的几个指纹进行计算,拿到一个110位大数组,然后转字符,在头部再添加十二位随机字符,再进行魔改的base64加密。 问:抖音的x_bogus、a_bogus值有什么用&#x…...

继承深度剖析

前言 从继承开始就开始C进阶了, 这一块需要好好学习,这块知识很重要, 坑有点多,所以是面试笔试的常客。 基本概念 继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段, 它允许程序员在保持原有…...

使用 Vue 和 Ant Design 实现抽屉效果的模块折叠功能

功能描述: 有两个模块,点击上面模块的收起按钮时,上面的模块可以折叠,下面的模块随之扩展 代码实现: 我们在 Vue 组件中定义两个模块的布局和状态管理: const scrollTableY ref(560); // 表格初始高度…...

Springboot整合SpringCache+redis简化缓存开发

使用步骤&#xff1a; 1.引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId> </dependency><dependency><groupId>org.springframework.boot</groupI…...

关于EOF标识符

EOF的概念 EOF是C语言中表示文件结束的标志符号&#xff0c;通常被定义为-1&#xff0c;它用于指示已到达文件的末尾或输入流的末尾。 EOF的使用 在输入操作中&#xff0c;EOF常常用于判断是否到达了文件末尾或输入流末尾&#xff0c;以便终止读取操作。例如&#xff0c;在使…...

家用洗地机排行榜前十名:2024十大王牌机型精准种草

最近很多人都在问我洗地机相关的问题&#xff0c;不愧是改善家庭生活品质的“三神器”之一。洗地机依靠其清洁力和清洁效率吸引了越来越多的平时需要做家务人群的兴趣&#xff0c;为了解答大家关于洗地机的各种疑问&#xff0c;我把市面上目前非常火爆的洗地机型号和参数都进行…...

【Chrome插件】如何在Chrome插件开发中处理复杂数据结构的存储

最近俺在接触 Chrome 插件开发&#xff0c;需要把一个数据存放到浏览器的存储中。这个数据结构有点复杂&#xff0c;它包含一个 Map 和一个数组。我使用 chrome.storage.local API来存储这个数据&#xff0c;然后在另一个地方获取数据。保存数据的代码并没有报错&#xff0c;但…...

MySQL 保姆级教程(二):使用 MySQL 检索数据

使用 MySQL 3.2 选择数据库 使用数据库: 输入: USE 数据库名;输出: Database changed分析: 不返回任何结果&#xff0c;显示某种形式的通知 ​ 例如: 使用 crashcourse 数据库 use crashcourse; 3.3 了解数据库和表 列出所有的数据库: 输入: SHOW DATABASES;输出: --------…...

Sui Bridge在测试网上线并推出10万SUI激励计划

是一种为Sui设计的原生桥接协议&#xff0c;专门用于在Sui与其他网络之间桥接资产和数据。今天&#xff0c;Sui Bridge宣布在测试网上线。作为一种原生协议&#xff0c;Sui Bridge能够在Ethereum和Sui之间轻松且安全地转移ETH、wBTC、USDC和USDT&#xff0c;使其成为Sui基础设施…...

Spring系统学习 - Bean的作用域

bean作用域介绍 Spring框架提供了不同的作用域来管理Bean的生命周期和可见性&#xff0c;这对于控制不同类型的组件和处理并发请求尤其重要。 singleton&#xff08;默认&#xff09;&#xff1a; 每个Spring IoC容器只有一个bean实例。当容器创建bean后&#xff0c;它会被缓存…...

贪吃蛇双人模式设计(2)

敲上瘾-CSDN博客控制台程序设置_c语言控制程序窗口大小-CSDN博客贪吃蛇小游戏_贪吃蛇小游戏csdn-CSDN博客 一、功能实现&#xff1a; 玩家1使用↓ → ← ↑按键来操作蛇的方向&#xff0c;使用右Shift键加速&#xff0c;右Ctrl键减速玩家2使用W A S D按键来操作蛇的方向&am…...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析

今天聊的内容&#xff0c;我认为是AI开发里面非常重要的内容。它在AI开发里无处不在&#xff0c;当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗"&#xff0c;或者让翻译模型 "将这段合同翻译成商务日语" 时&#xff0c;输入的这句话就是 Prompt。…...

Matlab | matlab常用命令总结

常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...

《基于Apache Flink的流处理》笔记

思维导图 1-3 章 4-7章 8-11 章 参考资料 源码&#xff1a; https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...

大学生职业发展与就业创业指导教学评价

这里是引用 作为软工2203/2204班的学生&#xff0c;我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要&#xff0c;而您认真负责的教学态度&#xff0c;让课程的每一部分都充满了实用价值。 尤其让我…...

Spring数据访问模块设计

前面我们已经完成了IoC和web模块的设计&#xff0c;聪明的码友立马就知道了&#xff0c;该到数据访问模块了&#xff0c;要不就这俩玩个6啊&#xff0c;查库势在必行&#xff0c;至此&#xff0c;它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据&#xff08;数据库、No…...

Netty从入门到进阶(二)

二、Netty入门 1. 概述 1.1 Netty是什么 Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty是一个异步的、基于事件驱动的网络应用框架&#xff0c;用于…...

淘宝扭蛋机小程序系统开发:打造互动性强的购物平台

淘宝扭蛋机小程序系统的开发&#xff0c;旨在打造一个互动性强的购物平台&#xff0c;让用户在购物的同时&#xff0c;能够享受到更多的乐趣和惊喜。 淘宝扭蛋机小程序系统拥有丰富的互动功能。用户可以通过虚拟摇杆操作扭蛋机&#xff0c;实现旋转、抽拉等动作&#xff0c;增…...

[论文阅读]TrustRAG: Enhancing Robustness and Trustworthiness in RAG

TrustRAG: Enhancing Robustness and Trustworthiness in RAG [2501.00879] TrustRAG: Enhancing Robustness and Trustworthiness in Retrieval-Augmented Generation 代码&#xff1a;HuichiZhou/TrustRAG: Code for "TrustRAG: Enhancing Robustness and Trustworthin…...

加密通信 + 行为分析:运营商行业安全防御体系重构

在数字经济蓬勃发展的时代&#xff0c;运营商作为信息通信网络的核心枢纽&#xff0c;承载着海量用户数据与关键业务传输&#xff0c;其安全防御体系的可靠性直接关乎国家安全、社会稳定与企业发展。随着网络攻击手段的不断升级&#xff0c;传统安全防护体系逐渐暴露出局限性&a…...

解析“道作为序位生成器”的核心原理

解析“道作为序位生成器”的核心原理 以下完整展开道函数的零点调控机制&#xff0c;重点解析"道作为序位生成器"的核心原理与实现框架&#xff1a; 一、道函数的零点调控机制 1. 道作为序位生成器 道在认知坐标系$(x_{\text{物}}, y_{\text{意}}, z_{\text{文}}…...