《计算机视觉》—— 换脸
- 效果如下:
- 完整代码:
import cv2
import dlib
import numpy as npJAW_POINTS = list(range(0, 17))
RIGHT_BROW_POINTS = list(range(17, 22))
LEFT_BROW_POINTS = list(range(22, 27))
NOSE_POINTS = list(range(27, 35))
RIGHT_EYE_POINTS = list(range(36, 42))
LEFT_EYE_POINTS = list(range(42, 48))
MOUTH_POINTS = list(range(48, 61))
FACE_POINTS = list(range(17, 68))# 关键点集
POINTS = [LEFT_BROW_POINTS + RIGHT_EYE_POINTS +LEFT_EYE_POINTS + RIGHT_BROW_POINTS + NOSE_POINTS + MOUTH_POINTS]# 处理为元组,后续使用方便
POINTStuple = tuple(POINTS)def getFaceMask(im, keyPoints): # 根据关键点获取脸部掩膜im = np.zeros(im.shape[:2], dtype=np.float64)for p in POINTS:points = cv2.convexHull(keyPoints[p]) # 获取凸包cv2.fillConvexPoly(im, points, color=1) # 填充凸包,数字在0~1之间# 单通道im构成3通道im(3,行,列),改变形状(行、列、3)适应0penCVim = np.array([im, im, im]).transpose((1, 2, 0))im = cv2.GaussianBlur(im, (25, 25), 0) # 需要根据具体调整return im""" 求出b脸仿射变换到a脸的变换矩阵M,此处用到的算法难以理解,大家可直接跳过 """def getM(points1, points2):points1 = points1.astype(np.float64) # int8转换为浮点数类型points2 = points2.astype(np.float64) # 转换为浮点数类型c1 = np.mean(points1, axis=0) # 归一化:(数值-均值)/标准差c2 = np.mean(points2, axis=0) # 归一化:(数值-均值)/标准差,均值不同,主要是脸五官位置大小不同points1 -= c1 # 减去均值points2 -= c2 # 减去均值s1 = np.std(points1) # 方差计算标准差s2 = np.std(points2) # 方差计算标准差points1 /= s1 # 除标准差,计算出归一化的结果points2 /= s2 # 除标准差,计算出归一化的结果# 奇异值分解,Singular Value DecompositionU, S, Vt = np.linalg.svd(points1.T * points2)R = (U * Vt).T # 通过U和Vt找到Rreturn np.hstack(((s2 / s1) * R, c2.T - (s2 / s1) * R * c1.T))def getKeyPoints(im): # 获取关键点rects = detector(im, 1) # 获取人脸方框位置shape = predictor(im, rects[0]) # 获取关键点s = np.matrix([[p.x, p.y] for p in shape.parts()])return s""" 修改b图的颜色值,与a图相同 """
def normalColor(a, b):ksize = (111, 111) #非常大的核,去噪等运算时为11就比较大了aGauss = cv2.GaussianBlur(a, ksize, 0) # 对a进行高斯滤波bGauss = cv2.GaussianBlur(b, ksize, 0) # 对b进行高斯滤波weight = aGauss / bGauss # 计算目标图像调整颜色的权重值,存在0除警告,可忽略。where_are_inf = np.isinf(weight)weight[where_are_inf] = 0return b * weighta = cv2.imread("dlrb_3.jpg") # 换脸A图片
b = cv2.imread("zly.jpg") # 换脸B图片detector = dlib.get_frontal_face_detector() # 构造脸部位置检测器
predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat") # 获取人脸关键点定位模型aKeyPoints = getKeyPoints(a) # 获取A图片的68关键点
bKeyPoints = getKeyPoints(b) # 获取B图片的68关键点bOriginal = b.copy() # 不对原来的图片b进行破坏和修改aMask = getFaceMask(a, aKeyPoints) # 获取图片A的人脸掩膜
cv2.imshow('aMask', aMask)
cv2.waitKey()bMask = getFaceMask(b, bKeyPoints) # 获取图片B的人脸掩膜
cv2.imshow('bMask', bMask)
cv2.waitKey()"""求出b脸仿射变换到a脸的变换矩阵M"""
M = getM(aKeyPoints[POINTStuple], bKeyPoints[POINTStuple])"""将b的脸部(bmask)根据M仿射变换到a上"""
dsize = a.shape[:2][::-1]
# 目标输出与图像a大小一致
# 需要注意,shape是(行、列),warpAffine参数dsize是(列、行)
# 使用a.shape[:2][::-1],获取a的(列、行)# 函数warpAffine(src,M,dsize,dst=None, flags=None, borderMode=None, borderValue=None)
# src:输入图像
# M:运算矩阵,2行3列的,
# dsize:运算后矩阵的大小,也就是输出图片的尺寸
# dst:输出图像
# flags:插值方法的组合,与resize函数中的插值一样,可以查看cv2.resize
# borderMode:边界模式,BORDER_TRANSPARENT表示边界透明
# borderValue:在恒定边框的情况下使用的borderValue值;默认情况下,它是 0
bMaskWarp = cv2.warpAffine(bMask, M, dsize, borderMode=cv2.BORDER_TRANSPARENT, flags=cv2.WARP_INVERSE_MAP)
cv2.imshow("bMaskWarp", bMaskWarp)
cv2.waitKey()"""获取脸部最大值(两个脸模板香加)"""
mask = np.max([aMask, bMaskWarp], axis=0)
cv2.imshow("mask", mask)
cv2.waitKey()""" 使用仿射矩阵M,将b映射到a """
bWrap = cv2.warpAffine(b, M, dsize, borderMode=cv2.BORDER_TRANSPARENT, flags=cv2.WARP_INVERSE_MAP)
cv2.imshow("bWrap", bWrap)
cv2.waitKey()""" 求b图片的仿射到图片a的颜色值,b的颜色值改为a的颜色 """
bcolor = normalColor(a, bWrap)
cv2.imshow("bcolor", bcolor)
cv2.waitKey()""" ===========step8:换脸(mask区域用bcolor,非mask区城用a)============= """
out = a * (1.0 - mask) + bcolor * mask# =========输出原始人脸、换脸结果===============
cv2.imshow("a", a)
cv2.imshow("b", bOriginal)
cv2.imshow("out", out/255)
cv2.waitKey()
cv2.destroyAllWindows()
相关文章:

《计算机视觉》—— 换脸
效果如下: 完整代码: import cv2 import dlib import numpy as npJAW_POINTS list(range(0, 17)) RIGHT_BROW_POINTS list(range(17, 22)) LEFT_BROW_POINTS list(range(22, 27)) NOSE_POINTS list(range(27, 35)) RIGHT_EYE_POINTS list(range(36…...

【JavaEE初阶】深入透析文件-IO关于文件内容的操作(四种文件流)
前言 🌟🌟本期讲解关于CAS的补充和JUC中有用的类,这里涉及到高频面试题哦~~~ 🌈上期博客在这里:【JavaEE初阶】文件-IO之实现文件系统的操作如何进行实现-CSDN博客 🌈感兴趣的小伙伴看一看小编主页&…...
复习:react 中的 refs,怎么使用,有哪些使用场景
在 React 中,refs(引用)是一个重要的特性,它允许开发者直接访问 DOM 元素或者 React 组件的实例。以下是对 React 中 refs 的使用及其使用场景的详细解释: 一、refs 的使用方法 字符串引用 在早期的 React 版本中,可以通过字符串来设置 ref。然而,这种方法已经被废弃,…...

Python OpenCV精讲系列 - 目标检测与识别深入理解(二十)
💖💖⚡️⚡️专栏:Python OpenCV精讲⚡️⚡️💖💖 本专栏聚焦于Python结合OpenCV库进行计算机视觉开发的专业教程。通过系统化的课程设计,从基础概念入手,逐步深入到图像处理、特征检测、物体识…...
golang中的上下文
背景 在Go语言中,使用context包来管理跨API和进程间的请求生命周期是常见的做法。特别是在涉及到并发编程时,如启动协程(goroutine)来处理异步任务,正确地传递和监听context变得尤为重要。比如,在gin框架中…...

Navigation2 算法流程
转自 https://zhuanlan.zhihu.com/p/405670882 此文仅作学习笔记 启动流程 在仿真环境中启动导航包的示例程序,执行nav2_bringup/bringup/launch/tb3_simulation_launch.py文件。ROS2的launch文件支持采用python语言来编写以支持更加复杂的功能,本文件…...
OpenAI swarm+ Ollama快速构建本地多智能体服务 - 1. 服务构建教程
OpenAI开源了多智能体编排的工程swarm,今天介绍一下swarm与OLLAMA如何结合使用的教程,在本地构建自己的多智能体服务,并给大家实践演示几个案例。 安装步骤 安装ollama,在官网下载对应操作系统的版本即可,下载后用ol…...
HTB:Wifinetic[WriteUP]
目录 连接至HTB并启动靶机 1.What is the name of the OpenWRT backup file accessible over FTP? 使用nmap对靶机21、22端口进行脚本、服务信息扫描 2.Whats the WiFi password for SSID OpenWRT? 3.Which user reused the WiFi password on thier local account? 4.…...

专业学习|马尔可夫链(概念、变体以及例题)
一、马尔可夫链的概念及组成 (一)学习资料分享 来源:024-一张图,但讲懂马尔可夫决策过程_哔哩哔哩_bilibili 马尔可夫链提供了一种建模随机过程的方法,具有广泛的应用。在实际问题中,通过转移概率矩阵及初…...
RK3576 安卓SDK编译环境搭建
编译 Android14 对机器的配置要求较高: 建议预留500G存储 多分配CPU和内存 建议使用 Ubuntu 20.04 操作系统或更高版本 sudo apt-get updatesudo apt-get install make gcc sudo apt-get install g++ patchelf gawk texinfo chrpath diffstat binfmt-support sudo apt-get …...

Renesas R7FA8D1BH (Cortex®-M85) 上光电编码器测速功能
目录 概述 1 软硬件 1.1 软硬件环境信息 1.2 开发板信息 1.3 调试器信息 2 硬件架构 2.1 硬件框架结构 2.2 测速功能原理介绍 2.2.1 理论描述 2.2.2 实现原理 2.2.3 系统硬件结构 3 软件实现 3.1 FSP配置项目 3.2 代码实现 3.2.1 初始化函数 3.2.2 功能函数 3.…...

软件测试学习笔记丨Linux三剑客-sed
本文转自测试人社区,原文链接:https://ceshiren.com/t/topic/32521 一、简介 sed(Stream editor)是一个功能强大的文本流编辑器,主要用于对文本进行处理和转换。它适用于自动化处理大量的文本数据,能够支持…...

Vue脚手架学习 vue脚手架配置代理、插槽、Vuex使用、路由、ElementUi插件库的使用
目录 1.vue脚手架配置代理 1.1 方法一 1.2 方法二 2.插槽 2.1 默认插槽 2.2 具名插槽 2.3 作用域插槽 3.Vuex 3.1 概念 3.2 何时使用? 3.3 搭建vuex环境 3.4 基本使用 3.5 getters的使用 3.6 四个map方法的使用 3.6.1 mapState方法 3.6.2 mapGetter…...
使用yml文件安装环境时,如何添加conda和pip的镜像源
博客参考 添加conda镜像源 name: NAME channels:- conda-forge- pytorch- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/msys2- defaults depende…...

c语言经典100例
1.字符串转为数字 #include <stdio.h>int strToInt(char *s) {int num0;int sign1;int step1;if (*s -){sign -1;s;}while (*s > 0&&*s < 9){num num*10(*s-0);step 10;s;}return num*sign; }int main() {char a[10] "-1234";char *s a ;pr…...

百易云资产管理运营系统 ufile.api.php SQL注入漏洞复现
0x01 产品描述: 百易云资产管理运营系统,是专门针对企业不动产资产管理和运营需求而设计的一套综合解决方案。该系统能够覆盖资产的全生命周期管理,包括资产的登记、盘点、评估、处置等多个环节,同时提供强大的运营分析功能&#…...
【分布式微服务云原生】《Redis RedLock 算法全解析:应对时钟漂移与网络分区挑战》
《Redis RedLock 算法全解析:应对时钟漂移与网络分区挑战》 摘要: 本文深入探讨 Redis 的 RedLock 算法,详细阐述其步骤及工作原理,同时重点分析该算法如何处理时钟漂移和网络分区这两个常见的分布式系统问题。读者将通过本文深入…...

OceanBase 的写盘与传统数据库有什么不同?
背景 在数据库开发过程中,“写盘”是一项核心操作,即将内存中暂存的数据安全地转储到磁盘上。在诸如MySQL这样的传统数据库管理系统中,写盘主要有以下几步:首先将数据写入缓存池;其次,为了确保数据的完整性…...

用Java爬虫API,轻松获取taobao商品SKU信息
在电子商务的世界里,SKU(Stock Keeping Unit,库存单位)是商品管理的基础。对于商家来说,SKU的详细信息对于库存管理、价格策略制定、市场分析等都有着重要作用。taobao作为中国最大的电子商务平台之一,提供…...

OpenHarmony 入门——ArkUI 自定义组件内同步的装饰器@State小结(二)
文章大纲 引言一、组件内状态装饰器State1、初始化2、使用规则3、变量的传递/访问规则说明4、支持的观察变化的场景5、State 变量的值初始化和更新机制6、State支持联合类型实例 引言 前一篇文章OpenHarmony 入门——ArkUI 自定义组件之间的状态装饰器小结(一&…...

stm32G473的flash模式是单bank还是双bank?
今天突然有人stm32G473的flash模式是单bank还是双bank?由于时间太久,我真忘记了。搜搜发现,还真有人和我一样。见下面的链接:https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...
React Native 导航系统实战(React Navigation)
导航系统实战(React Navigation) React Navigation 是 React Native 应用中最常用的导航库之一,它提供了多种导航模式,如堆栈导航(Stack Navigator)、标签导航(Tab Navigator)和抽屉…...

遍历 Map 类型集合的方法汇总
1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...

Debian系统简介
目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版ÿ…...
【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密
在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...

visual studio 2022更改主题为深色
visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中,选择 环境 -> 常规 ,将其中的颜色主题改成深色 点击确定,更改完成...

1.3 VSCode安装与环境配置
进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件,然后打开终端,进入下载文件夹,键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...

Python爬虫(一):爬虫伪装
一、网站防爬机制概述 在当今互联网环境中,具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类: 身份验证机制:直接将未经授权的爬虫阻挡在外反爬技术体系:通过各种技术手段增加爬虫获取数据的难度…...
【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)
要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况,可以通过以下几种方式模拟或触发: 1. 增加CPU负载 运行大量计算密集型任务,例如: 使用多线程循环执行复杂计算(如数学运算、加密解密等)。运行图…...
【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分
一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计,提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合:各模块职责清晰,便于独立开发…...