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

Python Opencv实践 - 简单的AR项目

        这个简单的AR项目效果是,通过给定一张静态图片作为要视频中要替换的目标物品,当在视频中检测到图片中的物体时,通过单应矩阵做投影,将视频中的物体替换成一段视频播放。这个项目的所有素材来自自己的手机拍的视频。

        静态图片:

        
        当我在原视频中检测到这本书时,会将书替换成另一个视频里的内容。

        关于opencv里的透视投影,单应矩阵等概念,请自行百度。下面是代码:

import cv2 as cv
import numpy as npvideoOriginal = cv.VideoCapture("../../SampleVideos/NationalGeography.mp4")
videoReplace = cv.VideoCapture("../../SampleVideos/Milo1.mp4")
targetImg = cv.imread("./book.png", cv.IMREAD_COLOR)
targetH,targetW,targetC = targetImg.shape#创建ORB对象
orb = cv.ORB_create(nfeatures=1500)
#提取ORB关键点和特征描述符
kpImg,descsImg = orb.detectAndCompute(targetImg, None)
#调试:绘制关键点
#imgDebug = cv.drawKeypoints(targetImg, kpImg, None)
#cv.imshow("ORB Keypoints", imgDebug)
#匹配距离阈值
matchDistanceThr = 0.75while True:ret,frame = videoOriginal.read()if ret == False:break;#frameAug表示最终合成的增强现实的结果图片frameAug = frame.copy()ret,frameReplace = videoReplace.read()if ret == False:break;#将视频大小调整到和待替换目标图片大小frameReplace = cv.resize(frameReplace, (targetW,targetH), interpolation=cv.INTER_AREA)kpVideo,descsVideo = orb.detectAndCompute(frame, None)#frame = cv.drawKeypoints(frame, kpVideo, None)#进行特征匹配bf = cv.BFMatcher()matches = bf.knnMatch(descsImg, descsVideo, k=2)goodMatches = []for m,n in matches:if m.distance < matchDistanceThr * n.distance:goodMatches.append(m)#print(len(goodMatches))#调试:绘制匹配结果imgFeatureMatching = cv.drawMatches(targetImg, kpImg, frame, kpVideo, goodMatches, None, flags=2)#找到单应矩阵#首先找到srcPts和dstPtsif (len(goodMatches) > 20):srcPts = np.float32([kpImg[m.queryIdx].pt for m in goodMatches]).reshape(-1,1,2)dstPts = np.float32([kpVideo[m.trainIdx].pt for m in goodMatches]).reshape(-1,1,2)#找到单应矩阵matrix,mask = cv.findHomography(srcPts, dstPts, cv.RANSAC, 5)#print(matrix)#映射targetImg的四个角点到目标平面targetPts = np.float32([[0,0],[0,targetH],[targetW,targetH],[targetW, 0]]).reshape(-1,1,2)targetOnVideoPts = cv.perspectiveTransform(targetPts, matrix)#print("Target shape:", targetImg.shape)#print("Frame shape:", frame.shape)#print(targetPts)#print('maps to:')#print(targetOnVideoPts)#print()#绘制待替换目标图像的位置映射到视频帧后的边框结果imgTargetOnVideoBox = cv.polylines(frame, [np.int32(targetOnVideoPts)], True, (255,0,255), 3)#调用warpPerspective将要替换的视频文件帧图像投影到视频帧的图像imgWarp = cv.warpPerspective(frameReplace, matrix, (frame.shape[1],frame.shape[0]))#获得掩码图#首先将视频帧中要替换的区域内容的mask标记为全1(白色)maskForReplace = np.zeros((frame.shape[0],frame.shape[1]), np.uint8)cv.fillPoly(maskForReplace, [np.int32(targetOnVideoPts)], (255,255,255))#获得原视频帧内容的mask,将maskForReplace取反即可maskForVideo = cv.bitwise_not(maskForReplace)#生成增强现实的帧frameAug = cv.bitwise_and(frameAug, frameAug, mask = maskForVideo)frameAug = cv.bitwise_or(imgWarp, frameAug)cv.imshow('Augmented Video', frameAug)cv.moveWindow('Augmented Video',  imgFeatureMatching.shape[1],0)cv.imshow('FeatureMatchResult', imgFeatureMatching)cv.moveWindow('FeatureMatchResult', 0,0)#cv.imshow('Mask For Video', maskForVideo)#cv.imshow('Mask For Replace', maskForReplace)#cv.imshow('WarpImage', imgWarp)#cv.moveWindow("WarpImage", 800,0)#cv.imshow('TargetOnVideo', imgTargetOnVideoBox)#cv.imshow('VideoPlayer', frame)if cv.waitKey(33) & 0xFF == ord('q'):break;videoOriginal.release()
videoReplace.release()
cv.destroyAllWindows()

        运行结果:

Python Opencv实践简单的AR项目

相关文章:

Python Opencv实践 - 简单的AR项目

这个简单的AR项目效果是&#xff0c;通过给定一张静态图片作为要视频中要替换的目标物品&#xff0c;当在视频中检测到图片中的物体时&#xff0c;通过单应矩阵做投影&#xff0c;将视频中的物体替换成一段视频播放。这个项目的所有素材来自自己的手机拍的视频。 静态图片&…...

Java不可变集合

Java不可变集合 不可变集合&#xff1a;也就是不可以被修改的集合 创建不可变集合的应用场景 ●如果某个数据不能被修改&#xff0c;把它防御性地拷贝到不可变集合中是个很好的实践。 ●当集合对象被不可信的库调用时&#xff0c;不可变形式是安全的。 简单理解&#xff1…...

openGauss学习笔记-146 openGauss 数据库运维-备份与恢复-配置文件的备份与恢复

文章目录 openGauss学习笔记-146 openGauss 数据库运维-备份与恢复-配置文件的备份与恢复146.1 背景信息146.2 前置条件146.3 操作步骤146.4 示例 openGauss学习笔记-146 openGauss 数据库运维-备份与恢复-配置文件的备份与恢复 146.1 背景信息 在openGauss使用过程中&#x…...

一文读懂中间件

前言&#xff1a;在程序猿的日常工作中&#xff0c; 经常会提到中间件&#xff0c;然而大家对中间件的理解并不一致&#xff0c;导致了一些不必要的分歧和误解。“中间件”一词被用来描述各种各样的软件产品&#xff0c;在不同文献中有着许多不同的中间件定义&#xff0c;包括操…...

【编程基础心法】「设计模式系列」让我们一起来学编程界的“兵法”设计模式(序章)

一起来学编程界的“兵法”设计模式&#xff08;序章&#xff09; 设计模式是什么设计模式的概念设计模式的分类创建型模式&#xff08;5种&#xff09;结构型模式&#xff08;7种&#xff09;行为型模式&#xff08;11种&#xff09; 设计模式应用场景工厂模式的实现及应用单例…...

技术阅读周刊第第8️⃣期

技术阅读周刊&#xff0c;每周更新。 历史更新 20231103&#xff1a;第四期20231107&#xff1a;第五期20231117&#xff1a;第六期20231124&#xff1a;第七期 Prometheus vs. VictoriaMetrics (VM) | Last9 URL: https://last9.io/blog/prometheus-vs-victoriametrics/?refd…...

HTML程序大全(2):通用注册模版

一、正常情况效果 二、某项没有填写的效果 三、没有勾选同意项的效果 四、代码 <!DOCTYPE html> <html> <head><meta charset"UTF-8"><title>注册</title><style>body {font-family: Arial, sans-serif;background-color…...

【循环结构 for、break、continue高级用法】

在 C++ 中,for 循环是一种常用的循环结构,它用于重复执行代码块直到满足指定的条件。for 循环的基础用法相对简单,而高级用法则涉及更复杂的控制结构和技术。让我们探讨这些用法,并通过一些示例来加深理解。 文章目录 基础用法高级用法实战示例注意事项结合 break 和 conti…...

JAVA网络编程——BIO、NIO、AIO深度解析

I/O 一直是很多Java同学难以理解的一个知识点&#xff0c;这篇帖子将会从底层原理上带你理解I/O&#xff0c;让你看清I/O相关问题的本质。 1、I/O的概念 I/O 的全称是Input/Output。虽常谈及I/O&#xff0c;但想必你也一时不能给出一个完整的定义。搜索了谷哥欠&#xff0c;发…...

Linux高级系统编程-3 进程

概念 进程与程序的区别 程序&#xff1a;一个可执行文件, 占磁盘空间&#xff0c;是静态的 进程&#xff1a;一个程序运行的过程, 占内存&#xff0c;动态的。 单道程序和多道程序 单道程序设计: 所有进程一个一个排队执行。若 A 阻塞&#xff0c; B 只能等待&#xff0…...

ES-ELSER 如何在内网中离线导入ES官方的稀疏向量模型(国内网络环境下操作方法)

ES官方训练了稀疏向量模型&#xff0c;用来支持语义检索。&#xff08;目前该模型只支持英文&#xff09; 最好是以离线的方式安装。在线的方式&#xff0c;在国内下载也麻烦&#xff0c;下载速度也慢。还不如用离线的方式。对于一般的生产环境&#xff0c;基本上也是网络隔离的…...

Excel 使用技巧

Excel 使用技巧 注意&#xff1a; excel 中设计计算的字符尽量使用英文。 拼接两段文字&#xff08;字符串拼接&#xff09; 方法一 在需要计算的单元格上,键入 点击 A1(点击需要拼接的单元格) & C1(点击需要拼接的单元格) 举例: 姓名栏想要拼接 姓 和 名 两列点击姓名这一…...

Hadoop学习笔记(HDP)-Part.03 资源规划

目录 Part.01 关于HDP Part.02 核心组件原理 Part.03 资源规划 Part.04 基础环境配置 Part.05 Yum源配置 Part.06 安装OracleJDK Part.07 安装MySQL Part.08 部署Ambari集群 Part.09 安装OpenLDAP Part.10 创建集群 Part.11 安装Kerberos Part.12 安装HDFS Part.13 安装Ranger …...

一个最新国内可用的免费GPT4,Midjourney绘画网站+使用教程

一、前言 ChatGPT GPT4.0&#xff0c;Midjourney绘画&#xff0c;相信对大家应该不感到陌生吧&#xff1f;简单来说&#xff0c;GPT-4技术比之前的GPT-3.5相对来说更加智能&#xff0c;会根据用户的要求生成多种内容甚至也可以和用户进行创作交流。 然而&#xff0c;GPT-4对普…...

深入了解Java8新特性-日期时间API之ZonedDateTime类

阅读建议 嗨&#xff0c;伙计&#xff01;刷到这篇文章咱们就是有缘人&#xff0c;在阅读这篇文章前我有一些建议&#xff1a; 本篇文章大概19000多字&#xff0c;预计阅读时间长需要10分钟以上。本篇文章的实战性、理论性较强&#xff0c;是一篇质量分数较高的技术干货文章&…...

使用Vue写一个日期选择器

在 Vue 中实现日期选择器的方法有很多&#xff0c;下面提供一个简单的实现方法。 首先&#xff0c;在需要使用日期选择器的组件中引用 Vue 和 date-fns 库&#xff0c;date-fns 库是一个轻量级的 JavaScript 时间日期工具库&#xff0c;可以方便地处理日期的格式化和计算。 &…...

19、pytest通过mark标记测试函数

官方实例 [pytest] markers slow:marks tests as slow(deselect with -m "not slow")serial# content of test_mark.py import pytestpytest.mark.slow def test_mark_function():print("test_mark_function was invoked")assert 0解读与实操 通过使用p…...

Linux环境变量与命令行参数

Linux环境变量与命令行参数 一.命令行参数1.语法2.应用1:简易计算器 二.环境变量1.环境变量的概念2.环境变量的作用3.进一步理解环境变量的作用4.常见环境变量5.导出环境变量(添加环境变量)6.环境变量的特性7.另一种获取环境变量的方式8.小功能:用于身份验证的代码9.补充:第三种…...

jQuery实现3D轮播图

通过CSS3的3D变换和jQuery Transit插件实现了一个3D旋转的图片轮播效果 HTML部分&#xff1a; div id“banner”&#xff1a;定义了一个id为"banner"的div标签&#xff0c;作为图片轮播的容器。 ul: 在"banner"中定义了一个无序列表&#xff0c;每个列表项…...

Java面试题(每天10题)-------连载(43)

目录 Spring篇 1、请举例说明Qualifier注解 2、构造方法注入和设值注入有什么区别&#xff1f; 3、Spring框架中有哪些不同类型的事件&#xff1f; 4、FileSystemResource和ClassPathResource有什么区别&#xff1f; 5、Spring框架中都用到了哪些设计模式&#xff1f; 6…...

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周&#xff0c;有很多同学在写期末Java web作业时&#xff0c;运行tomcat出现乱码问题&#xff0c;经过多次解决与研究&#xff0c;我做了如下整理&#xff1a; 原因&#xff1a; IDEA本身编码与tomcat的编码与Windows编码不同导致&#xff0c;Windows 系统控制台…...

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…...

日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする

日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...

React Native在HarmonyOS 5.0阅读类应用开发中的实践

一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强&#xff0c;React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 &#xff08;1&#xff09;使用React Native…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)

可以使用Sqliteviz这个网站免费编写sql语句&#xff0c;它能够让用户直接在浏览器内练习SQL的语法&#xff0c;不需要安装任何软件。 链接如下&#xff1a; sqliteviz 注意&#xff1a; 在转写SQL语法时&#xff0c;关键字之间有一个特定的顺序&#xff0c;这个顺序会影响到…...

linux 错误码总结

1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...

AI书签管理工具开发全记录(十九):嵌入资源处理

1.前言 &#x1f4dd; 在上一篇文章中&#xff0c;我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源&#xff0c;方便后续将资源打包到一个可执行文件中。 2.embed介绍 &#x1f3af; Go 1.16 引入了革命性的 embed 包&#xff0c;彻底改变了静态资源管理的…...

Springboot社区养老保险系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;社区养老保险系统小程序被用户普遍使用&#xff0c;为方…...

Android第十三次面试总结(四大 组件基础)

Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成&#xff0c;用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机&#xff1a; ​onCreate()​​ ​调用时机​&#xff1a;Activity 首次创建时调用。​…...

Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)

Aspose.PDF 限制绕过方案&#xff1a;Java 字节码技术实战分享&#xff08;仅供学习&#xff09; 一、Aspose.PDF 简介二、说明&#xff08;⚠️仅供学习与研究使用&#xff09;三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...