注:自己写博客主要是做笔记,记录学到的知识点,加深对所学的知识点的理解,重复学到的知识点,故内容与所参考学习的博客或者书籍基本没有不同
reshape函数既可以改变通道数,又可以对矩阵元素进行序列化。
函数原型:
C++: Mat Mat::reshape(int cn,int rows=0) const
cn:表示通道数(channels),如果设置为0,则表示通道不变;
如果设置为其他数字,表示要设置的通道数
rows:表示矩阵行数,如果设置为0,则表示保持原有行数不变,如果设置为其他数字,表示要设置的行数

#include "pch.h"
#include <opencv2/opencv.hpp>
#include <iostream>

using namespace std;
using namespace cv;

int main()
{
	Mat data = Mat(20,30,CV_32F);//设置一个20行30列1通道的一个举证
	cout << "行数" << data.rows << endl;
	cout << "列数" << data.cols << endl;
	cout << "通道" << data.channels() << endl<<endl;

	//使用Mat::reshape()函数,不改变通道数,将矩阵序列化为1行N列的行向量
	Mat dst1 = data.reshape(0,1);
	cout << "行数" << dst1.rows << endl;
	cout << "列数" << dst1.cols << endl;
	cout << "通道" << dst1.channels() << endl<<endl;

	//使用Mat::reshape()函数,不改变通道数,将矩阵序列化为N行1列的行向量
	Mat dst2 = data.reshape(0, data.rows*data.cols);
	cout << "行数" << dst2.rows << endl;
	cout << "列数" << dst2.cols << endl;
	cout << "通道" << dst2.channels() << endl << endl;

	//上步不改变通道数,将序列转化为N行1列的行向量需要计算行数
	//换个方法 先序列化为行向量,再转置
	Mat dst3 = data.reshape(0,1);
	Mat dst4 = data.reshape(0, 1).t();
	cout << "行数" << dst4.rows << endl;
	cout << "列数" << dst4.cols << endl;
	cout << "通道" << dst4.channels() << endl << endl;

	//通道数由1变为2,行数不变
	Mat dst5 = data.reshape(2, 0);
	cout << "行数" << dst5.rows << endl;
	cout << "列数" << dst5.cols << endl;
	cout << "通道" << dst5.channels() << endl << endl;
    //由结果可知,列数被分出了一般给第二个通道
	//同理,如果通道由1变为3,行数不变,则通道的列数变为原来的三分之一
	//需要注意的是,如果行保持不变,改变的通道数一定能被列整除,否则会出错

	//通道数由1变为3,行数不变
	Mat dst6 = data.reshape(3, 0);
	cout << "行数" << dst6.rows << endl;
	cout << "列数" << dst6.cols << endl;
	cout << "通道" << dst6.channels() << endl << endl;

	//通道1到2,行数变为原来的五分之一
	Mat dst7 = data.reshape(2, data.rows/5);
	cout << "行数" << dst7.rows << endl;
	cout << "列数" << dst7.cols << endl;
	cout << "通道" << dst7.channels() << endl << endl;
	//遵循 变化之前的rows*cols*channels=变化之后的rows*cols*channels;需注意在变化的时候要考虑到是否整除的情况。
	//如果改变的数值不能够整除,就会报错

	//验证opencv在序列化的时候是行序列化还是列序列化
	Mat data_1 = (Mat_<int>(2,3)<<1,2,3,10,20,30);//2行3列的矩阵
	cout << data_1 << endl;
	Mat dst_1 = data_1.reshape(0,6);//通道不变,序列成列向量;结果为6行一列
	cout << endl << dst_1 << endl;
	Mat dst_2 = data_1.reshape(0, 1);//通道不变,序列成行向量;结果为1行6列
	cout << endl << dst_2 << endl;


	//从结果中可以看出,opencv里不管是变化成行向量还是列向量,opencv都是行序列化,即从左到右,从上到下
	//相对应的,在matlab里,是列序列化,即从上到下,从左到右


	system("pause");
	//C++中system("pause")简单来说,暂停的意思;一般在linux编程时会用到,等待接受信号,才会重新运行。
	/*
		在进行C/C++编程的时候,运行程序查看输出效果的时候,会出现窗口闪一下就关闭的情况。
		C语言中一般通过添加getchar();
		C++中一般在mian函数中的return之前添加system("pause");这样可以看到清楚输出的结果,pause会输出"press any key to contine"。
	*/
	return 1;
}

reshape函数怎么把数据取出来_序列化