计算机动画作业:图像morphing

article/2025/9/4 21:42:28

本学期选了计算机动画课程,第一次作业是图像morphing, 本来打算选择基于四边网格的morphing, 但因为要用到曲面插值,感觉比较麻烦,因此使用基于三角网格的face morphing。

一、总体方案

1、检测人脸特征点,可以检测人脸81个特征点:https://github.com/codenik/shape_predictor_81_face_landmarks
2、基于81个面部特征点 + 图像边界的8个点 , 共拿到每张图片的 89个点
3、对两张图像的采样点进行Delaunay三角剖分
4、根据时间t,分别计算原图像 -> t 时刻的原图像, 目标图像 -> t时刻的目标图像
5、根据时间t, 融合 t 时刻的原图像 和 t时刻的目标图像
难点:三角形区域仿射变换:使用OpenCV将一个三角形仿射变换到另一个三角形

流程图如下:
在这里插入图片描述

二、具体实现

1、main.py

import sys, os, cv2, time
from skimage import io
import numpy as np
from util import face_detection_triangle
from util import img_tri_affinesrc_img_path = 'images/dst.png'
dst_img_path = 'images/src.png'
src_img = cv2.imread(src_img_path)
dst_img = cv2.imread(dst_img_path)src_points, src_tri = face_detection_triangle(src_img, 'images/src_tri.jpg')
dst_points, dst_tri = face_detection_triangle(dst_img, 'images/dst_tri.jpg')tcnt = 50
t = 0
src_img_t = 255 * np.ones(src_img.shape, dtype = src_img.dtype)
dst_img_t = 255 * np.ones(dst_img.shape, dtype = dst_img.dtype)for i in range(50, 50+tcnt):for j in range(src_tri.shape[0]) : #src_tri.shape[0]src_p0 = src_points[src_tri[j, 0]]src_p1 = src_points[src_tri[j, 1]]src_p2 = src_points[src_tri[j, 2]]src_tri_points = np.float32([[src_p0[0], src_p0[1]], [src_p1[0], src_p1[1]], [src_p2[0], src_p2[1]]])dst_p0 = dst_points[src_tri[j, 0]]dst_p1 = dst_points[src_tri[j, 1]]dst_p2 = dst_points[src_tri[j, 2]]dst_tri_points = np.float32([[dst_p0[0], dst_p0[1]], [dst_p1[0], dst_p1[1]], [dst_p2[0], dst_p2[1]]])mid_tri_points = src_tri_points * (1-t) + dst_tri_points * timg_tri_affine(src_img, src_img_t, src_tri_points, mid_tri_points)img_tri_affine(dst_img, dst_img_t, dst_tri_points, mid_tri_points)res_image_t = src_img_t[0:651, :, :] * (1-t)/255 + dst_img_t[0:651, :, :] * t/255cv2.imshow('morphing-res', res_image_t)cv2.waitKey(50)t += 1.0 / tcntcv2.waitKey(0)

2、util.py

import sys, os, dlib, glob, cv2
from skimage import io
import numpy as np
from scipy.spatial import Delaunay
import matplotlib.pyplot as pltdef face_detection_triangle(image, path_out):predictor_path = 'face_landmarks_predictor.dat'detector = dlib.get_frontal_face_detector()predictor = dlib.shape_predictor(predictor_path)frame = imagedets = detector(frame, 0)points = np.zeros((81+8, 2))for k, d in enumerate(dets):shape = predictor(frame, d)landmarks = np.matrix([[p.x, p.y] for p in shape.parts()])for num in range(shape.num_parts):cv2.circle(frame, (shape.parts()[num].x, shape.parts()[num].y), 3, (255, 0, 0), -1)points[num][0] = int(shape.parts()[num].x)points[num][1] = int(shape.parts()[num].y)height = frame.shape[0] width = frame.shape[1]points[81] = [4, 4]points[82] = [width-4, 4]points[83] = [4, height-4]points[84] = [width-4, height-4]points[85] = [int(width/2), 4]points[86] = [width-4, int(height/2)]points[87] = [4, int(height/2)]points[88] = [int(width/2), height-4]tri = Delaunay(points)color = (255, 0, 0)for i in range(tri.simplices.shape[0]):p0 = points[tri.simplices[i, 0]]p1 = points[tri.simplices[i, 1]]p2 = points[tri.simplices[i, 2]]cv2.line(frame, (int(p0[0]), int(p0[1])), (int(p1[0]), int(p1[1])), color)cv2.line(frame, (int(p0[0]), int(p0[1])), (int(p2[0]), int(p2[1])), color)cv2.line(frame, (int(p1[0]), int(p1[1])), (int(p2[0]), int(p2[1])), color)cv2.imwrite(path_out, frame)return points, tri.simplices# Warps and alpha blends triangular regions from img1 and img2 to img
def img_tri_affine(img1, img2, tri1, tri2) :# Find bounding rectangle for each triangler1 = cv2.boundingRect(tri1)r2 = cv2.boundingRect(tri2)# Offset points by left top corner of the respective rectanglestri1Cropped = []tri2Cropped = []for i in range(0, 3):tri1Cropped.append(((tri1[i][0] - r1[0]),(tri1[i][1] - r1[1])))tri2Cropped.append(((tri2[i][0] - r2[0]),(tri2[i][1] - r2[1])))# Crop input imageimg1Cropped = img1[r1[1]:r1[1] + r1[3], r1[0]:r1[0] + r1[2]]# Given a pair of triangles, find the affine transform.warpMat = cv2.getAffineTransform( np.float32(tri1Cropped), np.float32(tri2Cropped) )# Apply the Affine Transform just found to the src imageimg2Cropped = cv2.warpAffine( img1Cropped, warpMat, (r2[2], r2[3]), None, flags=cv2.INTER_LINEAR, borderMode=cv2.BORDER_REFLECT_101 )# Get mask by filling trianglemask = np.zeros((r2[3], r2[2], 3), dtype = np.float32)cv2.fillConvexPoly(mask, np.int32(tri2Cropped), (1.0, 1.0, 1.0), 16, 0);img2Cropped = img2Cropped * mask# Copy triangular region of the rectangular patch to the output imageimg2[r2[1]:r2[1]+r2[3], r2[0]:r2[0]+r2[2]] = img2[r2[1]:r2[1]+r2[3], r2[0]:r2[0]+r2[2]]  * ( (1.0, 1.0, 1.0) - mask )  img2[r2[1]:r2[1]+r2[3], r2[0]:r2[0]+r2[2]] = img2[r2[1]:r2[1]+r2[3], r2[0]:r2[0]+r2[2]]  + img2Cropped

http://chatgpt.dhexx.cn/article/bY04vyZF.shtml

相关文章

Morphing

<script src"http://widgets.amung.us/classic.js" type"text/javascript"></script> <script type"text/javascript"> </script> Morphing 这篇文章给大家介绍一下morphing&#xff0c;它是一种变型动画&#xff0c;…

深度学习中的GPU与CUDA

对应视频教程&#xff1a;https://www.bilibili.com/video/BV1S5411X7FY/ 文章目录 1. 显卡&#xff08;GPU&#xff09;与驱动2. 显卡与CUDA3. 如何查看自己的显卡 1. 显卡&#xff08;GPU&#xff09;与驱动 显卡&#xff0c;也称之为 GPU。GPU 的全称是 Graphics Processin…

CUDA详解

CUDA&#xff08;Compute Unified Device Architecture&#xff0c;统一计算设备架构&#xff09;&#xff0c;是显卡厂商NVIDIA推出的运算平台。 CUDA™是一种由NVIDIA推出的通用并行计算架构&#xff0c;该架构使GPU能够解决复杂的计算问题。 它包含了CUDA指令集架构&#xf…

CUDA入门

1. 引言 CUDA为a platform and programming model for CUDA-enabled GPUs。该平台通过GPU来进行计算。CUDA为GPU编程和管理 提供C/C语言扩展和API。 CUDA编程中&#xff0c;会同时使用CPU和GPU进行计算&#xff1a; CPU system&#xff1a;称为host。GPU system&#xff1a;…

cuda和cudatoolkit

Pytorch 使用不同版本的 cuda 由于课题的原因&#xff0c;笔者主要通过 Pytorch 框架进行深度学习相关的学习和实验。在运行和学习网络上的 Pytorch 应用代码的过程中&#xff0c;不少项目会标注作者在运行和实验时所使用的 Pytorch 和 cuda 版本信息。由于 Pytorch 和 cuda 版…

最新CUDA环境配置(Win10 + CUDA 11.6 + VS2019)

最新CUDA环境配置(Win10 CUDA 11.6 VS2019) 本篇博客根据NVIDIA 官方文档所述, 并根据自己实践得出. 供各位需要的朋友参考. 1.前言 本篇文章的软件环境为: Windows 10CUDA 11.6VS2019 CUDA是目前做人工智能, 深度学习等方向的必备工具库. 由CUDA衍生出的加速工具很多, …

一文搞懂CUDA

什么是cuda 统一计算设备架构&#xff08;Compute Unified Device Architecture, CUDA&#xff09;&#xff0c;是由NVIDIA推出的通用并行计算架构。解决的是用更加廉价的设备资源&#xff0c;实现更高效的并行计算。 CUDA是NVIDIA公司所开发的GPU编程模型&#xff0c;它提供…

GPU,CUDA,cuDNN的理解

我们知道做深度学习离不开GPU,不过一直以来对GPU和CPU的差别,CUDA以及cuDNN都不是很了解,所以找了些资料整理下,希望不仅可以帮助自己理解,也能够帮助到其他人理解。 先来讲讲CPU和GPU的关系和差别吧。截图来自资料1(CUDA的官方文档): 从上图可以看出GPU(图像处理器,…

CUDA编程之快速入门

CUDA(Compute Unified Device Architecture)的中文全称为计算统一设备架构。做图像视觉领域的同学多多少少都会接触到CUDA,毕竟要做性能速度优化,CUDA是个很重要的工具,CUDA是做视觉的同学难以绕过的一个坑,必须踩一踩才踏实。CUDA编程真的是入门容易精通难,具有计算机体…

CUDA学习

想想学习CUDA的时间也应该有十来天了&#xff0c;也该是做一个小总结了&#xff0c;说说我理解的CUDA&#xff0c;它到底是什么东西&#xff1f; 其实说到CUDA&#xff0c;还真的没几个人知道&#xff0c;说实话&#xff0c;我也听说不久&#xff0c;主要因为它2007年才刚发布&…

CUDA简介

CUDA简介 CUDA是什么 CUDA&#xff0c;Compute Unified Device Architecture的简称&#xff0c;是由NVIDIA公司创立的基于他们公司生产的图形处理器GPUs&#xff08;Graphics Processing Units,可以通俗的理解为显卡&#xff09;的一个并行计算平台和编程模型。 通过CUDA&#…

CUDA是什么-CUDA简介

在大家开始深度学习时&#xff0c;几乎所有的入门教程都会提到CUDA这个词。那么什么是CUDA&#xff1f;她和我们进行深度学习的环境部署等有什么关系&#xff1f;通过查阅资料&#xff0c;我整理了这份简洁版CUDA入门文档&#xff0c;希望能帮助大家用最快的时间尽可能清晰的了…

java队列和栈 共同_java 栈和队列的模拟--java

栈的定义&#xff1a;栈是一种特殊的表这种表只在表头进行插入和删除操作。因此&#xff0c;表头对于栈来说具有特殊的意义&#xff0c;称为栈顶。相应地&#xff0c;表尾称为栈底。不含任何元素的栈称为空栈。 栈的逻辑结构&#xff1a;假设一个栈S中的元素为an,an-1,..,a1&am…

栈和队列学习总结

一、栈 1、特点及应用 先进后出。(如果会和队列先进先出记混的话,就记场景吧:弹栈弹栈,就是把最上面的最新进来的弹出去;而队列就像我们火车站排队检票出站一样,谁排在前面谁就先出去。) 应用的话,其实我们经常接触呀。比如Undo操作(就是撤销操作)就是使用的栈的思想…

栈和队列的共同点和不同点

堆栈都是一种数据项按序排列的数据结构&#xff0c;只能在一端(称为栈顶(top))对数据项进行插入和删除。 要点&#xff1a;堆&#xff1a;顺序随意 栈&#xff1a;后进先出(Last-In/First-Out) 堆 堆&#xff1a;什么是堆&#xff1f;又该怎么理解呢&#xff1f; ①堆通常是一…

栈和队列实现和实例分析

目录 前言栈队列实例分析结语 前言 本篇文章主要讲述数据结构中栈和队列的实现&#xff0c;以及相关实例分析。 栈 注意本文所讲述的栈是数据结构的一种&#xff0c;并不是内存划区中的栈区&#xff0c;但是这两者有相似之处&#xff0c;即&#xff1a;存储数据时满足数据先…

栈和队列的共同处和不同处

共同处 栈和队列的共同处是&#xff1a;它们都是由几个数据特性相同的元素组成的有限序列&#xff0c;也就是所谓的线性表。 不同处 队列 队列&#xff08;queue&#xff09;是限定仅在表的一端插入元素、在另一端删除元素的线性表。 在队列中&#xff0c;允许插入的一端被…

索引的优缺点以及索引的设计原则

索引概述 索引&#xff08;index&#xff09; 是帮助 MySQL 高效获取数据的数据结构&#xff08;有序&#xff09;。 在数据之外&#xff0c;数据库系统还维护者满足特定查找算法的数据结构&#xff0c;这些数据结构以某种方式引用&#xff08;指向&#xff09;数据&#xff0…

SQL数据库之索引优缺点

SQL数据库之索引使用原则及利弊 索引是对数据库表中一列或多列的值进行排序的一种结构&#xff0c;使用索引可快速访问数据库表中的特定信息。 优点 通过创建唯一性索引&#xff0c;可以保证数据库表中每一行数据的唯一性。 可以大大加快数据的检索速度&#xff0c;这也是创建…

Oracle索引的建立及优缺点

在看公司建表语句时发现了这样一段代码 本着学习的态度面向百度&#xff1a;&#xff1a;&#xff1a;&#xff1a;&#xff1a; 原来这是Oracle的索引 Oracle的索引说明 1&#xff09;索引是数据库对象之一&#xff0c;用于加快数据的检索&#xff0c;类似于书籍的索引。在…