opencv 学习:reshape函数
在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函数相关推荐
- Opencv的reshape函数
reshape函数既可以改变矩阵的通道数,又可以对矩阵元素进行序列化,而且不需要复制数据. C++: Mat Mat::reshape(int cn, int rows=0 ) const 参数虽然比 ...
- OpenCV学习+常用函数记录①:图像的基本处理
OpenCV 图像的基本处理 1.1 图片读取和显示 1.2 写入文件(保存) 1.3 像素操作 1.4 图片剪切 1.5 镜像处理: 1.6 图像缩放 1.7 图像位移 1.8 图像旋转 1.9 仿 ...
- OpenCV学习(函数)
OpenCV[未完结] 1_图片读取与显示 imread()函数:读取图片 param1:图片的名称 如果当前读入的图片与该脚本在相同目录下,则路径可以为相对路径 如果当前读入的图片不与该脚本在相同目 ...
- python学习-reshape()函数理解
文章目录 前言 一.reshape() 1.reshape(m,n) 2.reshape(m,n,p) 3.对多维数组reshape 总结 前言 提示:这里可以添加本文要记录的大概内容: 例如:随着人 ...
- OpenCV——Mat reshape函数
Mat reshape(int cn, int rows=0) const; cn: 表示通道数(channels), 如果设为0,则表示保持通道数不变,否则则变为设置的通道数. rows: 表示矩阵 ...
- OpenCV reshape函数需要注意的细节
OpenCV reshape函数需要注意的细节 [尊重原创,转载请注明出处]https://blog.csdn.net/guyuealian/article/details/80252853 本人在使 ...
- 【youcans 的 OpenCV 学习课】7. 空间域图像滤波
专栏地址:『youcans 的图像处理学习课』 文章目录:『youcans 的图像处理学习课 - 总目录』 [youcans 的 OpenCV 学习课]7. 空间域图像滤波 图像滤波是在尽可能保留图像 ...
- opencv reshape函数详解
在opencv中,reshape函数比较有意思,它既可以改变矩阵的通道数,又可以对矩阵元素进行序列化,非常有用的一个函数. 函数原型: C++: Mat Mat::reshape(int cn, in ...
- OpenCV 学习笔记03 boundingRect、minAreaRect、minEnclosingCircle、boxPoints、int0、circle、rectangle函数的用法...
函数中的代码是部分代码,详细代码在最后 1 cv2.boundingRect 作用:矩形边框(boundingRect),用于计算图像一系列点的外部矩形边界. cv2.boundingRect(arr ...
最新文章
- [转] L1 L2范数
- 类的加载顺序和对象的实例化
- (17)10-10-12分页
- 计算机现代管理专业,信息管理与信息系统是个鸡肋专业吗?
- C#与时间有关的一些方法
- java 问题排查_JAVA问题排查笔记
- 阿里巴巴公司DBA笔试题
- Java 建模: 子整体软件开发,第二部分
- 重载 重写 多态区别
- C# web 读取excel并导入数据库
- python进阶 pdf_Python进阶(Intermediate_Python)_中文PDF彩色版.pdf
- 学习大数据必须掌握哪些核心技术?
- [GZOI2019GXOI2019]省选AFO记
- 今年双11,飞猪的“非OTA”之路走得怎么样了?
- jdk版本升级、技术选型
- 手机照片局部放大镜_揭秘“网红大片”里的“骗局”!用手机就能惊艳朋友圈...
- 「Gitee篇」如何用Git平台账号登录建木CI
- 黑客是如何炼成的(自学黑客4大知识点)
- 第二章 bean捆绑基础(3节)
- springboot+freemarker导出word