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的内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • numpy库reshape用法详解

    numpy.reshape(重塑) 给数组一个新的形状而不改变其数据 numpy.reshape(a, newshape, order='C')参数: a:array_like 要重新形成的数组. newshape:int或tuple的整数 新的形状应该与原始形状兼容.如果是整数,则结果将是该长度的1-D数组.一个形状维度可以是-1.在这种情况下,从数组的长度和其余维度推断该值. order:{'C','F','A'}可选 使用此索引顺序读取a的元素,并使用此索引顺序将元素放置到重新形成的数组中

  • 基于PyTorch的permute和reshape/view的区别介绍

    二维的情况 先用二维tensor作为例子,方便理解. permute作用为调换Tensor的维度,参数为调换的维度.例如对于一个二维Tensor来说,调用tensor.permute(1,0)意为将1轴(列轴)与0轴(行轴)调换,相当于进行转置. In [20]: a Out[20]: tensor([[0, 1, 2], [3, 4, 5]]) In [21]: a.permute(1,0) Out[21]: tensor([[0, 3], [1, 4], [2, 5]]) 如果使用view(

  • numpy库ndarray多维数组的维度变换方法(reshape、resize、swapaxes、flatten)

    numpy库对多维数组有非常灵巧的处理方式,主要的处理方法有: .reshape(shape) : 不改变数组元素,返回一个shape形状的数组,原数组不变 .resize(shape) : 与.reshape()功能一致,但修改原数组 In [22]: a = np.arange(20) #原数组不变 In [23]: a.reshape([4,5]) Out[23]: array([[ 0, 1, 2, 3, 4], [ 5, 6, 7, 8, 9], [10, 11, 12, 13, 14

  • 浅谈numpy中函数resize与reshape,ravel与flatten的区别

    这两组函数中区别很是类似,都是一个不改变之前的数组,一个改变数组本身 resize和reshape >>> import numpy as np >>> a = np.arange(20).reshape(4,5) >>> a array([[ 0, 1, 2, 3, 4], [ 5, 6, 7, 8, 9], [10, 11, 12, 13, 14], [15, 16, 17, 18, 19]]) >>> a.reshape(2,1

  • OpenCV reshape函数实现矩阵元素序列化

    在opencv中,reshape函数比较有意思,它既可以改变矩阵的通道数,又可以对矩阵元素进行序列化,非常有用的一个函数. 函数原型: C++: Mat Mat::reshape(int cn, int rows=0) const 参数比较少,但设置的时候却要千万小心. cn: 表示通道数(channels), 如果设为0,则表示保持通道数不变,否则则变为设置的通道数. rows: 表示矩阵行数. 如果设为0,则表示保持原有的行数不变,否则则变为设置的行数. 首先设置一个初始矩阵:一个20行30

  • Numpy中的shape、reshape函数的区别

    目录 1 shape()函数 2 reshape()函数 1 shape()函数 读取矩阵的长度,比如shape[0]就是读取矩阵第一维度的长度,相当于行数.它的输入参数可以是一个整数表示维度,也可以是一个矩阵.shape函数返回的是一个元组tuple,表示数组(矩阵)的维度/ 形状,例子如下: w.shape[0]返回的是w的行数 w.shape[1]返回的是w的列数 df.shape():查看行数和列数 1. 数组(矩阵)只有一个维度时,shape只有shape[0],返回的是该一维数组(矩

  • 深入浅析OpenCV copyTo()函数

    目录 copyTo() 函数原型 简单示例 mask参数深入探究 copyTo() 函数原型 copyTo这个函数有两种定义方式,分别是: void copyTo( OutputArray m ) const; void copyTo( OutputArray m, InputArray mask ) const; 参数: 一个参数:一张输出图像 两个参数:一张输出图像和一个掩码图 简单示例 例如: image_in.copyTo(image_out); 就是把image_in这张图复制(cop

  • 基于OpenCV与JVM实现矩阵处理图像

    目录 图片裁剪 图片模糊处理 子矩阵生成矩阵 从图片子矩阵生成矩阵 submat(int rowStart, int rowEnd, int colStart, int colEnd) 函数的返回值是一个矩阵对象.内容是原图的子矩阵或子区域. 首先我们用imread来读取图片,然后输出矩阵对象本身的一些信息 import org.opencv.core.CvType; import org.opencv.core.Mat; import org.opencv.core.Core; import

  • OpenCV每日函数之BarcodeDetector类条码检测器

    目录 一.概述 二.类参考 1.函数原型 2.参数详解 三.OpenCV源码 1.源码路径 2.源码代码 四.效果图像示例 一.概述 OpenCV在V4.5.3版本的contrib包中提供了一个barcode::BarcodeDetector类,用于条形码的识别. 二.类参考 1.函数原型 构造方法 cv::barcode::BarcodeDetector::BarcodeDetector ( const std::string & prototxt_path = "", co

  • Kotlin语法学习-变量定义、函数扩展、Parcelable序列化等简单总结

    Kotlin语法学习-变量定义.函数扩展.Parcelable序列化等简单总结 今年 Google I/O 2017 开发者大会中,Google 宣布正式把 Kotlin 纳入 Android 程序的官方一级开发语言(First-class language),作为Android开发者,当然要逐步熟悉这门语言,第一步就要从语法开始学习. 在这之前,我们需要了解怎么使用Kotlin编写一个Android应用.对于Android Studio 3.0版本,我们在创建工程的时候直接勾选 Include

  • 使用OpenCV circle函数图像上画圆的示例代码

    OpenCV中circle与rectangle函数显示,只不过rectangle在图像中画矩形,circle在图像中画圆. void circle(Mat img, Point center, int radius, Scalar color, int thickness=1, int lineType=8, int shift=0) img为源图像 center为画圆的圆心坐标 radius为圆的半径 color为设定圆的颜色,规则根据B(蓝)G(绿)R(红) thickness 如果是正数,

  • 详解numpy.ndarray.reshape()函数的参数问题

    我们知道numpy.ndarray.reshape()是用来改变numpy数组的形状的,但是它的参数会有一些特殊的用法,这里我们进一步说明一下.代码如下: import numpy as np class Debug: def __init__(self): self.array1 = np.ones(6) def mainProgram(self): print("The value of array1 is: ") print(self.array1) print("Th

  • jquery中封装函数传递当前元素的方法示例

    最近在工作中遇到一个问题,需要对页面上一组元素进行ajax操作,结构如下: <div id="aid"></div> <div id="aid"></div> <div id="aid"></div> <div id="aid"></div> <div id="stop">Stop here</

  • 使用jQuery中的wrap()函数操作HTML元素的教程

    wrap()函数用于在每个匹配元素外部包裹指定的HTML结构. 与该函数相对的是unwrap()函数,用于当前匹配元素的父元素(只移除父元素,其内部节点全部保留). 该函数属于jQuery对象(实例). 语法 jQueryObject.wrap( wrapper ) 参数 wrapper String/Element/jQuery/Function类型用于包裹匹配元素的节点. 如果参数wrapper为字符串,则将其视作jQuery选择器或html字符串,jQuery会自行判断. jQuery 1

随机推荐