片段性的总结
- Vins-Fusion的小总结
- RGBA图格式
- RGB和BGR图区别
- cv::copyTo蒙版mask的使用
- 查找可执行文件调用的库目录
- QT5源码库可以使得opencv的imshow显示像素值
- 重新编译时出问题,建议清除所有编译产生的文件,再进行重新编译
- 代码调试总结1
- 代码调试总结2
- 读取RGB图像RGB分量方法
- RVIZ给点云加上RGB信息
- make install 设置安装路径
- 快速得到当前目录的方法
- 图像降采样方法以及注意问题
- ROS缺少某种依赖,但是不知道依赖包名字,查找方法
- opencv中文相关查询网址
- Eigen的欧拉角顺序
- EVO评估工具的使用
- CMake中自定义调用Eigen版本
- CMake中自定义调用Opencv版本
- 编译通过,但是运行可执行文件仍缺少动态库(.so)
- 查找当前目录包含某个关键词的文件
- cv::Mat::step
- docker一键安装
- SSH进行远程copy
- 通过NFS,ssh挂载远程目录镜像
- 命令行安装出现依赖问题无法安装
- ubuntu桌面版添加开机自启动程序
- Ros安装
Vins-Fusion的小总结
- 整个工程的主入口就是vins_estimator:: rosNodeTest.cpp,在main函数中由registerPub(n);声明了一堆需要发布的消息的发布器
- 同时还会订阅IMU_TOPIC、IMAGE_TOPIC并进行回调把已经到来的图片和IMU信息都存储起来,等待后续进程的处理。这里就和ORBSLAM不一样,对于来不及处理的帧会被覆盖掉,但是vins基本不会,因为它把这些数据都先存储起来,所以这就能解释为什么TX2运行vins时不丢失但是会因为来不及处理摄像头传来的这么多帧把内存堆满,出现延迟的情况。
- 主函数会创建另一个进程去运行sync_process函数,这个函数也主要是对存放image的topic的容器进行读取并处理,通过函数inputImage对每一帧(双目的左右帧,时间对齐)进行光流跟踪和对featureBuf容器的填充。
值得注意的是
if(MULTIPLE_THREAD)
{
if(inputImageCnt % 2 == 0)
{
mBuf.lock();
featureBuf.push(make_pair(t, featureFrame));
mBuf.unlock();
}
}
这里inputImageCnt(处理的帧数)是能整除2的时候才会对featureBuf进行填充,就是说明处理了两帧,featureBuf才会填充一帧的信息。
- MULTIPLE_THREAD是一个参数文件读取的参数,是否对void Estimator::processMeasurements()函数进行分线程运行,一般都会这么干。
- 该函数处理各种buffer里面的东西,当featureBuf不等于空时,开始进行以下处理(为什么是featureBuf,因为当有图像buffer数据的时候,才会有featuretracker.push(make_pair(t,featureFrame)),即有图像数据后,程序才发给跟踪器叫他产生feature,因此当featureBuf不等于空,所有的buffer,包括imu,图像,都不为空):
processIMU(): 对IMU进行预积分
processIMage():对图像进行处理
pub VIO的各种话题,包括里程计信息,tf变换,相机姿态,点云信息,并且发布关键帧。 - 也就因为当featureBuf不等于空时,开始进行以下处理,而featureBuf处理了两帧,featureBuf才会填充一帧的信息,所以会出现processMeasurements()函数发布出来的消息频率比image_traker要低。
- 想要让processMeasurements()函数发布的topic频率变高,1、是在硬件处理速度允许的情况下提升前端图片topic的频率(摄像头采集图片的频率),2、把inputImageCnt % 2 == 0的判断去掉,让其每帧都能对featureBuf进行填充
RGBA图格式
RGBA是代表Red(红色)Green(绿色)Blue(蓝色)和Alpha的色彩空间。虽然它有的时候被描述为一个颜色空间,但是它其实仅仅是RGB模型的附加了额外的信息。采用的颜色是RGB,可以属于任何一种RGB颜色空间,但是Catmull和Smith在1971至1972年间提出了这个不可或缺的alpha数值,使得alpha渲染和alpha合成变得可能。提出者以alpha来命名是源于经典的线性插值方程αA + (1-α)B所用的就是这个希腊字母。
alpha通道一般用作不透明度参数。如果一个像素的alpha通道数值为0%,那它就是完全透明的(也就是看不见的),而数值为100%则意味着一个完全不透明的像素(传统的数字图像)。在0%和100%之间的值则使得像素可以透过背景显示出来,就像透过玻璃(半透明性),这种效果是简单的二元透明性(透明或不透明)做不到的。它使数码合成变得容易。alpha通道值可以用百分比、整数或者像RGB参数那样用0到1的实数表示。
RGBA是四通道
RGB是三通道
两个的形式的图转灰度图需要区分
RGB和BGR图区别
R代表红,red; G代表绿,green; B代表蓝,blue。RGB模式就是,色彩数据模式,R在高位,G在中间,B在低位。BGR正好相反。 ,转化成灰度图的时候需要进行区分
if(mImGray.channels()==3)
{
if(mbRGB)
cvtColor(mImGray,mImGray,CV_RGB2GRAY);
else
cvtColor(mImGray,mImGray,CV_BGR2GRAY);
}
else if(mImGray.channels()==4)
{
if(mbRGB)
cvtColor(mImGray,mImGray,CV_RGBA2GRAY);
else
cvtColor(mImGray,mImGray,CV_BGRA2GRAY);
}
cv::copyTo蒙版mask的使用
如果mask不是NULL,也就是说mask是一个数组,并且是一个和dst or src大小完全一致的数组。
这时遍历src的每一个元素,
(1)在位置i时候如果mask对应的值为不为0,那么把src (i) 的值复制给dst (i) 。
(2)如果mask(i) 为0,那么不管src(i)是什么,dst(i)都设置为0.
mask = NULL 意思就是没有模板、不使用掩码操作
特别注意:
mask必须是CV_8U类型
srcImage.copyto(dstImage, mask),mask作为一个掩模板,如果在某个像素点(i, j)其值为1(只看第一通道,所以mask单通道即可)则把srcImage.at(i, j)处的值直接赋给dstImage.at(i, j),如果其值为0则dstImage.at(i, j)处保留其原始像素值
关于此函数的源码解析可查看:http://blog.csdn.net/jdpshq/article/details/9007627
查找可执行文件调用的库目录
可用来有效查询例如某个工程调用了哪个版本的opencv
ldd (bin name)
QT5源码库可以使得opencv的imshow显示像素值
前提这张图片是CV_8U数据类型
在opencv编译前,在CMakeLists文件中会有一些功能的开关
找到
OCV_OPTION(WITH_QT
"Build with Qt Backend support"
OFF IF (NOT ANDROID AND NOT IOS AND NOT WINRT) )
把OFF改为ON,重新编译,以及安装,安装前需要先看好,安装的路径,如果直接安装到usr/bin下有可能会覆盖之前版本,所以可以选择安装在当前需要该opencv版本的工程下,但是需要该工程的调用路径
重新编译时出问题,建议清除所有编译产生的文件,再进行重新编译
- ros工程需要删除除了build之外的还有devel,log等凡是编译后产生的配置文件
- 如果时简单的CMakeLists工程,只需删除buid下的文件
代码调试总结1
- 调试过程中,逐步推敲,问题出现在哪一步
- 找到出现问题的地方,并且这时候去验证到该步的数据是否都是正确的,逐个数据去验证
- 例如这里:
- 灰度情况下是没有问题的,加了RGB信息之后就有了问题,说明就是这个RGB信息添加的部分出了问题
- 视差计算前,以及点云计算前都去验证出现在哪一部,视差计算,视差图是准确的说明没有问题,点云计算,灰度图传入下是没问题,RGB图传入就有问题,说明就是点云计算出现了问题
- 验证点云计算输入的数据是否都是准确的,左右图,以及采集RGB的图,左右图要求是基线校正后,用于计算视差的图,采集RGB图要求是和左图是一样,逐个打印验证
- 只有验证完代码问题,才需要考虑是否理论基础的理解不够以及须添加额外处理
代码调试总结2
- 出现问题,要详细回看GitHub页面,有可能是某一步的配置出现遗漏
- 开源代码编译出错,可以考虑改变分支,以及回退更新版本
- 开源代码编译出错,最终可能需要回看源代码,找出出错位置,用cout输出所在函数名称或者if判断的函数。可以进行大范围的cout打印,逐渐缩小范围
读取RGB图像RGB分量方法
指针偏移
pixel_rgb_ptr=rectified_stereo_pair.image_left_color.ptr<unsigned char>(v);
其中指针偏移要注意
const uint8_t b = pixel_rgb_ptr[3 * u];
const uint8_t g = pixel_rgb_ptr[3 * u + 1];
const uint8_t r = pixel_rgb_ptr[3 * u + 2];
其中v是行,u是列,bgr存储顺序是并列存储,那么图像实际存储的尺寸是3widthheigh
cv::Vec3b
const uint8_t b=rectified_stereo_pair.image_left_color.at<cv::Vec3b>(v,u)[0];
const uint8_t g=rectified_stereo_pair.image_left_color.at<cv::Vec3b>(v,u)[1];
const uint8_t r=rectified_stereo_pair.image_left_color.at<cv::Vec3b>(v,u)[2];
这种方法不需要进行偏移,只需要给行v列u坐标就可以得到当前bgr分量的数组
- 存储的顺序是bgr不是rgb
- 高位是r低位是b,因此再ros点云添加rgb时候要注意高低位。
RVIZ给点云加上RGB信息
- ros的RVIZ使得点云有颜色显示,这里涉及到sensor_msgs::PointCloud2的理解,其中PointField[] fields成员变量是关键,参考http://wiki.ros.org/pcl/Overview
make install 设置安装路径
-
make install不能随意使用,很可能被安装到/user/bin/中覆盖掉已有环境数据。因此在编译一些工程时候对于仅现当前工程使用的库,建议制定安装目录
方法一:
cmake -DCMAKE_INSTALL_PREFIX=/usr ..
方法二:
修改cmake文件,加入:
SET(CMAKE_INSTALL_PREFIX < install_path >)
方法三:
export DESTDIR=/INSTALL/DIR make install
方法四:
make DESTDIR=/install/directory install
快速得到当前目录的方法
- pwd可以直接打印当前目录或者直接把某一文件拉入终端可得到当前文件路径
图像降采样方法以及注意问题
进行图像1/4的降采样以及内参的也进行1/4的减小
-
这里值得注意的是,在降采样/上采样过程中,要确保图片能够正确读取,否则会出现错误
eror: (-215:Assertion failed) !_src.empty() in function 'cv::pyrDown_'
-
使用cv::pyrDown,或者cv::resize进行降采样,一次只能是缩放1/2,那么缩放1/4可集执行两次1/2缩放
ROS缺少某种依赖,但是不知道依赖包名字,查找方法
官方提供方法,可在ROS安装教程界面找到
-
apt-cache search ros-kinetic(版本号)
如果环境中缺失某些依赖,可查找ros相关的功能包
opencv中文相关查询网址
http://www.opencv.org.cn/forum/
opencv的中文资料
https://docs.opencv.org/master/index.html
opencv document直接输入函数名可以查找相关信息
Eigen的欧拉角顺序
Eigen::Vector3d euler_angles = rotation_matrix.eulerAngles ( 2,1,0 );
// ZYX顺序,即 yaw pitch roll顺序
EVO评估工具的使用
evo_traj tum evo_xag75.txt --plot
CMake中自定义调用Eigen版本
FIND_PACKAGE(Eigen3 REQUIRED NO_MODULE PATHS /home/fei/git-project/openmvs_keo/eigen_install NO_DEFAULT_PATH)
if(EIGEN3_FOUND)
INCLUDE_DIRECTORIES(${EIGEN3_INCLUDE_DIRS})
ADD_DEFINITIONS(${EIGEN_DEFINITIONS} -D_USE_EIGEN)
message("EIGEN_INCLUDE_DIRS: ${EIGEN_INCLUDE_DIRS}")
message("EIGEN3_INCLUDE_DIRS: ${EIGEN3_INCLUDE_DIRS}")
SET(_USE_EIGEN TRUE)
endif()
这里的路径就是Eigen的安装路径,和opencv不一样,要注意eigen安装后也是有.cmake文件的。如果没有则是安装有问题,编译会出现找不到eigen的错误
CMake中自定义调用Opencv版本
find_package(OpenCV REQUIRED NO_MODULE PATHS /home/fei/OpenCV/opencv3.3.1/opencv3.3.1-install/lib/cmake/opencv4 NO_DEFAULT_PATH)
if(OpenCV_FOUND)
INCLUDE_DIRECTORIES(${OpenCV_INCLUDE_DIRS})
ADD_DEFINITIONS(${OpenCV_DEFINITIONS})
SET(_USE_OPENCV TRUE)
MESSAGE(STATUS "OpenCV ${OpenCV_VERSION} found (include: ${OpenCV_INCLUDE_DIRS})")
else()
MESSAGE("-- Can't find OpenCV. Please specify OpenCV directory using OpenCV_DIR variable")
endif()
需要注意的是,这里的路径是安装路径下包含.cmake文件的路径,注意:不同的版本可能路径不一样,不能随意照搬
编译通过,但是运行可执行文件仍缺少动态库(.so)
error while loading shared libraries: libopencv_highgui.so.3.0:
cannot open shared object file
一般可执行文件静态库已经被编译进了文件中,但是动态文件(.so)可能需要指定路径,特别是移植可执行文件到别的机器上的时候,就容易出现这个问题
解决:
ldd bin文件查看缺少哪些库:但是一般运行bin后就会弹出
locate libopencv_imgcodecs.so.3.0
或者直接在自定义的opencv安装路径下搜索
sudo gedit /etc/ld.so.conf.d/opencv.conf(名字自定义)
在文件下添加动态库的绝对路径,如
/home/fei/OpenCV/opencv3.2.0/opencv-3.2.0-install/lib
保存后运行,不可漏
ldconfig
查找当前目录包含某个关键词的文件
find . |xargs grep x
x是关键词
cv::Mat::step
step[0]是矩阵中一行元素的字节数
step[1]是矩阵中一个元素的字节数(elemSize)
step1 = step / elemSize1,elemSize1是元素的每个通道所占的字节数
step1(0)是矩阵一行元素的通道数(不是很贴切)
step1(1)是矩阵一个元素的通道数(channel())
docker一键安装
sudo curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
参考https://blog.csdn.net/okcd00/article/details/84255669
SSH进行远程copy
由远程copy到主机
scp [远程用户名]@[远程ip地址]:[远程目录] [本地目录]
由主机copy到远程
scp -r [本地目录] [远程用户名]@[远程ip地址]:[远程目录]
通过NFS,ssh挂载远程目录镜像
对应目录本地修改就可以同步到远程端口
先安装NFS服务,百度查找
sudo mount -o nolock [远程ip地址]:[远程目录] [本地目录(/mnt)]
命令行安装出现依赖问题无法安装
先安装aptitude
sudo apt-get install aptitude
再调用aptitude去递归安装依赖以及源程序
sudo aptitude install fcitx
ubuntu桌面版添加开机自启动程序
使用图形界面添加
gnome-session-properties
Ros安装
https://blog.csdn.net/qq_44830040/article/details/106049992
sudo rosdep init
出现错误
ERROR: cannot download default sources list from:
https://raw.githubusercontent.com/ros/rosdistro/master/rosdep/sources.list.d/20-default.list
Website may be down.
###查找openCV某个函数源文件
find . -name '*' -type f | xargs grep 'bilateralFilter'