在opencv中,reshape函数比较有意思,它既可以改变矩阵的通道数,又可以对矩阵元素进行序列化,非常有用的一个函数。

函数原型:

C++: Mat Mat::reshape(int cn, int rows=0) const

参数比较少,但设置的时候却要千万小心。

cn: 表示通道数(channels), 如果设为0,则表示保持通道数不变,否则则变为设置的通道数。

rows: 表示矩阵行数。 如果设为0,则表示保持原有的行数不变,否则则变为设置的行数。

首先设置一个初始矩阵:一个20行30列1通道的一个矩阵

int main()
{Mat data = Mat(20, 30, CV_32F);  //设置一个20行30列1通道的一个矩阵cout << "行数: " << data.rows << endl;cout << "列数: " << data.cols << endl;cout << "通道: " << data.channels() << endl;system("pause");return 1;
}

输出:

第一次变化:通道数不变,将矩阵序列化1行N列的行向量。

int main()
{Mat data = Mat(20, 30, CV_32F);  //设置一个20行30列1通道的一个矩阵cout << "行数: " << data.rows << endl;cout << "列数: " << data.cols << endl;cout << "通道: " << data.channels() << endl;cout << endl;Mat dst = data.reshape(0, 1);cout << "行数: " << dst.rows << endl;cout << "列数: " << dst.cols << endl;cout << "通道: " << dst.channels() << endl;system("pause");return 1;
}

第二次变化:通道数不变,将矩阵序列化N行1列的列向量。

int main()
{Mat data = Mat(20, 30, CV_32F);  //设置一个20行30列1通道的一个矩阵cout << "行数: " << data.rows << endl;cout << "列数: " << data.cols << endl;cout << "通道: " << data.channels() << endl;cout << endl;Mat dst = data.reshape(0, data.rows*data.cols);cout << "行数: " << dst.rows << endl;cout << "列数: " << dst.cols << endl;cout << "通道: " << dst.channels() << endl;system("pause");return 1;
}

可见,序列成列向量比行向量要麻烦一些,还得去计算出需要多少行。但我们可以先序列成行向量,再转置

    Mat dst = data.reshape(0, 1);      //序列成行向量Mat dst = data.reshape(0, 1).t();  //序列成列向量

第三次变化:通道数由1变为2,行数不变。

int main()
{Mat data = Mat(20, 30, CV_32F);  //设置一个20行30列1通道的一个矩阵cout << "行数: " << data.rows << endl;cout << "列数: " << data.cols << endl;cout << "通道: " << data.channels() << endl;cout << endl;Mat dst = data.reshape(2, 0);cout << "行数: " << dst.rows << endl;cout << "列数: " << dst.cols << endl;cout << "通道: " << dst.channels() << endl;system("pause");return 1;
}

从结果可以看出,列数被分出一半,放在第二个通道里去了。

同理,如果通道数由1变为3,行数不变。则每通道的列数变为原来的三分之一。

需要注意的是,如果行保持不变,改变的通道数一定要能被列数整除,否则会出错。

第四次变化:通道数由1变为2,行数变为原来的五分之一。

int main()
{Mat data = Mat(20, 30, CV_32F);  //设置一个20行30列1通道的一个矩阵cout << "行数: " << data.rows << endl;cout << "列数: " << data.cols << endl;cout << "通道: " << data.channels() << endl;cout << endl;Mat dst = data.reshape(2, data.rows/5);cout << "行数: " << dst.rows << endl;cout << "列数: " << dst.cols << endl;cout << "通道: " << dst.channels() << endl;system("pause");return 1;
}

可见,不管怎么变,都遵循这样一个等式:

变化之前的  rows*cols*channels = 变化之后的 rows*cols*channels

我们只能改变通道数和行数,列数不能改变,它是自动变化的。

但是要注意的是,在变化的时候,要考虑到是否整除的情况。如果改变的数值出现不能整除,就会报错。

最后,我们再验证一下:opencv在序列化的时候是行序列化还是列序列化呢?

我们知道,在matlab里面,是列序列化, 即取值为从上到下,从左到右,opencv又是怎么样的呢

int main()
{Mat data = (Mat_<int>(2, 3) << 1, 2, 3, 10, 20, 30);  //2行3列的矩阵cout << data << endl;Mat dst1 = data.reshape(0, 6);   //通道不变,序列成列向量cout <<endl<< dst1 << endl;Mat dst2 = data.reshape(0, 1);   //通道不变,序列成行向量cout << endl << dst2 << endl;system("pause");return 1;
}

从结果看出,不管是变化成行向量还是列向量,opencv都是行序列化,即从左到右,从上到下,与matlab是不一样的。

简单的一个函数,功能却很强大!你会用了吗

opencv 学习:reshape函数相关推荐

  1. Opencv的reshape函数

    reshape函数既可以改变矩阵的通道数,又可以对矩阵元素进行序列化,而且不需要复制数据. C++: Mat Mat::reshape(int cn, int rows=0 ) const 参数虽然比 ...

  2. OpenCV学习+常用函数记录①:图像的基本处理

    OpenCV 图像的基本处理 1.1 图片读取和显示 1.2 写入文件(保存) 1.3 像素操作 1.4 图片剪切 1.5 镜像处理: 1.6 图像缩放 1.7 图像位移 1.8 图像旋转 1.9 仿 ...

  3. OpenCV学习(函数)

    OpenCV[未完结] 1_图片读取与显示 imread()函数:读取图片 param1:图片的名称 如果当前读入的图片与该脚本在相同目录下,则路径可以为相对路径 如果当前读入的图片不与该脚本在相同目 ...

  4. python学习-reshape()函数理解

    文章目录 前言 一.reshape() 1.reshape(m,n) 2.reshape(m,n,p) 3.对多维数组reshape 总结 前言 提示:这里可以添加本文要记录的大概内容: 例如:随着人 ...

  5. OpenCV——Mat reshape函数

    Mat reshape(int cn, int rows=0) const; cn: 表示通道数(channels), 如果设为0,则表示保持通道数不变,否则则变为设置的通道数. rows: 表示矩阵 ...

  6. OpenCV reshape函数需要注意的细节

    OpenCV reshape函数需要注意的细节 [尊重原创,转载请注明出处]https://blog.csdn.net/guyuealian/article/details/80252853 本人在使 ...

  7. 【youcans 的 OpenCV 学习课】7. 空间域图像滤波

    专栏地址:『youcans 的图像处理学习课』 文章目录:『youcans 的图像处理学习课 - 总目录』 [youcans 的 OpenCV 学习课]7. 空间域图像滤波 图像滤波是在尽可能保留图像 ...

  8. opencv reshape函数详解

    在opencv中,reshape函数比较有意思,它既可以改变矩阵的通道数,又可以对矩阵元素进行序列化,非常有用的一个函数. 函数原型: C++: Mat Mat::reshape(int cn, in ...

  9. OpenCV 学习笔记03 boundingRect、minAreaRect、minEnclosingCircle、boxPoints、int0、circle、rectangle函数的用法...

    函数中的代码是部分代码,详细代码在最后 1 cv2.boundingRect 作用:矩形边框(boundingRect),用于计算图像一系列点的外部矩形边界. cv2.boundingRect(arr ...

最新文章

  1. [转] L1 L2范数
  2. 类的加载顺序和对象的实例化
  3. (17)10-10-12分页
  4. 计算机现代管理专业,信息管理与信息系统是个鸡肋专业吗?
  5. C#与时间有关的一些方法
  6. java 问题排查_JAVA问题排查笔记
  7. 阿里巴巴公司DBA笔试题
  8. Java 建模: 子整体软件开发,第二部分
  9. 重载 重写 多态区别
  10. C# web 读取excel并导入数据库
  11. python进阶 pdf_Python进阶(Intermediate_Python)_中文PDF彩色版.pdf
  12. 学习大数据必须掌握哪些核心技术?
  13. [GZOI2019GXOI2019]省选AFO记
  14. 今年双11,飞猪的“非OTA”之路走得怎么样了?
  15. jdk版本升级、技术选型
  16. 手机照片局部放大镜_揭秘“网红大片”里的“骗局”!用手机就能惊艳朋友圈...
  17. 「Gitee篇」如何用Git平台账号登录建木CI
  18. 黑客是如何炼成的(自学黑客4大知识点)
  19. 第二章 bean捆绑基础(3节)
  20. springboot+freemarker导出word

热门文章

  1. 使用 FRP 反向代理实现 Windows 远程连接
  2. Docker的4种网络模式
  3. linux给普通用户sudo权限
  4. golang 打印调用堆栈
  5. 分支优化:neg+sbb算术运算代替逻辑跳
  6. Windows8系统服务终极优化
  7. Android环境的构建
  8. Python深入04 闭包
  9. The Elements of Statistical Learning的笔记
  10. linux创建mysql视图_MySQL视图基本操作