Detailed explanation of the reshape() function in OpenCV - change the number of channels of the matrix and serialize the matrix elements


Detailed explanation of the reshape() function in OpenCV - change the number of channels of the matrix and serialize the matrix elements

The reshape function in opencv can not only change the number of channels of the matrix, but also serialize the matrix elements

1. Function prototype
Mat Mat::reshape(
	int cn, 
	int rows=0
) const

参数解释:
cn:通道数,如果设为0,则表示保持通道数不变,否则变为设置的通道数;
rows:矩阵行数,如果设为0,则表示保持原有的行数不变,否则则变为设置的行数;
2. Examples

Initialize a matrix with 20 rows and 30 columns and 1 channel

#include <opencv2\opencv.hpp>
#include <iostream>
#include <demo.h>

using namespace cv;
using namespace std;

int main() {
    
    
	system("chcp 65001");

	// 初始化一个矩阵,20行30列1通道
	Mat data = Mat(20, 30, CV_32F);
	cout << "行数: " << data.rows << endl;
	cout << "列数: " << data.cols << endl;
	cout << "通道: " << data.channels() << endl;
	cout << endl;
	//(1)通道数不变,将矩阵序列化为1行N列的行向量
	Mat dstRows = data.reshape(0, 1);
	cout << "行数: " << dstRows.rows << endl;
	cout << "列数: " << dstRows.cols << endl;
	cout << "通道: " << dstRows.channels() << endl;
	cout << endl;
	//(2)通道数不变,将矩阵序列化N行1列的列向量
	/**
	* 序列成列向量比行向量要麻烦一些,还得去计算出需要多少行,但我们可以先序列成行向量,再转置;
	* Mat dst = data.reshape(0, 1);      //序列成行向量
	* Mat dst = data.reshape(0, 1).t();  //序列成列向量
	*/
	Mat dstCols = data.reshape(0, data.rows*data.cols);
	cout << "行数: " << dstCols.rows << endl;
	cout << "列数: " << dstCols.cols << endl;
	cout << "通道: " << dstCols.channels() << endl;
	cout << endl;

	//(3)通道数由1变为2,行数不变
	// 注意:从结果可以看出,列数被分出一半,放在第二个通道里去了;如果通道数由1变为3,行数不变,则每通道的列数变为原来的三分之一;需要注意的是,如果行保持不变,改变的通道数一定要能被列数整除,否则会报错
	Mat dstChannel1 = data.reshape(2, 0);
	cout << "行数: " << dstChannel1.rows << endl;
	cout << "列数: " << dstChannel1.cols << endl;
	cout << "通道: " << dstChannel1.channels() << endl;
	cout << endl;
	//(4)通道数由1变为2,行数变为原来的五分之一
	Mat dstChannel2 = data.reshape(2, data.rows/5);
	cout << "行数: " << dstChannel2.rows << endl;
	cout << "列数: " << dstChannel2.cols << endl;
	cout << "通道: " << dstChannel2.channels() << endl;
	cout << endl;

	waitKey();
	destroyAllWindows();
	return 0;
}

insert image description here

3. Conclusion:
  • It can be seen that no matter how it is changed, it follows such an equation: 变化之前的 rows*cols*channels = 变化之后的 rows*cols*channels, we can only change the number of channels and rows, and the number of columns cannot be changed. It changes automatically, but it should be noted that when changing, we must consider When it comes to whether it is evenly divisible, if the changed value is not evenly divisible, an error will be reported;
  • When opencv is serialized, it is line serialized, that is, from left to right, from top to bottom;

Guess you like

Origin blog.csdn.net/qq_33867131/article/details/131769674