前言
虽然librviz的API里面包含image_view.h的源文件,但是一直到noetic,ros都没有把image_view的共享库编译出来,没有办法,只能通过修改源文件,自己生成共享库。
工具 | 版本 |
---|---|
ros | noetic |
OGRE | 1.9 |
这里需要特别注意,一直到我写这篇文章为止,librviz共享库依赖的都是OGRE1.9,如果你手动安装过OGRE,新的OGRE一定是v13版本以上的,那么需要把新的OGRE卸载了,如果你看不懂这段话,证明你没有安装新的OGRE,那就啥都不用做。
另一种方案
我看到过一种方案就是把接收到的sensor_msgs::Image转化为cv::Image,再用Qt的方法,把cv::Image转化为Qt::Image,因为一直到我写这篇文章之前,Qt都没有提供sensor::Image转化为Qt::Image的方法,这种方案是这样说的:
image_msg=msg;//sensor::Image msg
cv_bridge::CvImagePtr cv_ptr;
cv_ptr = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::BGR8);
QImage temp=Mat2QImage(cv_ptr->image);
temp=temp.scaled(QSize(ui->image_display->width(),ui->image_display->height()));
QPixmap pixmap = QPixmap::fromImage(temp);
ui->image_display->setPixmap(pixmap);
这个方法的一个缺点是延迟大,容易掉帧,如果对于实时性要求比较高,这种方法几乎行不通。
新的方案
可能比较好的办法是用已经有的库,不用重复造轮子,rviz提供了rviz::ImageView类,但是不知道为什么,一直到noetic版本,ros都没有把ImageView的共享库编译出来,因此需要手动下载源代码,手动编译,源文件的地址是:https://docs.ros.org/en/kinetic/api/rviz/html/c++/image__view_8h_source.html
https://docs.ros.org/en/kinetic/api/rviz/html/c++/image__view_8cpp_source.html
分别是头文件和实现文件,但是直接下载下来是不能用的,需要做一些修改,修改完的文件托管在github。
使用方法
只需要把这两个文件放到合适的位置,你的CMakeLists.txt文件可以找到它们就行,这里我是直接把它们放在src文件夹下面(用ros的开发者都知道)。把image_view.cpp文件添加到可执行文件里面。
#include"image_view.h"
ImageVoew* image_show=new ImageView(ui->image_widget,"camera_topic","screenManger_name");
其中ui->image_widget是你在Qt里面预留的一个widget,"camera_topic"是你的相机话题,“screenManager_name"是ogre里面渲染窗口总控的名字,如果了解vtk和ogre的开发者就知道两者都是靠名称(id)来区分渲染对象的。因此如果开发者实例化多个相机显示,就需要设置不同的"screenManger”,以便渲染引擎可以区分。
相对于源码,我做了许多不涉及原理的修改,开发者可以对照两者的区别,为我提意见,但是类似于让Qt::Widget大小自适应图片分辨率等功能我都没有实现。。。