# 人脸过渡大作业报告
## 基本功能介绍
此次大作业实现了从一张人脸照片到另一张人脸照片的过渡。
**使用程序流程:**
- 选取控制点(特征点):使用者可以选择已经存储于文件中的控制点,也可以自己手动选择控制点。在选择的时候需要注意,源图像(SI)中控制点和目标图像(DI)中控制点顺序需要对应(比如 SI 中先选眼睛再选鼻子,那么 DI 中也需要先选眼睛再选鼻子),其次,控制点的数量也需要保持一致,如若不然,选取的控制点无效,会被要求重新选取。
- 显示 Delaunay 分割效果:完成本次作业的核心算法之一便是 Delaunay 三角分割。所以会显示 Delaunay 分割效果。
- 选择产生多少张过渡图片:过渡图片的数量是使用者选择的。
- 生成过渡图片并保存:这个过程可能需要一定的时间,程序运行完成之后可以在当前目录下查看产生的图片。
- 展示过渡图片:每张图片停留 1s。
- 选择是否保存此次选择的特征点:若保存此次选择的特征点,下次运行程序之时可以直接调用保存后的文件。
## 设计思路
为了实现程序功能,需要完成以下过程:
- 人工选取控制点。控制点取在眉心、眼珠、鼻子两侧等特征比较明显的部位。
- 控制点选好之后进行 Delaunay 三角化。根据选择的特征点将一张图片剖分为若干个三角形。
- 根据控制点对应关系,得到 SI 剖分三角形和 DI 剖分三角形对应关系。
- 根据 SI 剖分三角形和 DI 剖分三角形对应关系和过渡系数得到过渡图像中三角形与源/DI 剖分三角形对应关系。
- 根据三角形对应关系,求出仿射矩阵。
- 根据仿射矩阵,求出过渡图像中每一点仿射到源/DI 中的点(很有可能是个浮点数)。不同点在不同三角形中,所以对应的仿射矩阵很可能是不一样的。
- 根据仿射得到点的坐标,再由双线性插值得到过渡图片中每一点在源/DI 中像素值。
- 根据双线性插值结果和过度系数,求出过渡图片像素点的像素值。从而得到过渡图片。
- 改变过度系数,重新得到新的过渡图片,直至过渡完成。
## 原理
**基本原理:**
人脸过渡过程,可以使看作 SI 权重不断减小和 DI 权重不断增大,其本质是多次映射。图像权重体现为坐标和像素值权重。
可以这样来想,从 SI 直接变化到 DI 就,没有映射,没有过渡。但是从 SI 照片经过一张过渡照片,再到 DI,就有一次过渡,这个过程中就会发生两次映射,分别是 SI 映射到过渡图片,DI 映射到过渡图片。依此类推,当有两张过渡图片时,会发生四次映射。
在映射的过程中,如果用一个矩阵来代替,必然会导致有很大的误差,为了缩小这个误差,我们应该将图片分为若干个三角形或者是四边形(我选择是分为三角形),这样每个三角形中包含点的映射矩阵就由三角形的三个顶点来确定,而三角形的顶点就是由选取的控制点来确定的。
因为图像可以被剖分为许多三角形,所以我就拿三角形来举个例子:
源图中三角形三个点分别为【(0,0),(100,100)(100,0)】,DI 中三个点分别为【(0,0),(200,200),(200,0)】。若只有一张过渡图片,那么与该三角形对应的过渡三角形应该为【(0,0),(150,150)(150,0)】。若有两张过渡图片,那么对应的两个三角形分别为【(0,0),(133,133,0)(133,0)】和【(0,0),(166,166),(166,0)】。依此类推,就可以知道产生 n 张过渡图片,每张过渡图片的三角形坐标。
得到映射矩阵之后,分别求出 SI 和 DI 到过渡图像的映射,最后再附加上像素值权重,便得到过渡图像。
**控制点的选取。**
控制点的选取直接影响了过渡图片的质量,根据前面的叙述,三角形映射矩阵是由控制点决定的。那么为什么控制点的选取要选择具有特征的点?
就拿人的眼睛来举例子,如果在 SI 和 DI 中,包含眼睛的三角形控制点不是眼睛,那么 SI 和 DI 分别向过渡图像映射之后,眼睛的位置可能不是重叠的,这就会导致过渡图像中眼睛数量翻了一倍。
**三角剖分算法**
图像三角化要求产生的三角形边不会相交,并且所有的三角形能够刚好完全覆盖整个图像。在实现此目的时,我选用了 openCV 中的 Delaunay 剖分,Subdiv2D 这个类。
**仿射**
仿射的目的是要知道过渡三角形中每一个点对应 SI/DI 中三角形的点。
若已知,三角形 A 的三个顶点,分别为(x1,y1),(x2,y2),(x3,y3)对应三角形 B 的顶点为(a1,b1),(a2,b2),(a3,b3)
可以求出 A->B 的仿射矩阵。
Aff =
![](https://www.writebug.com/myres/static/uploads/2021/11/10/e7f8153ae39916030e64318dc03e41b6.writebug)
若已知三角形 A 中某点为(m,n)
可以求出其对应的点(c,d)
![](https://www.writebug.com/myres/static/uploads/2021/11/10/96941fffd64b4a12358f6f8738feadc5.writebug)
**双线性插值**
根据仿射变换求出对应点坐标是为了得到像素值。
得到的坐标多数情况下不是整数,而如何求取非整数(非网格点)处像素值呢?
我采用的是双线性插值法:
如下图:假设 P 为我们要求的插值节点,Q11,Q12,Q21,Q22 为网格点。
![](https://www.writebug.com/myres/static/uploads/2021/11/10/e4314c1dd2178f9fa7d11374a526cd94.writebug)
双线性插值方法是先在一个方向上插值(x 方向),再在另一个方向上插值(y 方向)。
举个例子,先在 x 上插值:
![](https://www.writebug.com/myres/static/uploads/2021/11/10/9c3439af98c2c527983fbc0fc700b9c9.writebug)
再在 y 上插值:
![](https://www.writebug.com/myres/static/uploads/2021/11/10/d80bfddeb59465cb30b16e3aac6f07b8.writebug)
## 程序实现以及结果
**控制点选取**
主要调用 setMouseCallback()函数,得到鼠标左键点击处坐标。
并且调用 circle()函数将鼠标左键左键点击处点亮。
![](https://www.writebug.com/myres/static/uploads/2021/11/10/e12f2ca7144484b1a1892b023edb7a04.writebug)
**Delaunay 三角化**
利用 openCV 中的 Subdiv2D 类,将控制点插入后,就可以得到三角化后,三角形的坐标,然后我再将三角形的边画出来,得到以下结果。
![](https://www.writebug.com/myres/static/uploads/2021/11/10/273ab1b3fb7c3301b43abeb41d6b85c4.writebug)
![](https://www.writebug.com/myres/static/uploads/2021/11/10/d90c98d1bafb674ea82c8cba05315d4d.writebug)
![](https://www.writebug.com/myres/static/uploads/2021/11/10/321e89a96fde3ddc1479b384a98a8161.writebug)
**仿射矩阵计算以及坐标仿射**
**仿射矩阵计算:**
![](https://www.writebug.com/myres/static/uploads/2021/11/10/2d25b3a5b52f4b370e21d5f6c50ea116.writebug)
**坐标仿射:**
![](https://www.writebug.com/myres/static/uploads/2021/11/10/7021a6be76fa181c3748eb9cf1718ad9.writebug)
**双线性插值**
![](https://www.writebug.com/myres/static/uploads/2021/11/10/e94ea1bfd1179b4687d9624097998555.writebug)
## 实验结果以及对结果的讨论
由于产生的图片比较多,不放便一张一张的贴出来,所以找了一张有特点的。
![](https://www.writebug.com/myres/static/uploads/2021/11/10/761a8ff603adcebaf56489b95789efb9.writebug)
以上图片出现了一个问题就是,某些区域会变得模糊,在这张图片中是下巴部分(原因肯可能是我在选取控制点时没选取好,下巴和下巴没有对应起来,也怪 Trump 是个双下巴,不好找。)
## 实验中遇到的问题
特征点的选取必须要有对应顺序,如果顺序不对应,那么产生的过渡照片质量
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
资源包含文件:课程设计报告word+项目源码及可执行exe文件 本项目主要用C++进行开发实现,首先选取控制点,其次显示 Delaunay 分割效果,再选择产生多少张过渡图片,实现了从一张人脸照片到另一张人脸照片的过渡。 为了实现程序功能,需要完成以下过程: 人工选取控制点。控制点取在眉心、眼珠、鼻子两侧等特征比较明显的部位。 控制点选好之后进行 Delaunay 三角化。根据选择的特征点将一张图片剖分为若干个三角形。 根据控制点对应关系,得到 SI 剖分三角形和 DI 剖分三角形对应关系。 根据 SI 剖分三角形和 DI 剖分三角形对应关系和过渡系数得到过渡图像中三角形与源/DI 剖分三角形对应关系。 根据三角形对应关系,求出仿射矩阵。 根据仿射矩阵,求出过渡图像中每一点仿射到源/DI 中的点(很有可能是个浮点数)。不同点在不同三角形中,所以对应的仿射矩阵很可能是不一样的。 根据仿射得到点的坐标,再由双线性插值得到过渡图片中每一点在源/DI 中像素值。 详细介绍参考:https://blog.csdn.net/sheziqiong/article/details/125590325
资源推荐
资源详情
资源评论
收起资源包目录
基于C++的人脸过渡项目.zip (22个子文件)
Mesh.exe 62KB
feature_src.txt 531B
课程设计报告.docx 406KB
feature_dst.txt 525B
LICENSE 1KB
Mesh_Morphing.h 1KB
main.cpp 2KB
img.docx-md
3-c655b4e3a5fb3c8dbadc1c322a7e74fe.png 9KB
10-7c4c19a00a781670c6897bfbfa8e70f5.png 6KB
4-f6b4f5597387cfa1b2611ee8be88185c.png 5KB
7-e2b0f7218e7c70237ac19a7fca394934.png 152KB
5-2bfa584562d605b6604064f824bd8b41.png 2KB
2-74f3b1305ef0f26576ae796da5d92f25.png 1KB
12-72bc691aa2d01a8b1e35d2f993f3c74b.png 9KB
13-c023aed1550cd7b51888dc4528db759b.png 28KB
9-36334383c87745290c8cb582be86e068.png 11KB
11-3d6d7851a2fac1bdd6b41dca3d0c04a6.png 3KB
6-5ee0c02190c7f0939d0274b0aa55aa96.png 156KB
8-b718a4bb73315d0bd167e9545f6be2dc.png 4KB
1-ff2b8b0c5ce96705a69bd9bd635c9b05.png 2KB
README.md 8KB
Mesh_Morphing.cpp 10KB
共 22 条
- 1
资源评论
shejizuopin
- 粉丝: 9988
- 资源: 1288
下载权益
C知道特权
VIP文章
课程特权
开通VIP
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功