【OpenCV/aruco】第一个AR Demo-二维图片

2023-05-16

  • 说在前面

操作系统:win10

vs 版本:2017

opencv版本:4.0.1

opencv-contrb版本:4.0.1

接上篇:【OpenCV/aruco】校准相机(Camera Calibration) Demo

下一篇:【OpenCV/aruco】第二个AR Demo-画Cube

  •  运行结果

这是个gif

  • 主要流程

1.  获取相机内参(详见上一篇-【OpenCV/aruco】校准相机(Camera Calibration) Demo)

2.  检测marker

3.  通过estimatePoseSingleMarkers()获取相机外参(旋转矢量以及平移矢量

4.  确定marker坐标系中要显示图像的位置,通过(projectPoints())相机内参、外参将3d坐标映射到图像坐标系

5.  计算透视变换getPerspectiveTransform()

6.  将透视变换应用于srcImage(要显示的图片) warpPerspective()

7.  通过imagePoints将frame中marker对应的像素用全零代替 fillConvexPoly()

8.  使用或运算将透视变换后的srcImage贴到frame对应的位置 bitwise_or()

9.  显示frame

  • 代码

srcImage注意一下路径,我放在.cpp的同级目录下,文件名自己改一下。

#include <opencv2\highgui.hpp>
#include <opencv2\videoio.hpp>
#include <opencv2\aruco.hpp>
#include <opencv2\aruco\dictionary.hpp>
#include <opencv2\aruco\charuco.hpp>
#include <opencv2\core.hpp>
#include <opencv2\imgproc\imgproc.hpp>
#include <opencv2\opencv.hpp>

using namespace std;
using namespace cv;
using namespace cv::aruco;

#define WINDOW_NAME "ARDemo"

Mat camMatrix, distCoeffs, srcImage;
float markerLength = 100;

static bool readCameraParameters(const string &filename, Mat &camMatrix, Mat &distCoeffs) {
	FileStorage fs(filename, FileStorage::READ);

	if (!fs.isOpened())
		return false;

	fs["camera_matrix"] >> camMatrix;
	fs["distortion_coefficients"] >> distCoeffs;

	return true;
}

void draw_image(Mat image, Mat & frame, Vec3d & rvec, Vec3d & tvec) {
	vector<Point3f> points;
	vector<Point2f> imagePoints;

	float l = markerLength * 0.5f;

	points.emplace_back(-l, l, 0);//确定每个marker对应的坐标系中四个顶点的位置
	points.emplace_back(l, l, 0);//这个坐标是上一篇中绘制出来的坐标轴中对应的坐标
	points.emplace_back(l, -l, 0);
	points.emplace_back(-l, -l, 0);

	//通过相机内参、外参将3d坐标映射到图像坐标系
	cv::projectPoints(points, rvec, tvec, camMatrix, distCoeffs, imagePoints);

	unsigned int x = (unsigned int)imagePoints[0].x;
	unsigned int y = (unsigned int)imagePoints[0].y;

	vector<Point2f> corners;
	corners.emplace_back(0, 0);
	corners.emplace_back(image.cols, 0);
	corners.emplace_back(image.cols, image.rows);
	corners.emplace_back(0, image.rows);

	//从四对对应点计算透视变换
	cv::Mat T = getPerspectiveTransform(corners, imagePoints);

	//将透视变换应用于image
	Mat warpedImg;
	cv::warpPerspective(image, warpedImg, T, frame.size());

	vector<Point2i> pts;

	for (auto i : imagePoints) {
		pts.emplace_back((int)i.x, (int)i.y);
	}

	//用全0填充凸多边形
	cv::fillConvexPoly(frame, pts, cv::Scalar::all(0), cv::LINE_AA);
	//或运算
	cv::bitwise_or(warpedImg, frame, frame);

	/*cout << points << endl;
	cout << imagePoints << endl;
	cout << corners << endl;
	cout << pts << endl;*/

	/*
	[-50, 50, 0;
	 50, 50, 0;
	 50, -50, 0;
	 -50, -50, 0]
	[98.558197, 147.89699;
	 131.39151, 168.23427;
	 108.73455, 203.80612;
	 75.317993, 184.06393]
	[0, 0;
	 100, 0;
	 100, 100;
	 0, 100]
	[98, 147;
	 131, 168;
	 108, 203;
	 75, 184]
	*/

	//waitKey();
}

int main(int argc, char * argv[]) {

	VideoCapture inputVideo(0);
	//VideoWriter writer("VideoTest.avi", VideoWriter::fourcc('M', 'J', 'P', 'G'), 25.0, Size(640, 480));

	Ptr<aruco::Dictionary> dictionary =
		aruco::getPredefinedDictionary(cv::aruco::DICT_4X4_50);

	bool readOk = readCameraParameters("camera.yml", camMatrix, distCoeffs);
	if (!readOk) {
		cerr << "Invalid camera file" << endl;
		return -1;
	}

	cout << camMatrix << endl;
	cout << distCoeffs << endl;

	srcImage = imread("feng.png");
	resize(srcImage, srcImage, Size(100, 100));

	namedWindow(WINDOW_NAME);

	Mat frame;

	while (inputVideo.grab()) {
		inputVideo >> frame;

		vector<int> ids;
		vector<vector<Point2f>> corners;

		aruco::detectMarkers(frame, dictionary, corners, ids);

		if (ids.size() > 0) {
			vector< Vec3d > rvecs, tvecs;//得到旋转矢量以及平移矢量
			cv::aruco::estimatePoseSingleMarkers(corners, 100, camMatrix, distCoeffs, rvecs, tvecs);

			for (unsigned int i = 0; i < ids.size(); i++) {
				draw_image(srcImage, frame, rvecs[i], tvecs[i]);
			}

			//writer << frame;
		}
		cv::imshow(WINDOW_NAME, frame);

		char key = (char)waitKey(10);
		if (key == 'b')
			break;
	}
	inputVideo.release();
	return 0;
}

 

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

【OpenCV/aruco】第一个AR Demo-二维图片 的相关文章

  • python实现TCP通信

    本例是在Ubuntu虚拟机中本机互传实现的TCP通信 一 TCP服务器端 xff08 server端 xff09 1 创建套接字 xff0c 绑定套接字到本地IP与端口 s 61 socket socket socket AF INET s
  • agrc argv解释

    以前经常看见过 xff1a int main int argc char argv 这样形式的main但是一直没有这样用直到研究点云时发现有个例子是 xff1a gt exe pcd 这样的doc下的命令才想起有这样的两个参数 xff0c
  • 个人面试细节、技巧总结(没有面试题哦!)

    面试除了自身技能过硬外 xff0c 良好的沟通 xff0c 平和的心态 xff0c 细节的拿捏也都是额外的加分项 最后 xff0c 以些许运气加以点缀 xff0c offer 便八九不离十了 参加工作两年有余 xff0c 只大专文凭 xff
  • 【记录】ORB-SLAM3编译以及在realsense D435i运行

    环境 xff1a 最开始用的是源码是ORB SLAM3 的1 0版本 xff0c 但是编译的时候出错太多了 xff0c 超出了能力范围 xff0c 更换了0 4 beta版本 xff0c 但是这个版本在运行的时候会直接segmentatio
  • ArtiPub

    ArtiPub ArtiPub Article Publisher的简称 xff0c 意为 34 文章发布者 34 是一款开源的一文多发平台 xff0c 可以帮助文章作者将编写好的文章自动发布到掘金 SegmentFault CSDN 知乎
  • mac安装配置zsh

    mac安装配置zsh 比mac自带的shell好用太多 一 安装homebrew 参考 xff1a https brew sh index zh cn bin bash c span class token string 34 span c
  • 手把手教你给win10 2004版本的ubuntu1804子系统安装docker

    ubuntu1804子系统安装docker ce 分两种情况 xff1a 1 win10版本小于2004版本2 win10版本大于2004版本 一 说明 win10版本小于2004的话 xff0c 可以使用WSL1 0 xff0c WSL1
  • windows安装scoop

    参考 xff1a https scoop sh 参考 xff1a https github com lukesampson scoop wiki Quick Start 懂不懂 xff0c 先装上 xff0c 这样你就完成了该工具学习的第一
  • PX4飞控学习(五)

    PX4的应用 程序入口为 程序名 main int argc char argv 这里实现应用参数 主循环函数在 task main int argc char argv thread main int argc char argv 等函数
  • 转载kubernetes 1.9 与 CentOS 7.3 内核兼容问题

    20201022转载kubernetes 1 9 与 CentOS 7 3 内核兼容问题 原文 xff1a http www linuxfly org kubernetes 19 conflict with centos7 生产环境发现不定
  • 【转载】为什么说Prometheus是足以取代Zabbix的监控神器?

    原文 xff1a https www infoq cn article 275NDkYNZRpcTIL2R8Ms 原文 xff1a https mp weixin qq com s biz 61 MzI4NTA1MDEwNg 61 61 a
  • 【转载】K8S 问题排查:cgroup 内存泄露问题

    转载 K8S 问题排查 xff1a cgroup 内存泄露问题 原文 xff1a http www xuyasong com p 61 2049 前言 这篇文章的全称应该叫 xff1a 在某些内核版本上 xff0c cgroup 的 kme
  • 【可用】prometheus邮件报警配置

    参考 xff1a https github com prometheus alertmanager issues 384 参考 xff1a https github com easzlab kubeasz issues 448 使用QQ邮箱
  • 【案例】微服务-中台-业务关系图(来自processon)

    微服务 中台 业务关系图 知识云微服务架构 微服务开发平台规划架构图 微服务架构图 物联网微服务无业务架构 阿里中台技术在大型企业数字化转型的架构图 阿里中台战略笔记
  • prometheus监控域名证书到期时间

    参考 xff1a https mp weixin qq com s gXffcNzixAiTKSBZcf2sBA 最终效果图 xff1a 下面全部使用docker部署 xff1a 一 部署prometheus 这是一个默认的promethe
  • windows更新后无法上网问题(wifi和有线都不行)

    我真是个既倒霉又幸运的孩子 曾经 xff0c 有人在旁边抱怨 xff1a 该死的微软 xff0c 更新了一堆bug xff01 我没有理他 xff0c 因为它没有影响到我 xff0c 我很开心 曾经 xff0c 又有人在旁边抱怨 xff1a
  • 服务器上的 Git - Gitosis

    公司有这个东西 xff0c 之前一直没研究过这个是啥 xff0c 原来就是git的一个权限管理工具 xff0c 可以用来搭建git服务器 xff0c 当然gitlab更好用 具体请参考 xff1a 服务器上的 Git Gitosis 本篇文
  • MAC重装

    options 43 command 43 r xff0c 开机长按 xff0c 抹掉磁盘 xff0c 在线安装
  • 深度强化学习专栏 —— 3.实现一阶倒立摆

    我将文章发表在了古月居 xff0c 一起来看看吧 xff01 戳这里 猜你想看 xff1a 深度强化学习专栏 1 研究现状深度强化学习专栏 2 手撕DQN算法实现CartPole控制深度强化学习专栏 3 实现一阶倒立摆pybullet杂谈
  • mysql导入数据报错ERROR 1290 (HY000): The MySQL server is running with the --secure-file-priv option so it

    参考 xff1a https blog csdn net u011677147 article details 64129606 参考 xff1a http blog itpub net 31015730 viewspace 2152273

随机推荐

  • 第五章

    一 master节点生成密钥 发送至所有node节点 span class token punctuation span root localhost span class token punctuation span span class
  • linux中的&符号

    很好的文章 xff0c 文件描述符那个一直不是很懂 xff1a https www linux com blog learn 2019 2 ampersands and file descriptors bash https www lin
  • 三剑客20190714

    最后wordpress项目 xff1a main yml root 64 jenkins wordpress playbooks cat roles wordpress tasks main yml name Update yum depe
  • office2019中不包含onenote2016

    office2019中不包含onenote office2019中不包含onenote xff0c 而windows自带的onenote界面又大改 xff0c 完全不适应 xff0c 如何下载onenote2016 一 进入onenote下
  • kubernetes 1.15.1 高可用部署 -- 从零开始

    kubernetes 1 15 1 高可用部署 从零开始 晚点开始部署
  • prometheus和node_exporter部署

    监控体系 前面一篇文章对prometheus作了简单的入门了解 xff0c 在安装prometheus和node exporter之前先对监控体系做一下梳理 xff0c 更直观的讲可以分为iaas paas xff0c saas三个维度来说
  • ROS的一些基础的知识,自用

    零散小知识 先参考这个博客 再参考这个博客总结的知识点 查看当前所以发布的话题名 rostopic list 让ros一直调用回调函数 xff0c ros spin如下的代码无效函数 ros span class token operato
  • TMS320F28377X芯片can通信心得笔记(2)——流程细节

    一 xff0c 前言 补充上一篇文章 TMS320F28377X芯片can通信心得笔记 xff0c 之前一直找不到清晰又压缩的方式把图片缩小 二 xff0c 补充流程如图片和部分代码 带颜色 和带 号部分为中断配置 1 CAN配置部分代码
  • IDEA创建一个servlet项目

    1 File gt project gt java project 选中web application 如果选择java Enterprise可以免去后期导入servlet api jar包和配置Tomcat xff0c 但是需要在proj
  • STM32系列单片机的标准外设库、HAL库和LL库的区别和介绍

    本文转载自CSDN博客 xff1a ZCShouEXP xff0c 点击此处跳转至原博客 STM32 Embedded Software 工作以来一直使用意法半导体 xff08 ST xff09 的STM32系列MCU xff0c ST为开
  • Github的wiki编写

    全球最大的wiki xff0c 应该就是维基百科吧 xff0c 其实百度百科 xff0c csdn写博客等等也是wiki 不久前自己接触了Github wiki的编写 xff0c 因此做个记录吧 模式一般选择Markdown xff0c 因
  • EGOPlanner—Prometheus代码阅读笔记汇总

    Prometheusv2中的EGOSwarm代码阅读笔记 xff0c 个人学习用 目前还有部分代码没看明白 xff0c 欢迎大家交流 xff01 主要参考资料 xff1a Fast Planner 代码解读参考资料整理 EGO Swarm代
  • UAVControl—Prometheus代码阅读笔记【二】——节点实现

    Prometheusv2中的uav control代码阅读笔记 xff0c 个人学习用 内容正在补充中 xff0c 欢迎大家交流 xff01 代码来源 xff1a https github com amov lab Prometheus 二
  • 记录Ubuntu server不能输入中文的全记录--没有解决(最后靠装的桌面版+x11vnc解决)

    1 网上查到的资料都是针对桌面版本的 xff0c 所以先安装了一个vnc桌面 xff0c 至少右击可以看到包含了系统属性 参考链接 xff1a https blog csdn net wayway0554 article details 8
  • int 和 Integer的区别

    int 和 Integer的区别 分析intIntegerint 与 Integer 的区别相同值下的 int 和 Integer 的比较结果 分析 int int 是java的基本数据类型 Integer Integer 继承了Objec
  • C/C++ 使用信号量控制线程运行顺序

    span class token macro property span class token directive keyword include span span class token string lt stdio h gt sp
  • C++ 问题整理

    说一下C 43 43 和C的区别 设计思想上 xff1a C 43 43 是面向对象的语言 xff0c 而 C 是面向过程的结构化编程语言 C 43 43 具有封装 继承和多态三种特性 C 43 43 支持范式编程 xff0c 比如模板类
  • 职业向导 - 面试题目汇总(嵌入式篇)

    自己踩的坑 存储类操作系统类总线类工具实用类基本电路知识类计算机语言类 存储类 SDRAM SRAM DRAM PSRAM xff0c NOR Flash Nand Flash不同 TablesChineseFull NameSDRAMab
  • ROS笔记(一)xxx.launch文件详解

    ROS笔记 一 xxx launch文件详解 launch文件是ROS中用于同时启动多个节点的重要文件 在大型的ROS项目中使用频繁 所以掌握其主要元素与属性对ROS系统的应用至关重要 xff1a launch标签 元素 说明launch拓
  • 【OpenCV/aruco】第一个AR Demo-二维图片

    说在前面 操作系统 xff1a win10 vs 版本 xff1a 2017 opencv版本 xff1a 4 0 1 opencv contrb版本 xff1a 4 0 1 接上篇 xff1a OpenCV aruco 校准相机 Came