OpenCV实现Mat与vector互转

【尊重原创,转载请注明出处】https://blog.csdn.net/guyuealian/article/details/80253066

1、Mat与vector互转

下面是鄙人实现的Mat与vector互转的方法,需要注意的是vector转Mat时,使用reshape()后,必须clone()一份,否则返回的结果出错,关于这方面的原因,可以参考鄙人的博客:https://blog.csdn.net/guyuealian/article/details/80252853

#include <opencv2/opencv.hpp>using namespace cv;
using namespace std;/***************** Mat转vector **********************/
template<typename _Tp>
vector<_Tp> convertMat2Vector(const Mat &mat)
{return (vector<_Tp>)(mat.reshape(1, 1));//通道数不变,按行转为一行
}/****************** vector转Mat *********************/
template<typename _Tp>
cv::Mat convertVector2Mat(vector<_Tp> v, int channels, int rows)
{cv::Mat mat = cv::Mat(v);//将vector变成单列的matcv::Mat dest = mat.reshape(channels, rows).clone();//PS:必须clone()一份,否则返回出错return dest;
}int main()
{/* char ->CV_8SC* unsigned char,uchar ->CV_8UC* unsigned short int,ushort->CV_16UC* short int->CV_16SC* int   ->CV_32SC* float ->CV_32FC* double->CV_64FC*/uchar arr[4][3] = { { 1, 1,1 },{ 2, 2,2 },{ 3, 3,3 },{ 4,4, 4 } };cv::Mat srcData(4, 3, CV_8UC1, arr);cout << "srcData=\n" << srcData << endl;vector<uchar> v = convertMat2Vector<uchar>(srcData);cv::Mat dest = convertVector2Mat<uchar>(v, 1, 4);//把数据转为1通道,4行的Mat数据cout << "dest=\n" << dest << endl;system("pause");waitKey();return 0;
}

运行结果:

srcData=
[  1,   1,   1;2,   2,   2;3,   3,   3;4,   4,   4]
dest=
[  1,   1,   1;2,   2,   2;3,   3,   3;4,   4,   4]

2、Mat与数组互转

利用Mat来存储数据,避免使用数组等操作

cv::Mat mean = (cv::Mat_<float>(2, 1) << 0.4404, 0.3111);
cout << "mean=" << mean << endl;
float a=mean.at<float>(0, 0);
float b = mean.at<float>(0, 0);

将数组内容传递给Mat,示例代码:

unsigned char cbuf[height][width];
cv::Mat img(height, width, CV_8UC1, (unsigned char*)cbuf);

将Mat中的内容传递给数组,如果Mat中的数据是连续的,那么对于传递到一维vector我们可以这样:

std::vector<uchar> array(mat.rows*mat.cols);
if (mat.isContinuous())array = mat.data;

同样的,传递到一维数组我们可以这样

unsigned char *array=new unsigned char[mat.rows*mat.cols];if (mat.isContinuous())array = mat.data;

对于二维vector的传值,我们可以这样处理​​​​​​​

uchar **array = new uchar*[mat.rows];
for (int i=0; i<mat.rows; ++i)array[i] = new uchar[mat.cols];for (int i=0; i<mat.rows; ++i)array[i] = mat.ptr<uchar>(i);

 RGB图与数组转换(3维矩阵)

    BYTE* iPtr = new BYTE [height*width*3];for(int i=0;i<height;i++){for(int j=0;j<width;j++){for(int k=0;k<3;k++){iPtr[i*width*3+j*3+k] = img.at<Vec3b>(i,j)[k];}}}

其中,img是一个3维uchar的Mat,Vec3b代表3个uchar,对于灰度图、4维矩阵等,只要把通道数和at的数据类型改一下就可以套用以上格式。还有一点千万注意,Mat的(i,j)是按(行,列)的规则,而图像中则是(高,宽),跟Size(x,y),Rect(x,y)的(x,y)是不同的

4字节对齐的情况

        http://lib.csdn.net/article/opencv/24030

        但如果图像大小不是4的整数倍,某些场合下不能直接使用Mat::data。因为图像在OpenCV里的存储机制问题,行与行之间可能有空白单元(一般是补够4的倍数或8的倍数,称为padding。这些空白单元对图像来说是没有意思的,只是为了在某些架构上能够更有效率,比如intel MMX可以更有效的处理那种个数是4或8倍数的行。Mat提供了一个检测图像是否连续的函数isContinuous()。当图像连通时,我们就可以把图像完全展开,看成是一行。此时调用Mat::ptr<>()方法就等价于Mat::data:

int nr=image.rows;
int nc=image.cols;
if(image.isContinuous())  {  nr=1;  nc=nc*image.rows*image.channels();  }   for(int i=0;i<nr;i++)  {       const uchar* inData=image.ptr<uchar>(i);         uchar* outData=outImage.ptr<uchar>(i);        for(int j=0;j<nc;j++)  {  *outData++=*inData++;  }  }  

        例如保存BMP格式的图像时,BMP要求图像数据按四字节对齐,此时就需要对Mat中的数据进行补零
对齐方法就是在每一行尾部补零,零的个数可能是1~3个

        但其实大部分时候,Mat的内存都是连续的,只有极个别时候需要担心这个问题,这里有说明,和这里

OpenCV实现Mat与vector,Mat与数组互转相关推荐

  1. 数据类型转换--Mat与Vector<Point2f>

    一.数据转换 1.Mat-->vector<Point3f>: Mat m; vector<Point3f> p; p=Mat_<Point3f>(m) 2. ...

  2. c语言构造mat型数据类型,视觉SLAM——OpenCV之Mat结构详解 数据成员和构造函数 创建Mat方法 遍历Mat方法...

    前言 OpenCV1时代采用基于C语言接口构建函数库,使用名为IplImage的结构体在内存中存储图像,其问题在于需要用户手动管理内存,如果不手动释放内存会造成内存泄漏. OpenCV2引入面向对象编 ...

  3. OpenCV Mat矩阵(图像Mat)初始化及访问方法

    一.Mat初始化 1.使用Mat构造函数 //方法一: Mat M( 2, 2, CV_8UC3, Scalar(0,255,0) );//其实是2*6的矩阵,因为每个元素有3个通道. Mat M1( ...

  4. 学习OpenCV(一)从Mat讲起

    本博客所用OpenCV版本为2.4.3,运行环境为Visual Studio2012. 学习OpenCV是一个比较漫长的过程,希望我能够坚持! (一)从Mat讲起 Mat是OpenCV中用于存放图像的 ...

  5. 【opencv4】opencv教程 C++ 4、Mat对象(深拷贝:clone()、copyTo(),create()创建图片,zeros()、eye()初始化空白图像,Scalar()创建向量)

    上一讲:[opencv4]opencv视频教程 C++(opencv教程)3.矩阵的掩膜操作(filter2D) 下一讲:[opencv4]opencv视频教程 C++ 5.读写图像imread.im ...

  6. opencv的mat赋值_OpenCV Mat 类型定义和赋值

    1.一般的Mat定义方法:cv::Mat M(height,width,),例: cv::Mat M(480,640,CV_8UC3); 表示定义了一个480行640列的矩阵,矩阵的每个单元的由三个( ...

  7. c++版本opencv(04.认识Mat对象-05.Mat对象创建与使用-06.遍历与访问每个像素-)

    c++版本opencv(04.认识Mat对象-05.Mat对象创建与使用-06.遍历与访问每个像素-) 一.04.认识Mat对象- 二,05.Mat对象创建与使用- 三,06.遍历与访问每个像素- 来 ...

  8. 【OpenCv】c++ 入门认识 Mat 类,单通道 Mat 的基本操作

    文章目录 前言 Mat 类 Mat 类的构造方式 Mat 基本操作 单通道 Mat 的基本操作 使用成员变量 rows 和 cols 获取矩阵的行数和列数 使用成员函数 size() 来获取矩阵的尺寸 ...

  9. mat opencv java_OpenCV Mat到JavaCV Mat转换

    您可以使用java.awt.image.BufferedImage作为接口. 您org.opencv.core.Mat对象只是转换为java.awt.image.BufferedImage中再取结果对 ...

最新文章

  1. 客快物流大数据项目(二十五):初始化业务数据
  2. 我们准备在网关中支持GrahpQL了
  3. python中bind的用法_JS中的apply、call和bind的用法和区别
  4. IETF:名词历史简介互联网精神的典范
  5. 离散数学之集合论 【下】
  6. 史上最简单的SpringCloud教程 | 第四篇:断路器(Hystrix)--里面有BUG,所以我转载改一下
  7. 【Python五篇慢慢弹】快速上手学python
  8. ASP.NET Core MVC 打造一个简单的图书馆管理系统 (修正版)(三)密码修改以及密码重置...
  9. XmlDataProvider的简单应用
  10. linux php-cli,php cli - shell语言的扩展利器 - Linux进阶, PHP技术 - freemouse-笔记-感悟-成长...
  11. Hibernate 入门简单教程
  12. 如何清空c盘只剩系统_c盘怎么清理到最干净只保留系统,教你如何给C盘减肥
  13. 拳王虚拟项目公社:虚拟资源项目超详解,人人皆可熟练操作
  14. react配合modal实现progress进度条
  15. java开发常用软件下载地址及教程。
  16. 51单片机数码管密码锁
  17. 安全问题的思考---君子不立于危墙之下
  18. word 批量设置图片大小
  19. win7重装的坑:启动分区不存在 使用分区工具修正
  20. 使用Meterperter会话获取目标屏幕与键盘记录

热门文章

  1. 今天学了瀑布流的js方法
  2. ios使用支付宝进行支付,注意事项 集成支付宝钱包支付iOS SDK的方法与经验。...
  3. 读CLR via C#总结(7) 以传引用的方式向方法传递参数---refout
  4. C++-运行时类型信息,异常(day11)
  5. JS中定时器setTimeout,setInterval,clearTimeout,clearInterval用法
  6. 6. H.264/AVC编码器原理
  7. 由java的八个基本数据类型说开去
  8. C# 开启摄像头 拍照
  9. 申请邓白氏编码和公司开发者账号需要的东西
  10. input和img图片水平对齐