从零开始学习SLAM:openCV

2023-05-16

继续跟随《视觉SLAM十四讲》学习SLAM问题,由于理论方面已经有一些研究,主要缺乏的是在LINUX下的实战开发能力,因而从代码开始分析入手,同时对C++11进行回顾。

1. openCV 中的Mat类

Mat类用于存储图像信息,详细信息见 https://docs.opencv.org/3.1.0/d3/d63/classcv_1_1Mat.html ,这里我们主要针对几个常用的点展开来记录。

  1. 类的结构
    Mat是由两个数据部分,包含信息有矩阵的大小,用于存储的方法,矩阵存储的地址等的矩阵头和一个指针,指向包含了像素值的矩阵(可根据选择用于存储的方法采用任何维度存储数据)。矩阵头部的大小是恒定的。然而,矩阵本身的大小因图像的不同而不同,通常是较大的数量级。
  2. 构造函数
    Mat类的默认构造函数为cv::Mat::Mat(),生成一个矩阵并由OpenCV提供的函数(一般是Mat::create() 和 cv::imread() )来分配储存空间。OpenCV使用了引用次数,当进行图像复制和传递时,不再复制整个Mat数据,而只是复制矩阵头和指向像素矩阵的指针,例如:
    / 关于 cv::Mat 的拷贝
    // 直接赋值并不会拷贝数据
    cv::Mat image_another = image;
    // 修改 image_another 会导致 image 发生变化
    image_another ( cv::Rect ( 0,0,100,100 ) ).setTo ( 0 ); // 将左上角100*100的块置零
    cv::imshow ( "image", image );
    cv::waitKey ( 0 );
    
    // 使用clone函数来拷贝数据
    cv::Mat image_clone = image.clone();
    image_clone ( cv::Rect ( 0,0,100,100 ) ).setTo ( 255 );
    cv::imshow ( "image", image );
    cv::imshow ( "image_clone", image_clone );
    cv::waitKey ( 0 );

也就是说直接拷贝拷贝的只是指向数据矩阵的指针,对任意一个指针指向内容的修改会影响其他所有的,销毁时则是每销毁一个引用计数会-1(每copy一次同样会+1),直到计数为0,矩阵数据会被清理。
常用的构造函数还包括

    Mat (int rows, int cols, int type)
 	Mat (Size size, int type)
 	Mat (int rows, int cols, int type, const Scalar &s)
 	Mat (Size size, int type, const Scalar &s)
 	Mat (int ndims, const int *sizes, int type)
 	Mat (int ndims, const int *sizes, int type, const Scalar &s)
 	Mat (const Mat &m)
 	Mat (int rows, int cols, int type, void *data, size_t step=AUTO_STEP)
 	Mat (Size size, int type, void *data, size_t step=AUTO_STEP)
 	Mat (int ndims, const int *sizes, int type, void *data, const size_t *steps=0)
 	Mat (const Mat &m, const Range &rowRange, const Range&colRange = Range::all())
 	Mat (const Mat &m, const Rect &roi)
 	Mat (const Mat &m, const Range *ranges)
  1. 成员函数
    Mat成员函数较常用的包括at(获取某位置的元素值),convertTo(将源文件转化为目标数据格式),clone(复制图像矩阵数据),create(分配矩阵的存储单元),type(获取数据类型),channels(获取通道数)(rows和cols属于Member Data调用不需要加括号),详细的说明可见 https://blog.csdn.net/guyuealian/article/details/70159660

2. 一个方便的读取矩阵txt文件的方式

ifstream fin("文件名.txt");
for ( int i=0; i<矩阵行数; i++ )
{
    double data[矩阵列数] = {0};
    for ( auto& d:data )
        fin>>d;
}

3. 两种常用的访问图像像素的方法

  1. 视觉SLAM十四讲中的方法(使用指针)
for ( size_t y=0; y<image.rows; y++ )
    {
        // 用cv::Mat::ptr获得图像的行指针
        unsigned char* row_ptr = image.ptr<unsigned char> ( y );  // row_ptr是第y行的头指针
        for ( size_t x=0; x<image.cols; x++ )
        {
            // 访问位于 x,y 处的像素
            unsigned char* data_ptr = &row_ptr[ x*image.channels() ]; // data_ptr 指向待访问的像素数据
            // 输出该像素的每个通道,如果是灰度图就只有一个通道
            for ( int c = 0; c != image.channels(); c++ )
            {
                unsigned char data = data_ptr[c]; // data为I(x,y)第c个通道的值
            }
        }
    }
  1. 使用at
for (int i = 0; i < image.rows; i++) 
	{ 
		for (int j = 0; j<image.cols; j++) 
		{ 
			
			image.at<Vec3b>(i,j)[0]=image.at<Vec3b>(i,j)[0]/div*div+div/2;
			image.at<Vec3b>(i,j)[1]=image.at<Vec3b>(i,j)[1]/div*div+div/2;
			image.at<Vec3b>(i,j)[2]=image.at<Vec3b>(i,j)[2]/div*div+div/2;
		} 
	} 

其他方法可以参考 https://blog.csdn.net/xiaowei_cqu/article/details/19839019

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

从零开始学习SLAM:openCV 的相关文章

  • 深度估计的准确性 - 立体视觉

    我正在研究立体视觉 我对这个问题的深度估计的准确性感兴趣 这取决于几个因素 例如 适当的立体校准 旋转 平移和失真提取 图像分辨率 相机和镜头质量 失真越小 色彩捕捉正确 两个图像之间的匹配特征 假设我们没有低成本的相机和镜头 没有廉价的网
  • 查找具有不同强度/亮度的相似图像

    假设我有如下图像 我可以选择什么来比较两个图像之间的相似度 显然它们是相同的图像 只是亮度不同 我找不到任何可行的方法 目前我最好的选择是训练 cnn 或自动编码器并比较输出的特征向量 但这似乎有点矫枉过正 任何提示将不胜感激 相当强大的工
  • 使用卡尔曼滤波器跟踪位置和速度

    我正在使用卡尔曼滤波器 恒定速度模型 来跟踪物体的位置和速度 我测量对象的 x y 并跟踪 x y vx vy 这是有效的 但是如果在传感器读数 x y vx vy 上添加 20 mm 的高斯噪声 即使该点没有移动 只是噪声也会发生波动 对
  • 如何检测图像是否像素化

    之前有人在 SO 上提出过这样的问题 在Python中检测像素化图像 https stackoverflow com questions 12942365 detecting a pixelated image in python还有关于q
  • 使用python从gst管道抓取帧到opencv

    我在用着OpenCV http opencv org 和GStreamer0 10 我使用此管道通过自定义套接字通过 UDP 接收 MPEG ts 数据包sockfd由 python 提供并显示它xvimagesink 而且效果很好 以下命
  • 在骨架图像中查找线 OpenCV python

    我有以下图片 我想找到一些线来进行一些计算 平均长度等 我尝试使用HoughLinesP 但它找不到线 我能怎么做 这是我的代码 sk skeleton mask rows cols sk shape imgOut np zeros row
  • HoughLinesP后如何合并线?

    My task is to find coordinates of lines startX startY endX endY and rectangles 4 lines Here is input file 我使用下一个代码 img c
  • 在Python中从整个图像中检测表格部分

    我有一张尺寸为 3500x5000 的图像 现在我只想检测整个图像中的表格部分 如果不能直接进行 OCR 处理 则对其进行裁剪和旋转 经过所有搜索后 我想到了使用裁剪图像中的每个单元格的想法https medium com coinmonk
  • OpenCV Python 和 SIFT 功能

    我知道有很多关于Python and OpenCV但我没有找到有关这个特殊主题的帮助 我想提取SIFT关键点来自 python OpenCV 中的图像 我最近安装了 OpenCV 2 3 可以访问 SURF 和 MSER 但不能访问 SIF
  • 如何在python 3.8中安装opencv-python

    我在 pycharm 中安装 opencv python 时遇到问题 打开 pycharm 后 我单击 设置 然后单击 项目解释器 单击 并搜索正确的模块 我开始安装 但失败了 Could not find a version that s
  • 针对不同处理器架构的 Gradle android 构建

    我想使用 Gradle 为 4 个不同的 Android CPU 处理器架构 armeabi armeabi v7a x86 mips 构建 4 个单独的 apk 我有为 4 个 CPU 架构构建的本机 OpenCV 库libs folde
  • 在 opencv 中一次性将旋转和平移结合起来

    我有一段用于旋转和平移图像的代码 Point2f pt 0 in rows double angle atan trans c trans b 180 M PI Mat r getRotationMatrix2D pt angle 1 0
  • 车辆分割和跟踪

    我已经从事一个项目一段时间了 目的是在无人机捕获的视频中检测和跟踪 移动 车辆 目前我正在使用 SVM 该 SVM 接受了从车辆和背景图像中提取的局部特征的特征袋表示的训练 然后 我使用滑动窗口检测方法来尝试定位图像中的车辆 然后我想要跟踪
  • 将 CvSeq 保存到数组

    我对 OpenCV 文档有点迷失 我想将 cvFindContours 返回的 CvSeq 保存到一个数组中 据我了解它将返回 CvContour 的 seq 但我找不到它包含的内容 我应该保存其中的哪些部分 稍后我可以迭代它并说调用 cv
  • 为什么在 OpenCV 中访问该矩阵时出现内存错误?

    我只是想写入给定大小的矩阵 当我在 Valgrind 中运行该程序时 出现内存错误 如下所示 主要 cpp include
  • 使用 Brew 安装 OpenCV 永远不会完成

    所以我尝试使用 Homebrew 安装 opencv 但它不起作用 我用了brew tap homebrew science进而brew install opencv发生的情况是 gt Installing opencv from home
  • OpenCV findContours() 仅返回一个外部轮廓

    我试图隔离验证码中的字母 我设法过滤验证码 结果是这个黑白图像 但是当我尝试使用 OpenCV 的 findContours 方法分离字母时 它只是发现了一个包裹整个图像的外部轮廓 从而产生了该图像 图像外部的黑色轮廓 我将此代码与 Pyt
  • Python中使用cv2获取当前视频播放位置

    我正在尝试使用 CV2 和 Python 从播放视频中获取当前播放时间位置 如果可能 以毫秒为单位 目前我正在使用此示例代码来播放视频文件 import cv2 import numpy as np file name 2 mp4 wind
  • Python OpenCV视频格式在浏览器中播放

    我正在尝试从一系列图像创建视频并将其显示在浏览器中 但由于某些奇怪的原因 无论我使用什么编解码器或文件格式 我都会收到以下错误 找不到格式和 MIME 类型受支持的视频 这是我的代码 ready images import cv2 for
  • 使用 OpenCV 绘制固定的网格线集

    是否可以根据 OpenCV 示例文件中颜色检测示例的输出 在所有交叉点处绘制具有定义点的用户定义网格线 基本上 网络摄像头需要从您上方检测人的头部和肩膀 然后 当检测到一个人时 我需要网格线在那里 以便我能够知道在 x 轴和 y 轴 前额和

随机推荐