OpenCV4学习笔记(75)——ArUco模块之实现AR(增强现实)效果

2023-05-16

今天要整理记录的是利用OpenCV中ArUco模块的aruco标记实现一个增强现实的小应用,当然了本次笔记的内容也是需要建立在之前的《OpenCV4学习笔记(72)》基础上的。

所谓增强现实(Augmented Reality),其实是一种将虚拟信息与真实世界巧妙融合的技术,通过技术手段将计算机生成的文字、图像、三维模型、音乐、视频等虚拟信息模拟仿真后,应用到真实世界中,两种信息互为补充,从而实现对真实世界的“增强”。在这里,我们主要利用aruco标记实现将图像、视频这些虚拟信息应用到拍摄下来的真实世界中。

首先,我们需要创建并打印出四个aruco标记,这四个标记作为我们确定现实增强区域的基准,例如下面这几张图像:在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
可以看到这四个aruco标记包围形成了一个大的四边形区域,这个区域就是我们要进行操作的ROI区域了,当然了还可以把这四个aruco标记裁剪下来,然后贴在门上、窗上、相框中等等场景,这样更有利于增强现实的体现。这里我们就不做裁剪了,就在这张纸上进行实验。下面将这张包含aruco标记的纸图像表述为场景图像。

首先,我们需要对场景图像进行aruco标记的检测,那么就需要先加载拍摄时所用相机的内参矩阵和畸变系数,这里默认已经对相机标定好了,以后有机会再整理一下相机标定的内容。

	//加载图像
	Mat inputImage = imread("D:\\opencv_c++\\opencv_tutorial\\data\\images\\FourMarkerVideo.jpg");
	resize(inputImage, inputImage, Size(600, 800));
	Mat test_image = inputImage.clone();
	//加载相机内参和畸变系数
	cv::Mat cameraMatrix, distCoeffs;
	vector<double> camera = { 657.1548323619423, 0, 291.8582472145741,0, 647.384819351103, 391.254810476919,0, 0, 1 };
	cameraMatrix = Mat(camera);
	cameraMatrix = cameraMatrix.reshape(1, 3);
	vector<double> dist = { 0.1961793476399528, -1.38146317350581, -0.002301820186177369, -0.001054637905895881, 2.458286937422959 };
	distCoeffs = Mat(dist);
	distCoeffs = distCoeffs.reshape(1, 1);

然后对场景图像中的aruco标记进行检测

	//进行标记检测
	auto dictionary = aruco::getPredefinedDictionary(DICT_6X6_250);
	vector<vector<Point2f>>corners, rejectedImaPoints;
	vector<int>ids;
	auto parameters = aruco::DetectorParameters::create();
	aruco::detectMarkers(test_image, dictionary, corners, ids, parameters, rejectedImaPoints, cameraMatrix, distCoeffs);
	//aruco::drawDetectedMarkers(test_image, corners, ids, Scalar(0, 255, 0));

接着我们要寻找所需的ROI区域,也就是四个aruco标记包围而成的一个四边形区域,那么我们需要确定这个四边形的四个顶点。我暂时考虑了两个方法,一是对四个标记的所有角点中的x、y坐标进行排序,找到正数和倒数的前两个值,再进行配对,从而找到四个顶点,这个方法在对于场景图像发生变化时、例如是场景视频的情况下有比较好的效果。二是直接从检测到的四个标记的ID值来索引标记,并获取四边形ROI区域中的对于角点,这个方法相对来说更简单粗暴,但是适用性会比较差,尤其是场景图像发生旋转的情况下比较难达到好的效果。

这里我使用的场景图像是一张固定的图像,也就是上面拍摄的场景图像,所以这里我使用第二个方法

	//提取四个标记形成的ROI区域
	vector<Point2f> roi_box_pt(4);
	//寻找方框的四个顶点,从检测到标记的顺序决定
	roi_box_pt[0] = corners[3][0];
	roi_box_pt[1] = corners[2][1];
	roi_box_pt[2] = corners[0][2];
	roi_box_pt[3] = corners[1][3];

接着我们需要读取要替换ROI区域的目标图像,并提取四个顶点

	//读取替换图像
	Mat new_image = imread("D:\\opencv_c++\\opencv_tutorial\\data\\images\\pig.jpg");
	int width = new_image.cols;
	int height = new_image.rows;
	//提取替换图像的四个顶点
	vector<Point2f> new_image_box(4);
	new_image_box[0] = Point(0, 0);
	new_image_box[1] = Point(width, 0);
	new_image_box[2] = Point(width, height);
	new_image_box[3] = Point(0, height);

然后将目标图像从原视平面到场景图像的视平面做透视变换

	//计算从替换图像到目标ROI图像的3x3单应性矩阵
	Mat H = findHomography(new_image_box, roi_box_pt);
	Mat roi_new_image;
	//进行透视变换
	warpPerspective(new_image, roi_new_image, H, test_image.size(), INTER_CUBIC);

然后为了将场景图像中的ROI区域挖空,我们需要设置一个掩膜,然后和场景图像进行按位与操作,最后将场景图像和目标图像通过加权相加融合,实现对场景图像的增强操作

	//制作掩膜
	Mat mask = Mat(test_image.size(), CV_8UC3,Scalar(255,255,255));
	for (int i = 0; i < roi_new_image.rows; i++)
	{
		for (int j = 0; j < roi_new_image.cols; j++)
		{
			if (roi_new_image.at<Vec3b>(i, j) != Vec3b(0,0,0))
			{
				mask.at<Vec3b>(i, j) = Vec3b(0, 0, 0);
			}
		}
	}
	Mat kernel = getStructuringElement(MorphShapes::MORPH_RECT, Size(3, 3));
	dilate(mask, mask, kernel);
	//用透视变换后的替换图像,替换原图像中的ROI区域
	Mat result;
	bitwise_and(test_image, mask, test_image);
	addWeighted(test_image, 1, roi_new_image, 0.7, 1.0, result);
	namedWindow("result", WINDOW_FREERATIO);
	imshow("result", result);

得到的效果如下:
在这里插入图片描述
由于这里的aruco标记是打印在一张纸上,所以看起来效果没有特别的好,但是试想下如果将它们裁剪下来,并且贴在相框上或者是窗上,再对拍摄下的图像进行增强现实操作,那是不是感觉就不一样了(╹ڡ╹ )

而且,假如我们使用的场景图像是实时视频流中的每一帧图像,那么还可以实现实时拍摄的增强现实效果,这样的话能得到更好的AR体验,当然了这样的话对电脑的要求就会比较高了。。。我也尝试过一下在实时视频流中进行处理,但是卡帧劝退了我。。。

今天尝试着将虚拟图像信息应用到了真实的场景图像中,实现一个比较有趣的AR效果,下次笔记再来尝试一下将视频信息应用到真实场景当中去,那本次笔记到此结束啦。

PS:本人的注释比较杂,既有自己的心得体会也有网上查阅资料时摘抄下的知识内容,所以如有雷同,纯属我向前辈学习的致敬,如果有前辈觉得我的笔记内容侵犯了您的知识产权,请和我联系,我会将涉及到的博文内容删除,谢谢!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

OpenCV4学习笔记(75)——ArUco模块之实现AR(增强现实)效果 的相关文章

  • SpringBoot-快速搭建一套JPA

    文章目录 结构Mavenapplication yml实体类daoservicecontroller测试 结构 Maven span class token tag span class token tag span class token
  • IntelliJ IDEA-Gradle-SpringBoot搭建

    前提条件 IntelliJ IDEA Gradle教学 Gradle 全局镜像配置和优先使用Maven 将Gradle进行安装和配置 创建项目 配置项目设置 指定自己的gradle的安装位置 以及仓库位置 用户主目录 用户主目录 Gradl
  • 我的喜马拉雅FM开播啦!

  • SpringBoot-JAP-JpaSpecificationExecutor详解

    文章目录 SpringBoot JAP JpaSpecificationExecutor详解使用方法接口介绍自定义工厂 SpringBoot JAP JpaSpecificationExecutor详解 JpaSpecificationEx
  • SwitchHosts-快速切换Hosts

    SwitchHosts是一个管理 快速切换Hosts小工具 xff0c 开源软件 xff0c 一键切换Hosts配置 xff0c 非常实用 xff0c 高效 其主要功能特性包括 xff1a 下载地址 https github com old
  • Java-新年抽奖-消息自动化发送脚本

    我们公司7点半开年会 然后大约8点半开始抽奖抢 使用腾讯会议的方式进行发关键字消息然后截图方式抽奖 然而我还在地铁上 手速慢的我只抽到了3等奖小米耳机一个 然后我回家后迫不及待第一时间赶紧使用java写一个机器人脚本 疯狂发消息 一言难尽啊
  • Java多线程-CompletableFuture(链式)

    线程池这个大家都知道 xff0c 是为了提高效率 xff0c 可以类比生活 xff0c 如果开个店 xff0c 需要几个员工 xff0c 正常的操作都是雇佣员工 xff0c 而不是每天使用临时工 xff0c 这样用完就解雇掉 xff0c 对
  • Java-Javassist(字节码修改)

    文章目录 开篇Javassist 常用类Javassist 的使用依赖代码示例 如何实现类似 AOP 的功能 开篇 说起 AOP 小伙伴们肯定很熟悉 xff0c 无论是 JDK 动态代理或者是 CGLIB 等 xff0c 其底层都是通过操作
  • Java多线程-Pip管道

    管道的意思 就是向一个管子一样从一端到另一端 只支持单方向的数据传输 需要注意的不能在同一个线程使用管道否则会导致死锁的情况 发生和接收必须在不同线程 通过使用管道 xff0c 实现不同线程间的通信 xff0c 而无需借助于临时文件之类的东
  • 新版本代码自动生成(MybatisPlus-generator) 代码示例+问题解决

    虽然MybatisPlus官网上已经给出了新版本代码生成器的核心依赖和核心代码 xff0c 但对于没接触过的小伙伴还是比较困难上手 x1f62d xff0c 本文将展现如何使用MybatisPlus generator快速生成代码 目录 1
  • 虚拟机如何使用共享文件夹传文件

    项目场景 xff1a 在使用VMware平台 xff0c ubuntu操作系统时 xff0c ftp文件传输一直报错 问题描述 xff1a 尝试了多种 xff0c 更改电脑设置 xff0c 甚至重装虚拟机 xff0c 始终如下图报错 解决方
  • 强化学习入门DQN详解

    Deep Q Network 参考资料 xff1a B站莫烦 xff1a https www bilibili com video BV13W411Y75P spm id from 61 333 337 search card all cl
  • 某项目因为多次流标导致实际项目时间严重压缩,我该咋办?

    问题 xff1a 某政府项目 xff0c 三个月前就开始招标 xff0c 因各种原因 xff0c 流标三次 xff0c 导致时间拖太长 原计划一期工期三个月 43 xff0c 1月底上线 xff0c 但因为招投标影响直到一个月前签订了合同
  • ROS创建工作空间及功能包流程总结整理(python)

    ROS创建工作空间及功能包流程总结整理 xff08 python xff09 参考资料 xff1a B站赵虚左 xff1a https www bilibili com video BV1Ci4y1L7ZZ p 61 19 amp vd s
  • ROS自定义发布消息类型

    ROS自定义发布消息类型 xff1a 在 ROS 通信协议中 xff0c 数据载体是一个较为重要组成部分 xff0c 在上一案例中 xff0c ROS 中通过 std msgs 封装了一些原生的数据类型 比如 String Int32 In
  • ROS服务通信:自定义数据文件以及服务端和客户端代码编写流程及步骤详解

    ROS服务通信具体实现流程 demo xff1a 实现两个整型数相加求和 xff0c 客户端发送两个整型数 xff0c 服务端对其求和 服务通信也需要自定义服务数据类型 xff0c 即自定义srv文件 xff0c 该过程和自定义msg文件非
  • ROS TF静态坐标变换实现

    ROS TF静态坐标变换实现 法一 xff1a 编码实现 发布方代码实现 xff1a 创建功能包并添加依赖 catkin create pkg tf static roscpp rospy std msgs tf2 tf2 ros tf2
  • ROS:Gazebo导入自定义环境

    Gazebo导入自定义环境 之前的案例gazebo中导入的是一个空世界empty world xff0c 这里会介绍如何导入房屋数目等自定义的环境 xff08 1 xff09 启动 gazebo 打开构建面板 xff0c 绘制仿真环境 xf
  • ROS导航实现:SLAM建图(slam_gmapping)与保存(map_server)

    导航实现 xff1a SLAM建图 先安装相关的ROS功能包 安装 gmapping 包 用于构建地图 sudo apt install ros lt ROS版本 gt gmapping 安装地图服务包 用于保存与读取地图 sudo apt
  • ROS导航实现:amcl定位

    ROS导航实现 xff1a amcl定位 xff08 1 xff09 首先编写启动amcl的launch文件 xff0c 这里建议复制粘贴模板 xff0c 再修改相关的参数即可 xff0c 步骤如下 xff1a 主目录下进入amcl文件 r

随机推荐

  • ROS导航实现之路径规划

    导航实现之路径规划 move base 功能包提供了基于动作 action 的路径规划实现 xff0c move base 可以根据给定的目标点 xff0c 控制机器人底盘运动至目标位置 xff0c 并且在运动过程中会连续反馈机器人自身的姿
  • 创建个人网站(github pages)并将站点一键托管到Github

    创建个人网站 xff08 github pages xff09 并将站点一键托管到Github 内容 xff1a 使用网站生成器mkdocs将markdown文件生成wiki站点并挂载到github的流程总结 亮点 xff1a 个人网站一键
  • 视觉SLAM十四讲(第2版)总结

    最近看完了 视觉SLAM十四讲 xff08 第2版 xff09 xff1a 从理论到实践 xff08 高翔等著 xff09 xff0c 原书分两部分 xff0c 先介绍了数学基础 xff0c 然后介绍了具体的SLAM实践 xff0c 非常适
  • 我的公众号 - 豆芽儿 软件研发人才生长社区

    为你系统分享敏捷开发 项目管理 需求分析 软件设计 UML 中层领导力 CMMI IT职场 ACP 软考 PMP等 高大上 的实用知识 xff0c 帮助你进阶为高端人才 xff01
  • Openblas 下载和使用方法

    Openblas 下载及使用 环境 xff1a 平台 xff1a Ubuntu 20 04 xff0c Orin xff1a Arm Cortex A78AE v8 2 64 bit 步骤 xff1a 1 去github 下载openbla
  • FreeRTOS学习记录

    FreeRTOS学习记录 前言FreeRTOS学习记录在STM32CubeMX中配置FreeRTOS 前言 本人小白 xff0c 最近学习了FreeRTOS操作系统 xff0c 打算做一点记录 学习的过程中虽然做了点练习 xff0c 不过都
  • 如何给华三交换机恢复出厂设置及命令

    如何给华三交换机恢复出厂设置及命令 在前几天 xff0c 上级单位线路重新规划 xff0c 需要我们将单位的线路进行改造 xff0c 这就涉及到了网络设备的重新配置 经查看 xff0c 上级接入交换机的业务端口配置为access xff0c
  • 解决Linux下Docker下载安装太慢

    卸载先前版本 yum remove docker docker span class token operator span client docker span class token operator span client span
  • sqlyong连接docker中的mysql 失败can‘t connect to MySQL server on (*******:3306)

    解决sqlyong连接docker中myslq失败 xff1a 一 查看mysql是否运行docker ps 二 查看mysql端口映射是否与连接相符 三 进入mysql容器查看是否能够进行本地连接docker exec it mysql
  • 解决springboot+webSocket出现404错误

    这是因为websocket创建的bean是由自己来管理的 需要将其创建的bean交给spring管理 创建websocketconfig span class token keyword package span com span clas
  • Bytebuffer源码剖析及实现原理

    Bytebuffer 官方解释A byte buffer xff0c 一个字节缓冲区 一 使用方法 ByteBuffer 初始状态是写模式 使用IO流即可写入数据 如 channel read 如果需要读取ByteBuffer中的数据调用f
  • Linux下安装并配置FTP文件服务器

    一 安装vsftpd 1 运行如下代码安装vsftpd yum install span class token operator span y vsftpd 2 运行以下命令设置FTP服务开机自启动 systemctl enable vs
  • Java 实现 图片OCR文字识别

    Java 实现图片OCR文字识别功能 前言 由于网上很多算法 以及语言库无法做到精准识别 所以综合条件下 使用了一款 space OCR API 的产品进行使用 每个月有25000条的 使用额度 日常使用或开发绰绰有余 网址链接 一 注册
  • js实现表单的校验

    js实现表单校验 CV即用 1 效果图 当每个输入框失去焦点时会通过正则表达式来验证输入的格式是否正确 点击登录按钮后 xff0c 如果有格式不正确的将无法登录 当校验全部通过以后才可以登录 2 源代码 xff1a HTML代码 xff1a
  • 你和国际项目经理(PMP),一步之遥?-张传波-专题视频课程

    你和国际项目经理 PMP xff0c 一步之遥 xff1f 913人已学习 课程介绍 项目管理是门实战性超强的大学问 xff0c 项目经理是一位能把控全局的 狠 角色 xff01 你距离这样的 狠 角色有多远呢 xff0c 你应该如何规划自
  • RTOS任务切换原理与实现

    曾今只是使用过移植好的RTOS进行任务开发 xff0c 对其实现的底层原理一直一知半解 xff0c 正好接触到了李述桐老师的课程以及一些网上的资料 xff0c 让我对实时操作系统的原理有了更深的理解 xff0c 特此把一些原理和思考记录下来
  • python报错:Process finished with exit code -1066598274 (0xC06D007E) 解决方法

    1 在运行Mask RCNN项目时 xff0c 导入官网下载的代码和数据集 xff0c 准备运行时报此错误 2 原因 官网要求python版本是3 4 xff0c 但是我python编译器版本为3 9 3 解决 将编译器版本更换为3 7试试
  • OpenCV4学习笔记(72)——ArUco模块之aruco标记的创建与检测

    今天要整理记录的是OpenCV中ArUco模块的基础内容 xff0c 包含aruco标记的创建与检测 要注意的是ArUco模块是包含在OpenCV的contrib拓展库中的 xff0c 需要自行下载OpenCV基础库和contrib拓展库进
  • OpenCV4学习笔记(74)——ArUco模块之对aruco标记进行实时姿态估计

    在之前的笔记 OpenCV4学习笔记 xff08 72 xff09 中 xff0c 记录了在OpenCV中关于aruco标记的创建和检测这方面的内容 xff0c 今天就基于aruco标记检测来进一步实现对aruco标记的实时姿态估计 首先我
  • OpenCV4学习笔记(75)——ArUco模块之实现AR(增强现实)效果

    今天要整理记录的是利用OpenCV中ArUco模块的aruco标记实现一个增强现实的小应用 xff0c 当然了本次笔记的内容也是需要建立在之前的 OpenCV4学习笔记 xff08 72 xff09 基础上的 所谓增强现实 Augmente