一、实验要求

1、手动点击关键点进行替换

2、利用光流对相邻的视频帧进行关键点的追踪

二、实验结果

三、实验代码

1、手动进行图像关键点的点击

import cv2
import numpy as np# 导入图片
img1 = cv2.imread('path1')
img2 = cv2.imread('path2')a =[]
b = []def on_EVENT_LBUTTONDOWN1(event, x, y, flags, param):# 点击鼠标左键if event == cv2.EVENT_LBUTTONDOWN:xy = "%d,%d" % (x, y)a.append(x)b.append(y)cv2.circle(img1, (x, y), 1, (255, 0, 0), thickness=-1)cv2.putText(img1, xy, (x, y), cv2.FONT_HERSHEY_PLAIN,1.0, (0, 0, 0), thickness=1)cv2.imshow("image1", img1)def on_EVENT_LBUTTONDOWN2(event, x, y, flags, param):# 点击鼠标左键if event == cv2.EVENT_LBUTTONDOWN:xy = "%d,%d" % (x, y)a.append(x)b.append(y)cv2.circle(img2, (x, y), 1, (255, 0, 0), thickness=-1)cv2.putText(img2, xy, (x, y), cv2.FONT_HERSHEY_PLAIN,1.0, (0, 0, 0), thickness=1)cv2.imshow("image2", img2)cv2.namedWindow("image1")
cv2.namedWindow("image2")
cv2.setMouseCallback("image1", on_EVENT_LBUTTONDOWN1)
cv2.setMouseCallback("image2", on_EVENT_LBUTTONDOWN2)
cv2.imshow("image1", img1)
cv2.imshow("image2", img2)
cv2.waitKey(0)cv2.destroyAllWindows()#for i in range(8):
#    print([a[i],b[i]])

调用cv2库和numpy库,利用cv2.setMouseCallback函数得到鼠标的点击信息,并在on_EVENT_LBUTTONDOWN函数中对点击的点进行标记,将点击点的坐标存储在数组a,b里面。

2、利用光流对相邻的视频帧进行关键点的追踪

(1)首先需要提取视频的第一帧,手动进行关键点的标注,调用cap.read函数,此时frame为视频第一帧的二进制流数据

import cv2
cap = cv2.VideoCapture('2.mp4')
ret, frame = cap.read()      #frame是每一帧的图像
scaling_factor = 0.5
frame = cv2.resize(frame, None, fx=scaling_factor,fy=scaling_factor, interpolation=cv2.INTER_AREA)

(2)手动点击关键点

a =[]
b = []def on_EVENT_LBUTTONDOWN1(event, x, y, flags, param):# 点击鼠标左键if event == cv2.EVENT_LBUTTONDOWN:xy = "%d,%d" % (x, y)a.append(x)b.append(y)cv2.circle(frame, (x, y), 1, (255, 0, 0), thickness=-1)cv2.putText(frame, xy, (x, y), cv2.FONT_HERSHEY_PLAIN,1.0, (0, 0, 0), thickness=1)cv2.imshow("image1", frame)def on_EVENT_LBUTTONDOWN2(event, x, y, flags, param):# 点击鼠标左键if event == cv2.EVENT_LBUTTONDOWN:xy = "%d,%d" % (x, y)a.append(x)b.append(y)cv2.circle(img1, (x, y), 1, (255, 0, 0), thickness=-1)cv2.putText(img1, xy, (x, y), cv2.FONT_HERSHEY_PLAIN,1.0, (0, 0, 0), thickness=1)cv2.imshow("image2", img1)cv2.namedWindow("image1")
cv2.setMouseCallback("image1", on_EVENT_LBUTTONDOWN1)
cv2.imshow("image1", frame)cv2.namedWindow("image2")
cv2.setMouseCallback("image2", on_EVENT_LBUTTONDOWN2)
cv2.imshow("image2", img1)
cv2.waitKey(0)p0=np.float32([[[a[0],b[0]]],[[a[1],b[1]]],[[a[2],b[2]]],[[a[3],b[3]]]])
print(p0)
cv2.destroyAllWindows()

(3)对视频光流进行追踪,p0为当前关键点,p1为视频流中关键点的下一个位置信息

调用cv2.calcOpticalFlowPyrLK()函数进行我们想要的追踪操作

(ps.关注cv2.calcOpticalFlowPyrLK()函数中p0的格式)

import cv2
import numpy as np# feature_params = dict(maxCorners=100, qualityLevel=0.3,
#                       minDistance=7, blockSize=7)
lk_params = dict(winSize=(15,15), maxLevel=2,criteria=(cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03))cap = cv2.VideoCapture('path')
ret, frame = cap.read()      #frame是每一帧的图像scaling_factor = 0.5
frame = cv2.resize(frame, None, fx=scaling_factor,fy=scaling_factor, interpolation=cv2.INTER_AREA)
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
p0 = np.float32([[[174,170]],[[180,190]],[[200,200]],[[210,210]]])
# p0 = cv2.goodFeaturesToTrack(gray, mask=None, **feature_params)    #角点检测
print(p0)
mask = np.zeros_like(frame)while True:ret, frame = cap.read()frame = cv2.resize(frame, None, fx=scaling_factor,fy=scaling_factor, interpolation=cv2.INTER_AREA)frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)p1, st, err = cv2.calcOpticalFlowPyrLK(gray, frame_gray, p0, None, **lk_params)print(p1[0][0])
#     print(p0)good_new = p1[st == 1]good_old = p0[st == 1]for i,(new,old) in enumerate(zip(good_new,good_old)):a,b = new.ravel()a=int(a)b=int(b)c,d = old.ravel()c=int(c)d=int(d)cv2.line(mask, (a, b),(c, d),(0, 150, 0), 1)cv2.circle(frame, (a, b), 3, (0, 255, 0), -1)gray = frame_gray.copy()p0 = good_new.reshape(-1, 1, 2)#     img = cv2.add(frame, mask)
#     cv2.imshow("Output", img)k = cv2.waitKey(30)if k == 27:breakcap.release()
cv2.destroyAllWindows()

3、人脸的替换(以为图片的替换为例)

(1)鼠标定点(不再赘述)

(2)矩阵变换

调用cv2.getPerspectiveTransform(), cv2.warpPerspective()函数进行两张图片上的关键点的对比(注:此函数规定对应点为4个点)

(3)内容替换

直接用变换好的图像相应矩阵位置处的值替换原图像位置的值

import numpy as np
import cv2
%matplotlib inlineimg1 = cv2.imread('path1')
img2 = cv2.imread('path2')a =[]
b = []# 一、鼠标定点def on_EVENT_LBUTTONDOWN1(event, x, y, flags, param):# 点击鼠标左键if event == cv2.EVENT_LBUTTONDOWN:xy = "%d,%d" % (x, y)a.append(x)b.append(y)#         cv2.circle(img1, (x, y), 1, (255, 0, 0), thickness=-1)
#         cv2.putText(img1, xy, (x, y), cv2.FONT_HERSHEY_PLAIN,
#                     1.0, (0, 0, 0), thickness=1)
#         cv2.imshow("image1", img1)def on_EVENT_LBUTTONDOWN2(event, x, y, flags, param):# 点击鼠标左键if event == cv2.EVENT_LBUTTONDOWN:xy = "%d,%d" % (x, y)a.append(x)b.append(y)#         cv2.circle(img2, (x, y), 1, (255, 0, 0), thickness=-1)
#         cv2.putText(img2, xy, (x, y), cv2.FONT_HERSHEY_PLAIN,
#                     1.0, (0, 0, 0), thickness=1)
#         cv2.imshow("image2", img2)cv2.namedWindow("image1")
cv2.namedWindow("image2")
cv2.setMouseCallback("image1", on_EVENT_LBUTTONDOWN1)
cv2.setMouseCallback("image2", on_EVENT_LBUTTONDOWN2)
cv2.imshow("image1", img1)
cv2.imshow("image2", img2)
cv2.waitKey(0)# print(a[3],b[3])
# print(a[6],b[6])cv2.destroyAllWindows()# 二、矩阵变换points1 = np.float32([[[a[4],b[4]]],[[a[5],b[5]]],[[a[6],b[6]]],[[a[7],b[7]]]])
points2 = np.float32([[[a[0],b[0]]],[[a[1],b[1]]],[[a[2],b[2]]],[[a[3],b[3]]]])M  =  cv2.getPerspectiveTransform(points1, points2)Affine_img = cv2.warpPerspective(img2, M, (img1.shape[1], img1.shape[0]))# 三、内容替换m=a[2]-a[0]
# n=b[2]-b[0]
for j in range(m):for i in range(m):img1[74+i][125+j] = Affine_img[74+i][125+j]cv2.namedWindow("image3")
cv2.imshow("image3",Affine_img)     # 显示图片
# cv2.imshow("image2",np.array(img_cov, dtype = np.uint8 ))
cv2.waitKey(0)cv2.destroyAllWindows()

四、完整代码

import numpy as np
import cv2
%matplotlib inline#视频第一帧和图像第一帧锁定cap = cv2.VideoCapture('2.mp4')
ret, frame = cap.read()      #frame是每一帧的图像
scaling_factor = 0.5
frame = cv2.resize(frame, None, fx=scaling_factor,fy=scaling_factor, interpolation=cv2.INTER_AREA)
img1 = cv2.imread('face.jpg')a =[]
b = []def on_EVENT_LBUTTONDOWN1(event, x, y, flags, param):# 点击鼠标左键if event == cv2.EVENT_LBUTTONDOWN:xy = "%d,%d" % (x, y)a.append(x)b.append(y)cv2.circle(frame, (x, y), 1, (255, 0, 0), thickness=-1)cv2.putText(frame, xy, (x, y), cv2.FONT_HERSHEY_PLAIN,1.0, (0, 0, 0), thickness=1)cv2.imshow("image1", frame)def on_EVENT_LBUTTONDOWN2(event, x, y, flags, param):# 点击鼠标左键if event == cv2.EVENT_LBUTTONDOWN:xy = "%d,%d" % (x, y)a.append(x)b.append(y)cv2.circle(img1, (x, y), 1, (255, 0, 0), thickness=-1)cv2.putText(img1, xy, (x, y), cv2.FONT_HERSHEY_PLAIN,1.0, (0, 0, 0), thickness=1)cv2.imshow("image2", img1)cv2.namedWindow("image1")
cv2.setMouseCallback("image1", on_EVENT_LBUTTONDOWN1)
cv2.imshow("image1", frame)cv2.namedWindow("image2")
cv2.setMouseCallback("image2", on_EVENT_LBUTTONDOWN2)
cv2.imshow("image2", img1)
cv2.waitKey(0)p0=np.float32([[[a[0],b[0]]],[[a[1],b[1]]],[[a[2],b[2]]],[[a[3],b[3]]]])
print(p0)
cv2.destroyAllWindows()#光流追踪关键点lk_params = dict(winSize=(15,15), maxLevel=2,criteria=(cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03))
mask = np.zeros_like(frame)gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)while True:ret, frame = cap.read()frame = cv2.resize(frame, None, fx=scaling_factor,fy=scaling_factor, interpolation=cv2.INTER_AREA)frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)p1, st, err = cv2.calcOpticalFlowPyrLK(gray, frame_gray, p0, None, **lk_params)good_new = p1[st == 1]good_old = p0[st == 1]for i,(new,old) in enumerate(zip(good_new,good_old)):e,f = new.ravel()e=int(e)f=int(f)g,h = old.ravel()g=int(g)h=int(h)cv2.line(mask, (e, f),(g, h),(0, 150, 0), 1)cv2.circle(frame, (e, f), 3, (0, 255, 0), -1)# 二、矩阵变换points1 = np.float32([[[a[4],b[4]]],[[a[5],b[5]]],[[a[6],b[6]]],[[a[7],b[7]]]])points2 = np.float32(p1)M  =  cv2.getPerspectiveTransform(points1, points2)Affine_img = cv2.warpPerspective(img1, M, (frame.shape[1], frame.shape[0]))# 三、内容替换m = p1[2][0][0]-p1[0][0][0]   #m=a[2]-a[0]m=int(m)n = p1[2][0][1]-p1[0][0][1]   #n=b[2]-b[0]n=int(n)a1 = int(p1[0][0][1])a2 = int(p1[0][0][0])a3 = int(p1[0][0][1])a4 = int(p1[0][0][0])for i in range(n):for j in range(m):frame[a1+i][a2+j] = Affine_img[a3+i][a4+j]#     cv2.namedWindow("image3")
#     cv2.imshow("image3",Affine_img)     # 显示图片
#     # cv2.imshow("image2",np.array(img_cov, dtype = np.uint8 ))
#     cv2.waitKey(0)#     cv2.destroyAllWindows()gray = frame_gray.copy()p0 = good_new.reshape(-1, 1, 2)img = cv2.add(frame, mask)cv2.imshow("Output", img)k = cv2.waitKey(30)if k == 27:breakcap.release()
cv2.destroyAllWindows()

完结撒花!

Python:计算机视觉实现视频的AI换脸(最基础)相关推荐

  1. python调用API轻松实现AI 换脸

    # AI换脸 # AndyCheimport requests import json import simplejson import base64# 第一步:获取人脸关键点 def find_fa ...

  2. 2019传智python就业班视频_2019黑马JAVAEE57期基础班就业班(全套)

    借助GitHub托管你的项目代码 PS:话说自己注册了GitHub都很久了,却没有怎么去弄,现在系统学习一下,也把自己的学习经历总结下来share给大家,希望大家都能把GitHub用起来,把你的项目代 ...

  3. AI换脸(支持视频换脸,支持cpu、低算力)【附代码】

    可直接选择一张人脸去替换另一张图片或者视频中的人脸.本项目仅提供人脸替换部分,不需要数据集,不用训练! 目录 项目说明 环境说明 准备工作 如何使用 免责声明 项目说明 本项目参考源码:GitHub ...

  4. 深度解密——沈腾版斯内普教授背后的AI换脸术

    AI换脸技术是近两年大热的与人脸相关的应用.近期,随着<哈利·波特>在国内各大影院重映,一个名为<当斯内普教授换上了沈腾的脸>的视频迅速在网络走红. 视频用AI换脸技术将斯内普 ...

  5. python实现视频ai换脸_python 实现 AI 换脸

    #!/usr/bin/python # -*- coding: utf-8 -*- # @Time : 2019/9/1 8:50 # @Author : cuijianzhe # @File : A ...

  6. python实现视频ai换脸_超简单使用Python换脸实例

    换脸! 这段时间,deepfakes搞得火热,比方说把<射雕英雄传>里的朱茵换成了杨幂,看下面的图!毫无违和感! 其实早在之前,基于AI换脸的技术就得到了应用,比方说<速度与激情7& ...

  7. python实现视频ai换脸_Python如何实现AI换脸功能 Python实现AI换脸功能代码

    Python如何实现AI换脸功能?本篇文章小编给大家分享一下Python实现AI换脸功能代码,文章代码详细的介绍了实现方法,小编觉得挺不错的,有需要的小伙伴们可以来看看. 需要用到的接口: 获取人脸信 ...

  8. 华为三星折叠手机可看不可摸;小米架构再调整;杨幂 AI 换脸视频制作者回应 | 极客头条...

    「CSDN 极客头条」,是从 CSDN 网站延伸至官方微信公众号的特别栏目,专注于一天业界事报道.风里雨里,我们将每天为朋友们,播报最新鲜有料的新闻资讯,让所有技术人,时刻紧跟业界潮流. 快讯速知 三 ...

  9. 开课吧python怎么样-找工作得有个大杀招,你看AI换脸这个技能怎么样?

    原标题:找工作得有个大杀招,你看AI换脸这个技能怎么样? 你ZAO吗,当你还沉浸在idol爆恋情的悲伤中,别人已经"和偶像同台对戏了"! 相信大部分小伙伴都已经知道"别人 ...

  10. Python进阶——网课不愁系列AI换脸技术

    俗话说的好:网络一线牵,珍惜这段缘! 网络的水很深,年轻人你把握不住,众所周知照片是可以P的,但是"视频"是"P"不了的(狗头保命) 谁能想到AI换脸竟然如此便 ...

最新文章

  1. [4月21日]《51CTO 编辑部的外传》——剧本篇(上)
  2. ROS学习(五):package.xml 文件
  3. ASP.NET Web API中的参数绑定总结
  4. linux.调整收发队列,linux消息队列通信
  5. (转)探究 TCP 一次数据包最大负载,上限真的是 65495 byte 吗
  6. 在springboot中使用easyexcel导出数据excel表格
  7. 【Python】编程笔记1
  8. boost::hana::is_disjoint用法的测试程序
  9. element el-popover 使用v-if 控制显示/隐藏,当条件变化时,里面有部分内容无法显示
  10. xshell vim 不能粘贴_编辑器之神——vim的入门指南
  11. 基于arm下的Linux控制,基于ARMuCLinux的网络控制系统设计与实现
  12. 我们身边的知识产权单元测试答案(期末考试复习)【湘潭大学】
  13. 升级到Oracle 19c:你不可不知的十大SQL问题(上)
  14. phpfpm内存越来越高_DDR5内存规范发布
  15. linux下录屏与截屏软件kazam
  16. 【酷熊科技】工作积累 ----------- Unity3D 读取 图片
  17. [App Store Connect帮助]二、 添加、编辑和删除用户(5)创建一个沙盒测试员帐户...
  18. 阮工的单片机编程经验集:如何做稳定单片机程序与上位机程序防卡顿,js等经验;阮丁远于20221111
  19. C4D模型工具—提取样条
  20. 教你STM32官方开发板原理图下载

热门文章

  1. matlab面板数据怎么求增长率的公式,增长率怎么计算公式(7个步骤详解)
  2. 【Leetcode】882. Reachable Nodes In Subdivided Graph 882. 细分图中的可到达结点
  3. 如何查询本机ip地址
  4. css td中画斜线,css 模拟表格斜线
  5. Python-初应用:乌龟吃鱼(菜菜狂踩雷现场、典型低级错误)
  6. 超星网络学生登录入口 附使用教程
  7. java 苹果cms 萌果_MacCMS8.x(苹果CMS8.x)整合Ckplayer6.4
  8. LM2596电路简析
  9. Scrapy爬虫框架详解
  10. 计算机录制视频的方法,怎么录制电脑屏幕视频步骤(电脑录屏的方法有4种)...