InputArray() 是一个接口类, 可以传入多种类型,例如Mat, Mat_<T>, Mat_<T, m,n>, vector<vector<T>>, vector<Mat>等;

因为在opencv中属于执行类,所以接口可能会改变,因此有几点需要注意:
1. 当在opencv的函数中看到出入类型为InputArray的参数,就可以传入 Mat,matx等类型

2. 如果传入值为空时, 可以用cv::noArray() 替代, 或者用cv::Mat()

3. 该类的设计基本只用于参数的传递, 因为不建议将自己的classmember或者 local, global变量申请为这种类型;

4. 如果在设计函数的传入类型时, 希望兼容更多,也可以使用_InputArray 或者OutputArray的类型,同时,在函数内部,使用_InputArray::getMat() 函数为该参数构建一个矩阵的头指针, 这样相当于直接对传输参数的内存区域进行了操作,但是并不需要将数据进行拷贝;

opencv中举例如下:

void myAffineTransform(InputArray _src, OutputArray _dst, InputArray _m)
{// get Mat headers for input arrays. This is O(1) operation,// unless _src and/or _m are matrix expressions.Mat src = _src.getMat(), m = _m.getMat();CV_Assert( src.type() == CV_32FC2 && m.type() == CV_32F && m.size() == Size(3, 2) );// [re]create the output array so that it has the proper size and type.// In case of Mat it calls Mat::create, in case of STL vector it calls vector::resize._dst.create(src.size(), src.type());Mat dst = _dst.getMat();for( int i = 0; i < src.rows; i++ )for( int j = 0; j < src.cols; j++ ){Point2f pt = src.at<Point2f>(i, j);dst.at<Point2f>(i, j) = Point2f(m.at<float>(0, 0)*pt.x +m.at<float>(0, 1)*pt.y +m.at<float>(0, 2),m.at<float>(1, 0)*pt.x +m.at<float>(1, 1)*pt.y +m.at<float>(1, 2));}
}

如上例, 传入的参数_src , 经过 src =  _src.getMat() 将操作区域传给src变量,这样可以直接对src进行访问或者查看;

同理, 传入的_dst变量,在内存空间申请完成后, 就可以用dst = dst_.getMat() 进行矩阵头复制, 然后接下来对dst矩阵操作即可;

如上操作完成,也无需再进行复制等额外的操作,因为对dst的赋值,其实直接操作的是_dst的mat区域;

OutputArray是InputArray的派生类。使用时需要注意的问题和InputArray一样。和InputArray不同的是,需要注意在使用_OutputArray::getMat()之前一定要调用_OutputArray::create()为矩阵分配空间。可以用_OutputArray::needed()来检测输出的矩阵是否需要被计算。有时候传进去的参不是空就不需要计算

这个在ORB SLAM 项目的提取orb特征的时候,也是同样的用法:

void ORBextractor::operator()( InputArray _image, InputArray _mask, vector<KeyPoint>& _keypoints,OutputArray _descriptors)
{if(_image.empty())return;//这里将传入参数_image 传给 image参数Mat image = _image.getMat();assert(image.type() == CV_8UC1 );// Pre-compute the scale pyramidComputePyramid(image);vector < vector<KeyPoint> > allKeypoints;ComputeKeyPointsOctTree(allKeypoints);//ComputeKeyPointsOld(allKeypoints);Mat descriptors;//计算总共的kp个数int nkeypoints = 0;for (int level = 0; level < nlevels; ++level)nkeypoints += (int)allKeypoints[level].size();if( nkeypoints == 0 )_descriptors.release();else{// 为参数_descriptors分配内存,并将内存区域指针变量传入到descriptors 这个Mat中_descriptors.create(nkeypoints, 32, CV_8U);descriptors = _descriptors.getMat();}_keypoints.clear();_keypoints.reserve(nkeypoints);//备注:KEYPOINT 1 与 KEYPOINT 2的值相等,KEYPOINT 3为KEYPOINT1 的scale倍int offset = 0;for (int level = 0; level < nlevels; ++level){vector<KeyPoint>& keypoints = allKeypoints[level];int nkeypointsLevel = (int)keypoints.size();if(nkeypointsLevel==0)continue;//std::cout<<"KEYPOINT 1: " << keypoints[0].pt<<std::endl;// preprocess the resized imageMat workingMat = mvImagePyramid[level].clone();GaussianBlur(workingMat, workingMat, Size(7, 7), 2, 2, BORDER_REFLECT_101);// Compute the descriptorsMat desc = descriptors.rowRange(offset, offset + nkeypointsLevel);computeDescriptors(workingMat, keypoints, desc, pattern);//std::cout<<"KEYPOINT 2: " << keypoints[0].pt<<std::endl;offset += nkeypointsLevel;// Scale keypoint coordinatesif (level != 0){float scale = mvScaleFactor[level]; //getScale(level, firstLevel, scaleFactor);for (vector<KeyPoint>::iterator keypoint = keypoints.begin(),keypointEnd = keypoints.end(); keypoint != keypointEnd; ++keypoint)keypoint->pt *= scale; // 对kp进行一个scale的放大}//std::cout<<"KEYPOINT 3: " << keypoints[0].pt<<std::endl;// And add the keypoints to the output_keypoints.insert(_keypoints.end(), keypoints.begin(), keypoints.end());}}

参考:https://blog.csdn.net/yang_xian521/article/details/7755101

_InputArray 和 outputArray在ORBslam中的使用相关推荐

  1. ORB-SLAM中的ORB特征(提取)

    点击上方"3D视觉工坊",选择"星标" 干货第一时间送达 作者:小葡萄 https://zhuanlan.zhihu.com/p/61738607 本文仅做学术 ...

  2. 详细解读ORBSLAM中的描述子提取过程

    一直都在基于ORBSLAM做一些相关的开发,只知道进来的图片会直接提取出BRIEF描述子,但是都没有详细地看过它具体的提取过程,今天仔细研究了一下代码和相关理论,弄清楚之后感觉神清气爽,部分内容查找有 ...

  3. 传统ORB-SLam中位姿优化中雅克比矩阵讲解

    由于之前的鱼眼orbslam只有单目部分,所以在优化时也只是用了单目位姿优化和三维坐标点优化,并没有将双目的优化添加进去,不知道是否对结果有影响: 这里添加双目的优化部分,主要是将添加雅克比矩阵: o ...

  4. ORB-SLAM中的重定位解读及追踪

    我们以ORBSLAM中的重定位举例,来分析重定位的过程.当跟踪失败的时候,系统会启动重定位. 找出一些候选关键帧,对每个候选关键帧,用ransac和EPNP估计位姿,然后更新当前帧的地图点匹配,然后优 ...

  5. ORB-SLAM中的ORB特征提取

    ORB-SLAM中的ORB特征提取 0.提取流程概览 1.构造金字塔 2.提取FAST角点 3.利用灰度质心法,计算旋转角度 [公式] 4.计算旋转后的BRIEF描述子 1.构造金字塔 2.提取FAS ...

  6. OpenCV辅助对象(help objects)(6)_InputArray和OutputArray

    opencv中的cv:DataType<>解决了算法与数据类型分类的问题,使算法能够适应多种类型的数据,以及能够方便提取出数据类型.但是OpenCV的基本数据类型有多多,Mat matx, ...

  7. 一起学ORBSLAM2(7)ORBSLAM中的优化问题

    转载请注明原创地址:https://blog.csdn.net/qq_30356613/article/category/6897125 ORBSLAM是一种基于优化方法的SLAM方法,与之前的基于滤 ...

  8. orb-slam中的orb特征

    1.ORB特征简介 ORB是Oriented FAST and Rotated BRIEF(oFAST and rBRIEF)的简称,ORB的名字已经说明了其来源,其实ORB特征是采用FAST方法来检 ...

  9. ORBSLAM的ORB特征到底从哪儿来?

    ORBSLAM中的主要使用了ORB特征,也就是FAST特征+BRIEF描述子的组合,具体这两种方法就不详细介绍了,这里主要说一下每个特征对应的描述子在ORBSLAM中的维护方式: 首先需要说明的是每个 ...

最新文章

  1. [转]oracle设计数据库应选择正确的数据类型
  2. 特征提取方法 SIFT,PCA-SIFT,GLOH,SURF
  3. Maven中 jar包冲突原理与解决办法依赖传递
  4. HDMI显示器驱动设计与验证
  5. 洛谷P1073 Tarjan + 拓扑排序 // 构造分层图
  6. case when then的用法
  7. redux中间件原理-讲义
  8. Java PipedInputStream close()方法与示例
  9. 收藏 | 机器学习、深度学习调参手册
  10. 非常干货之Python资源大全
  11. oj1047: 对数表
  12. 如何有效预防宕机?你需要掌握这4个方法
  13. 系统测试方案编写(五)
  14. 常识:如何从大陆拨打国际长途电话到境外的方法
  15. 2015CGMC 参赛游戏名单
  16. Excel 序号自动增长,变更
  17. 软件特性开发的流程感想
  18. 制作Windows PE启动镜像命令
  19. Linux cat命令使用
  20. [Pyecharts]数据可视化 大屏展示

热门文章

  1. bzoj 1656: [Usaco2006 Jan] The Grove 树木(BFS)
  2. matlab2c使用c++实现matlab函数系列教程-sum函数
  3. java 耦合解耦_为什么工厂模式可以解耦?why?
  4. CentOS7 上以 RPM 包方式安装 Oracle 18c 单实例
  5. Navicate在同步oracle数据,不同数据库之间同步
  6. windows下maven的使用
  7. error parsing xml:unbound prefix
  8. 如何建立最初的三层架构[转]
  9. [转载] pip快速下载python包
  10. 从零配置webpack(react+less+typescript+mobx)