rviz是如何获取图像里选择的点云的3D坐标的

以前以为rviz是用OpenGL渲染绘图,那么获取图像里像素点对应的真实3D坐标是采用的OpenGL里提供的API实现的,结果一看代码还真不是这样,rviz也就渲染用了OpenGL,其他都是自己实现的,图像界面的实现完全是遵循MVC设计模式自己实现的透视投影和坐标转换等所有相关类。获取点云图像里所选择的点云点的3D坐标相关的代码是这里:

src/rviz/selection/selection_manager.cpp:bool SelectionManager::getPatchDepthImage(Ogre::Viewport* viewport,int x,int y,unsigned width,unsigned height,std::vector<float>& depth_vector)
{unsigned int num_pixels = width * height;depth_vector.reserve(num_pixels);setDepthTextureSize(width, height);M_CollisionObjectToSelectionHandler::iterator handler_it = objects_.begin();M_CollisionObjectToSelectionHandler::iterator handler_end = objects_.end();for (; handler_it != handler_end; ++handler_it){handler_it->second->preRenderPass(0);}if (render(viewport, depth_render_texture_, x, y, x + width, y + height, depth_pixel_box_, "Depth",depth_texture_width_, depth_texture_height_)){uint8_t* data_ptr = (uint8_t*)depth_pixel_box_.data;for (uint32_t pixel = 0; pixel < num_pixels; ++pixel){uint8_t a = data_ptr[4 * pixel];uint8_t b = data_ptr[4 * pixel + 1];uint8_t c = data_ptr[4 * pixel + 2];int int_depth = (c << 16) | (b << 8) | a;float normalized_depth = ((float)int_depth) / (float)0xffffff;depth_vector.push_back(normalized_depth * camera_->getFarClipDistance());}}else{ROS_WARN("Failed to render depth patch\n");return false;}handler_it = objects_.begin();handler_end = objects_.end();for (; handler_it != handler_end; ++handler_it){handler_it->second->postRenderPass(0);}return true;
}bool SelectionManager::get3DPatch(Ogre::Viewport* viewport,int x,int y,unsigned width,unsigned height,bool skip_missing,std::vector<Ogre::Vector3>& result_points)
{boost::recursive_mutex::scoped_lock lock(global_mutex_);ROS_DEBUG("SelectionManager.get3DPatch()");std::vector<float> depth_vector;if (!getPatchDepthImage(viewport, x, y, width, height, depth_vector))return false;unsigned int pixel_counter = 0;Ogre::Matrix4 projection = camera_->getProjectionMatrix();float depth;for (unsigned y_iter = 0; y_iter < height; ++y_iter)for (unsigned x_iter = 0; x_iter < width; ++x_iter){depth = depth_vector[pixel_counter];// Deal with missing or invalid pointsif ((depth > camera_->getFarClipDistance()) || (depth == 0)){++pixel_counter;if (!skip_missing){result_points.push_back(Ogre::Vector3(NAN, NAN, NAN));}continue;}Ogre::Vector3 result_point;// We want to shoot rays through the center of pixels, not the corners,// so add .5 pixels to the x and y coordinate to get to the center// instead of the top left of the pixel.Ogre::Real screenx = float(x_iter + .5) / float(width);Ogre::Real screeny = float(y_iter + .5) / float(height);if (projection[3][3] == 0.0) // If this is a perspective projection{// get world-space ray from camera & mouse coordOgre::Ray vp_ray = camera_->getCameraToViewportRay(screenx, screeny);// transform ray direction back into camera coordsOgre::Vector3 dir_cam = camera_->getDerivedOrientation().Inverse() * vp_ray.getDirection();// normalize, so dir_cam.z == -depthdir_cam = dir_cam / dir_cam.z * depth * -1;// compute 3d point from camera origin and direction*/result_point = camera_->getDerivedPosition() + camera_->getDerivedOrientation() * dir_cam;}else // else this must be an orthographic projection.{// For orthographic projection, getCameraToViewportRay() does// the right thing for us, and the above math does not work.Ogre::Ray ray;camera_->getCameraToViewportRay(screenx, screeny, &ray);result_point = ray.getPoint(depth);}result_points.push_back(result_point);++pixel_counter;}return !result_points.empty();
}bool SelectionManager::get3DPoint(Ogre::Viewport* viewport, int x, int y, Ogre::Vector3& result_point)
{ROS_DEBUG("SelectionManager.get3DPoint()");std::vector<Ogre::Vector3> result_points_temp;bool success = get3DPatch(viewport, x, y, 1, 1, true, result_points_temp);if (result_points_temp.empty()){// return result_point unmodified if get point fails.return false;}result_point = result_points_temp[0];return success;
}

世界3D坐标是用的射线法计算出来。SelectionManager::get3DPoint()被rviz里多个地方调用,凡是UI界面上需要查看点的坐标地方都是调用它。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/154450.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LeetCode100122. Separate Black and White Balls

文章目录 一、题目二、题解 一、题目 There are n balls on a table, each ball has a color black or white. You are given a 0-indexed binary string s of length n, where 1 and 0 represent black and white balls, respectively. In each step, you can choose two a…

C++ 输入输出优化

对比广大博客之后总结如下。 有些题目强制要求在线&#xff0c;输出需要flush&#xff0c;那么这里输出只用cout&#xff0c;cout<<endl。 只开ios优化&#xff0c;不开cin.tie和cout.tie。 read()快读 输入整数。 inline int read(){int x0;char cgetchar();while(c…

4本期刊被踢!11月SCI/SSCI目录已更新

​2023年11月20日&#xff0c;科睿唯安更新了Web of Science核心期刊目录。 此次更新后SCIE期刊目录共包含9481本期刊&#xff0c;SSCI期刊目录共包含3551本期刊。此次SCIE & SSCI期刊目录更新&#xff0c;与上次更新&#xff08;2023年10月&#xff09;相比&#xff0c;共…

git进阶使用《多账号管理》

git 多账号管理 解决问题&#xff1a;同一台电脑&#xff0c;N 个 github 账号同时存在&#xff0c;需要对应 N 个 github 账号的 SSH key 1、运行 git Bash 客户端&#xff0c;输入如下代码&#xff1a; $ cd ~/.ssh $ ls2、创建一个 SSH key $ ssh-keygen -t rsa -C "…

模拟shell小程序

接下来利用我们当前的知识&#xff0c;撰写一个简单的shell外壳程序。 1.shell原理 shell的原理是实际上就是运行了一个父进程&#xff0c;然后创建出子进程&#xff0c;最后使用进程替换调用&#xff0c;替换成其他程序。 2.shell实现 2.1.死循环 首先一个shell一旦运行起…

解决Spring Cloud整合Nacos与Gateway的探险之旅

&#x1f38f;&#xff1a;你只管努力&#xff0c;剩下的交给时间 &#x1f3e0; &#xff1a;小破站 解决Spring Cloud整合Nacos与Gateway的探险之旅&#xff08;报错汇总&#xff09; 前言Caused by: com.alibaba.nacos.shaded.io.grpc.netty.shaded.io.netty.channel.Abstra…

PixCake:让你的照片焕发新生的AI人像处理技术修图软件

大家好&#xff01;今天我要向大家推荐一款令人惊艳的AI人像处理技术修图软件——PixCake像素蛋糕。无论你是摄影爱好者还是普通用户&#xff0c;PixCake都能帮助你将照片修饰得更加出色、生动。 PixCake拥有强大的AI人像处理技术&#xff0c;可以自动识别照片中的人物&#x…

建筑可视化中的 3D 纹理

在线工具推荐&#xff1a; 三维数字孪生场景工具 - GLTF/GLB在线编辑器 - Three.js AI自动纹理化开发 - YOLO 虚幻合成数据生成器 - 3D模型在线转换 - 3D模型预览图生成服务 1、什么是 3D 纹理&#xff1f; 纹理是将二维图像添加到三维模型的技术艺术。虽然对物体进行纹…

Linux安装Mysql详细教程(两种安装方法)

Linux之Mysql安装配置 第一种&#xff1a;Linux离线安装Mysql&#xff08;提前手动下载好tar.gz包&#xff09;第二种&#xff1a;通过yum安装配置Mysql&#xff08;服务器有网络&#xff09; 第一种&#xff1a;tar.gz包安装 1、 查看是否已经安装 Mysql rpm -qa | grep m…

计算机网络的标准化工作及相关组织

一、国际化组织 计算机网络的标准化工作由一些主要的组织来进行管理和推动。以下是几个主要的计算机网络标准化的国际组织及其相关的标准&#xff1a; 1. 国际标准化组织&#xff08;ISO&#xff09;&#xff1a;国际标准化组织负责制定各种行业的标准&#xff0c;包括计算机…

为什么游戏公司选择物理服务器

为什么游戏公司选择物理服务器 1、选择的自由 选择游戏物理服务器可让我们根据需要自由选择和配置硬件。在完成设置和配置新获得的游戏服务器的所有艰苦工作后&#xff0c;请始终查看我们获得的价格&#xff0c;以确保自己拥有足够的带宽资源、端口容量和CPU核心&#xff0c;以…

JVM线程的几种状态

1.New 新建的线程&#xff0c;线程还没启动。 2.Runnable 线程正在运行或者等待操作系统中的其他资源&#xff0c;例如线程运行过程中&#xff0c;系统分配资源给其他操作&#xff0c;此时这个线程还是Runnable状态&#xff0c;可以理解为可运行的线程。 3.Blocked 阻塞状…

SpringBoot 整合 Freemarker

通过 Freemarker 模版&#xff0c;我们可以将数据渲染成 HTML 网页、电子邮件、配置文件以及源代码等。 Freemarker 不是面向最终用户的&#xff0c;而是一个 Java 类库&#xff0c;我们可以将之作为一个普通的组件嵌入到我们的产品中。 Freemarker 模版后缀为 .ftl(FreeMarke…

Nginx部署前端项目

Nginx部署前端项目 1.在nginx官网http://nginx.org/en/download.html &#xff0c;下载稳定版本&#xff1a; 2.解压后&#xff0c;点击根目录中的nginx.exe即可启动Nginx&#xff0c;或是在nginx安装目录中启动cmd并输入以下命令启动&#xff1a; nginx.exe 或 start nginx3…

Apahce虚拟主机配置演示

在企业的真实环境中&#xff0c;一台WEB服务器发布单个网站会非常浪费资源&#xff0c;所以一台WEB服务器一般都会发布多个网站&#xff0c;少则3-5个&#xff0c;多个10-20个网站。在一台服务器上发布多网站&#xff0c;也称之为部署多个虚拟主机。 WEB虚拟机主机配置方法主要…

开源之夏2023 MatrixOne 项目结业啦

开源之夏是由中国科学院软件研究所与 OpenEuler 社区共同主办的一项面向高校学生的暑期在线活动&#xff0c;旨在鼓励在校学生积极参与开源软件的开发维护&#xff0c;促进优秀开源软件社区的蓬勃发展。 在开源之夏 2023 年中&#xff0c;MatrixOne 一共有 2 个任务项目&#…

Linux:firewalled服务常规操作汇总

一、firewalled防火墙工作原理 firewalled的内部结构&#xff0c;可以简单的看做下图&#xff0c;有两个集合&#xff0c;一个集合管理关闭的端口&#xff0c;另一个集合管理放开的端口。 二、常用操作 1、开启和关闭防火墙 临时性配置&#xff1a; systemctl [start | stop …

KT142C语音芯片搭配HAA2018功放,两个板子,一个声音正常一个没有声音

KT142C芯片搭配HAA2018功放&#xff0c;焊了两个板子&#xff0c;一个声音正常&#xff0c;一个没有声音&#xff0c;该如何分析解决问题呢&#xff1f; 客户提出来的这个问题&#xff0c;原理图如下&#xff1a;分析问题的步骤如下&#xff1a; 可以看出来芯片的原理图部分没有…

《算法通关村—进制转换问题处理模板》

《算法通关村—进制转换问题处理模板》 先来一个题热热身 504. 七进制数 给定一个整数 num&#xff0c;将其转化为 7 进制&#xff0c;并以字符串形式输出。 示例 1: 输入: num 100 输出: "202"示例 2: 输入: num -7 输出: "-10"提示&#xff1a; …

Git 标签

如果你达到一个重要的阶段&#xff0c;并希望永远记住那个特别的提交快照&#xff0c;你可以使用 git tag 给它打上标签。 比如说&#xff0c;我们想为我们的 runoob 项目发布一个"1.0"版本。 我们可以用 git tag -a v1.0 命令给最新一次提交打上&#xff08;HEAD&a…