OpenCV Mat实例详解 一

          OpenCV中的Mat是一个类,它用存储图像信息。由两部分数据组成:矩阵头和像素值矩阵。矩阵头包含矩阵尺寸、存储方法、存储地址等信息,而像素值矩阵则存储实际的像素值数据。

        Mat类在OpenCV中有十分重要的作用,图像信息的载入、保存、传递都离不开Mat类。OpenCV用来保存图像矩阵类型的数据信息,包括向量、矩阵、灰度或彩色图像等数据。通过使用Mat类,可以对图像进行各种操作和变换,例如裁剪、旋转、缩放、滤波等。 下面详细介绍Mat类中的常用方法(函数)。

Mat 类的常用构造函数

        Mat类的构造函数原型有很多,下面介绍几个常用的构造函数及其用法。

        Mat (int rows, int cols, int type);

        rows图像的像素行数,也可以说是以像素为单位的高度。

         cols图像的像素列数,也可以说是以像素为单位的宽度。

        type 数据类型,OpenCV的数据类型定义在interface.h中。如下:

 
#define 	CV_8U   0
 
#define 	CV_8S   1
 
#define 	CV_16U   2
 
#define 	CV_16S   3
 
#define 	CV_32S   4
 
#define 	CV_32F   5
 
#define 	CV_64F   6
 
#define 	CV_16F   7
  
#define 	CV_MAKE_TYPE   CV_MAKETYPE
 
#define 	CV_8UC1   CV_MAKETYPE(CV_8U,1)
 
#define 	CV_8UC2   CV_MAKETYPE(CV_8U,2)
 
#define 	CV_8UC3   CV_MAKETYPE(CV_8U,3)
 
#define 	CV_8UC4   CV_MAKETYPE(CV_8U,4)
 
#define 	CV_8UC(n)   CV_MAKETYPE(CV_8U,(n))
 
#define 	CV_8SC1   CV_MAKETYPE(CV_8S,1)
 
#define 	CV_8SC2   CV_MAKETYPE(CV_8S,2)
 
#define 	CV_8SC3   CV_MAKETYPE(CV_8S,3)
 
#define 	CV_8SC4   CV_MAKETYPE(CV_8S,4)
 
#define 	CV_8SC(n)   CV_MAKETYPE(CV_8S,(n))
 
#define 	CV_16UC1   CV_MAKETYPE(CV_16U,1)
 
#define 	CV_16UC2   CV_MAKETYPE(CV_16U,2)
 
#define 	CV_16UC3   CV_MAKETYPE(CV_16U,3)
 
#define 	CV_16UC4   CV_MAKETYPE(CV_16U,4)
 
#define 	CV_16UC(n)   CV_MAKETYPE(CV_16U,(n))
 
#define 	CV_16SC1   CV_MAKETYPE(CV_16S,1)
 
#define 	CV_16SC2   CV_MAKETYPE(CV_16S,2)
 
#define 	CV_16SC3   CV_MAKETYPE(CV_16S,3)
 
#define 	CV_16SC4   CV_MAKETYPE(CV_16S,4)
 
#define 	CV_16SC(n)   CV_MAKETYPE(CV_16S,(n))
 
#define 	CV_32SC1   CV_MAKETYPE(CV_32S,1)
 
#define 	CV_32SC2   CV_MAKETYPE(CV_32S,2)
 
#define 	CV_32SC3   CV_MAKETYPE(CV_32S,3)
 
#define 	CV_32SC4   CV_MAKETYPE(CV_32S,4)
 
#define 	CV_32SC(n)   CV_MAKETYPE(CV_32S,(n))
 
#define 	CV_32FC1   CV_MAKETYPE(CV_32F,1)
 
#define 	CV_32FC2   CV_MAKETYPE(CV_32F,2)
 
#define 	CV_32FC3   CV_MAKETYPE(CV_32F,3)
 
#define 	CV_32FC4   CV_MAKETYPE(CV_32F,4)
 
#define 	CV_32FC(n)   CV_MAKETYPE(CV_32F,(n))
 
#define 	CV_64FC1   CV_MAKETYPE(CV_64F,1)
 
#define 	CV_64FC2   CV_MAKETYPE(CV_64F,2)
 
#define 	CV_64FC3   CV_MAKETYPE(CV_64F,3)
 
#define 	CV_64FC4   CV_MAKETYPE(CV_64F,4)
 
#define 	CV_64FC(n)   CV_MAKETYPE(CV_64F,(n))
 
#define 	CV_16FC1   CV_MAKETYPE(CV_16F,1)
 
#define 	CV_16FC2   CV_MAKETYPE(CV_16F,2)
 
#define 	CV_16FC3   CV_MAKETYPE(CV_16F,3)
 
#define 	CV_16FC4   CV_MAKETYPE(CV_16F,4)
 
#define 	CV_16FC(n)   CV_MAKETYPE(CV_16F,(n))
 

下面以实例演示其用法

        在VS 中新建一个C++ 控制台程序,完成代码如下:

// OpenCVMatTest.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。


#include <iostream>
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

int main()
{
    Mat tmp(100,200, CV_8U);
    cout <<"构造Mat对象的高度为: " << tmp.rows << endl;
    cout << "构造Mat对象的宽度为: " << tmp.cols << endl;
    cout << "构造Mat对象的数据类型为: " << tmp.type() << endl;
}

试运行结果如下:

说明已成功构造对象。将构造函数的type直接输入0,也是同样的结果。如下:

 Mat tmp(100, 200,0);

如果将type参数用CV_8UC1替代结果又如何,如下:

// OpenCVMatTest.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。


#include <iostream>
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

int main()
{
    //Mat tmp(100,200, CV_8U);
    Mat tmp(100, 200, CV_8UC1);
    cout <<"构造Mat对象的高度为: " << tmp.rows << endl;
    cout << "构造Mat对象的宽度为: " << tmp.cols << endl;
    cout << "构造Mat对象的数据类型为: " << tmp.type() << endl;
}

试运行的结果,如下:

结果并未发生改变。修改代码如下:

// OpenCVMatTest.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。


#include <iostream>
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

int main()
{
    //Mat tmp(100,200, CV_8U);
    Mat tmp(100, 200, CV_8UC1);
    cout <<"构造Mat对象的高度为: " << tmp.rows << endl;
    cout << "构造Mat对象的宽度为: " << tmp.cols << endl;
    cout << "构造Mat对象的通道数为: " << tmp.channels() << endl;
    cout << "构造Mat对象的位深度为: " << tmp.depth() << endl;
    cout << "构造Mat对象的数据类型为: " << tmp.type() << endl;
}

、试运行的结果如下:

再次修改代码如下:

// OpenCVMatTest.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。


#include <iostream>
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

int main()
{
    //Mat tmp(100,200, CV_8U);
    Mat tmp(100, 200, CV_8UC2);
    cout <<"构造Mat对象的高度为: " << tmp.rows << endl;
    cout << "构造Mat对象的宽度为: " << tmp.cols << endl;
    cout << "构造Mat对象的通道数为: " << tmp.channels() << endl;
    cout << "构造Mat对象的位深度为: " << tmp.depth() << endl;
    cout << "构造Mat对象的数据类型为: " << tmp.type() << endl;
}

试运行结果如下:

可以看出数据类型与通道数发生了改变,位深度是0,即8位。再修改代码改成如下:

// OpenCVMatTest.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。


#include <iostream>
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

int main()
{
    //Mat tmp(100,200, CV_8U);
    //Mat tmp(100, 200, CV_8UC2);
    Mat tmp(100, 200, CV_8SC3);
    cout <<"构造Mat对象的高度为: " << tmp.rows << endl;
    cout << "构造Mat对象的宽度为: " << tmp.cols << endl;
    cout << "构造Mat对象的通道数为: " << tmp.channels() << endl;
    cout << "构造Mat对象的位深度为: " << tmp.depth() << endl;
    cout << "构造Mat对象的数据类型为: " << tmp.type() << endl;
}

试运行结果如下:

 说明type参数与位深度与通道数相关。从数据类型定义即可看出,如CV_8UC1其中的8U表示位深度为0,即8位无符号数据,C1表示通道数为1。

        Mat (Size size, int type);

这个构造函数与上面构造函数,只不过用Size参数代替了rows、cols参数。下面演示其使用。将上面的示例代码修改如下:

// OpenCVMatTest.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。


#include <iostream>
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

int main()
{
    //Mat tmp(100,200, CV_8U);
    //Mat tmp(100, 200, CV_8UC2);
    //Mat tmp(100, 200, CV_8SC3);

    Mat tmp(Size(100, 200), CV_16UC3);
    cout <<"构造Mat对象的高度为: " << tmp.rows << endl;
    cout << "构造Mat对象的宽度为: " << tmp.cols << endl;
    cout << "构造Mat对象的通道数为: " << tmp.channels() << endl;
    cout << "构造Mat对象的位深度为: " << tmp.depth() << endl;
    cout << "构造Mat对象的数据类型为: " << tmp.type() << endl;
}

试运行,结果如下:

可以看出Size的第一个参数是cols,第二个参数是rows,这点需要注意。

MatMat (int rows, int cols, int type, const Scalar &s)

 修改上面示例程序代码来演示该构造函数的使用,代码修改如下:

// OpenCVMatTest.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。


#include <iostream>
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

int main()
{
    //Mat tmp(100,200, CV_8U);
    //Mat tmp(100, 200, CV_8UC2);
    //Mat tmp(100, 200, CV_8SC3);

    Mat tmp = Mat(Size(400, 200), CV_8UC3, Scalar(255,0,0));
    cout <<"构造Mat对象的高度为: " << tmp.rows << endl;
    cout << "构造Mat对象的宽度为: " << tmp.cols << endl;
    cout << "构造Mat对象的通道数为: " << tmp.channels() << endl;
    cout << "构造Mat对象的位深度为: " << tmp.depth() << endl;
    cout << "构造Mat对象的数据类型为: " << tmp.type() << endl;
    cout << "构造Mat对象的Size为: " << tmp.size() << endl;
    imshow("构造图像", tmp);
    waitKey(0);

试运行,结果如下:

可以看出,已经构造出蓝色图片的Mat对象。

Mat (Size size, int type, const Scalar &s)

这个构造函数与上面的构造函数类似,就不再做详细介绍。

Mat (int ndims, const int *sizes, int type)

ndims 维数,只有1,2有效。

size 包含rows,cols的数组名

修改上面示例代码,来演示该构造函数的用法,修改后的代码如下:

// OpenCVMatTest.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。


#include <iostream>
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

int main()
{
    //Mat tmp(100,200, CV_8U);
    //Mat tmp(100, 200, CV_8UC2);
    //Mat tmp(100, 200, CV_8SC3);
    //Mat tmp = Mat(Size(400, 200), CV_8UC3, Scalar(255,0,0));
    int size[] = {400,200};
    Mat tmp = Mat(2, size, CV_8UC3, Scalar(0,255,0));
    cout <<"构造Mat对象的高度为: " << tmp.rows << endl;
    cout << "构造Mat对象的宽度为: " << tmp.cols << endl;
    cout << "构造Mat对象的通道数为: " << tmp.channels() << endl;
    cout << "构造Mat对象的位深度为: " << tmp.depth() << endl;
    cout << "构造Mat对象的数据类型为: " << tmp.type() << endl;
    cout << "构造Mat对象的Size为: " << tmp.size() << endl;
    imshow("构造图像", tmp);
    waitKey(0);
}

试运行后,结果如下:

 可以看出,数组的第一个元素被作为rows,第二个元素作为cols。把ndims参数值设为1,运行结果如下:

可以看出,构造对象图片的列变成了1,rows依然使用的数组的第一个元素。

Mat (const std::vector< int > &sizes, int type);

Mat (int ndims, const int *sizes, int type, const Scalar &s)

size 装有图像维度数据的vector 对象,

type 数据类型

s 含义颜色信息的Scalar参数

修改上面例程中的代码,来演示该构造函数的用法,修改后的代码如下:

// OpenCVMatTest.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。


#include <iostream>
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

int main()
{
    //Mat tmp(100,200, CV_8U);
    //Mat tmp(100, 200, CV_8UC2);
    //Mat tmp(100, 200, CV_8SC3);
    //Mat tmp = Mat(Size(400, 200), CV_8UC3, Scalar(255,0,0));
    //int size[] = {400,200};
    // Mat tmp = Mat(2, size, CV_8UC3, Scalar(0,255,0));
    //Mat tmp = Mat(1, size, CV_8UC3, Scalar(0, 255, 0));
    vector<int> size(2);
    size[0] = 400;
    size[1] = 200;
    Mat tmp = Mat(size, CV_8UC3, Scalar(0, 255, 0));
    cout <<"构造Mat对象的高度为: " << tmp.rows << endl;
    cout << "构造Mat对象的宽度为: " << tmp.cols << endl;
    cout << "构造Mat对象的通道数为: " << tmp.channels() << endl;
    cout << "构造Mat对象的位深度为: " << tmp.depth() << endl;
    cout << "构造Mat对象的数据类型为: " << tmp.type() << endl;
    cout << "构造Mat对象的Size为: " << tmp.size() << endl;
    imshow("构造图像", tmp);
    waitKey(0);
}

试运行,结果如下:

 可以看出已成功构造对象,且vector对象的第一个元素作为rows,第二个元素作为cols。

Mat (const Mat &m)

以已有的Mat对象,构造新的·Mat对象。m: Mat源

修改上面代码,来演示该构造函数的使用方法,修改后的代码如下:

// OpenCVMatTest.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。


#include <iostream>
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

int main()
{
    //Mat tmp(100,200, CV_8U);
    //Mat tmp(100, 200, CV_8UC2);
    //Mat tmp(100, 200, CV_8SC3);
    //Mat tmp = Mat(Size(400, 200), CV_8UC3, Scalar(255,0,0));
    //int size[] = {400,200};
    // Mat tmp = Mat(2, size, CV_8UC3, Scalar(0,255,0));
    //Mat tmp = Mat(1, size, CV_8UC3, Scalar(0, 255, 0));
    //vector<int> size(2);
    //size[0] = 400;
    //size[1] = 200;
    //Mat tmp = Mat(size, CV_8UC3, Scalar(0, 255, 0));
    Mat src = imread("1.jpg");
    src.resize(src.rows / 2, src.cols / 2);
    Mat tmp = Mat(src);
    cout <<"构造Mat对象的高度为: " << tmp.rows << endl;
    cout << "构造Mat对象的宽度为: " << tmp.cols << endl;
    cout << "构造Mat对象的通道数为: " << tmp.channels() << endl;
    cout << "构造Mat对象的位深度为: " << tmp.depth() << endl;
    cout << "构造Mat对象的数据类型为: " << tmp.type() << endl;
    cout << "构造Mat对象的Size为: " << tmp.size() << endl;
    cout << "构造Mat对象的Step为: " << tmp.step << endl;
    imshow("构造图像", tmp);
    waitKey(0);
}

试运行,结果如下:

Mat (int rows, int cols, int type, void *data, size_t step=AUTO_STEP);

Mat (Size size, int type, void *data, size_t step=AUTO_STEP);

Mat (int ndims, const int *sizes, int type, void *data, const size_t *steps=0);

Mat (const std::vector< int > &sizes, int type, void *data, const size_t *steps=0);

rows 构造对象图像rows

cols 构造对象图像 cols

type 构造对象图像数据类型

data 构造对象图像数据指针

ndims 构造对象图像的维度数

size 包含构造对象rows,cols参数的数组名

step 每个行矩阵所占的字节数。

steps 指向step的指针。

修改上面示例代码,来演示以上构造函数的用法,修改后的代码如下:

// OpenCVMatTest.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。


#include <iostream>
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

int main()
{
    //Mat tmp(100,200, CV_8U);
    //Mat tmp(100, 200, CV_8UC2);
    //Mat tmp(100, 200, CV_8SC3);
    //Mat tmp = Mat(Size(400, 200), CV_8UC3, Scalar(255,0,0));
    //int size[] = {400,200};
    // Mat tmp = Mat(2, size, CV_8UC3, Scalar(0,255,0));
    //Mat tmp = Mat(1, size, CV_8UC3, Scalar(0, 255, 0));
    //vector<int> size(2);
    //size[0] = 400;
    //size[1] = 200;
    //Mat tmp = Mat(size, CV_8UC3, Scalar(0, 255, 0));
    Mat src = imread("1.jpg");
    src.resize(src.rows / 2, src.cols / 2);
    //Mat tmp = Mat(src);
    Mat tmp = Mat(src.rows, src.cols, src.type(),src.data);
    cout <<"构造Mat对象的高度为: " << tmp.rows << endl;
    cout << "构造Mat对象的宽度为: " << tmp.cols << endl;
    cout << "构造Mat对象的通道数为: " << tmp.channels() << endl;
    cout << "构造Mat对象的位深度为: " << tmp.depth() << endl;
    cout << "构造Mat对象的数据类型为: " << tmp.type() << endl;
    cout << "构造Mat对象的Size为: " << tmp.size() << endl;
    cout << "构造Mat对象的Step为: " << tmp.step << endl;
    imshow("构造图像", tmp);
    waitKey(0);
}

试运行,结果如下:

修改上面示例代码,来演示另外构造函数的使用,修改后的代码如下:

// OpenCVMatTest.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。


#include <iostream>
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

int main()
{
    //Mat tmp(100,200, CV_8U);
    //Mat tmp(100, 200, CV_8UC2);
    //Mat tmp(100, 200, CV_8SC3);
    //Mat tmp = Mat(Size(400, 200), CV_8UC3, Scalar(255,0,0));
    //int size[] = {400,200};
    // Mat tmp = Mat(2, size, CV_8UC3, Scalar(0,255,0));
    //Mat tmp = Mat(1, size, CV_8UC3, Scalar(0, 255, 0));
    //vector<int> size(2);
    //size[0] = 400;
    //size[1] = 200;
    //Mat tmp = Mat(size, CV_8UC3, Scalar(0, 255, 0));
    Mat src = imread("1.jpg");
    src.resize(src.rows / 2, src.cols / 2);
    //Mat tmp = Mat(src);
    //Mat tmp = Mat(src.rows, src.cols, src.type(),src.data);
    Mat tmp = Mat(src.size(), src.type(), src.data);
    cout <<"构造Mat对象的高度为: " << tmp.rows << endl;
    cout << "构造Mat对象的宽度为: " << tmp.cols << endl;
    cout << "构造Mat对象的通道数为: " << tmp.channels() << endl;
    cout << "构造Mat对象的位深度为: " << tmp.depth() << endl;
    cout << "构造Mat对象的数据类型为: " << tmp.type() << endl;
    cout << "构造Mat对象的Size为: " << tmp.size() << endl;
    cout << "构造Mat对象的Step为: " << tmp.step << endl;
    imshow("构造图像", tmp);
    waitKey(0);
}

试运行,结果如下:

修改上面示例代码,来演示另外构造函数的使用,修改后的代码如下:

// OpenCVMatTest.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。


#include <iostream>
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

int main()
{
    //Mat tmp(100,200, CV_8U);
    //Mat tmp(100, 200, CV_8UC2);
    //Mat tmp(100, 200, CV_8SC3);
    //Mat tmp = Mat(Size(400, 200), CV_8UC3, Scalar(255,0,0));
    //int size[] = {400,200};
    // Mat tmp = Mat(2, size, CV_8UC3, Scalar(0,255,0));
    //Mat tmp = Mat(1, size, CV_8UC3, Scalar(0, 255, 0));
    //vector<int> size(2);
    //size[0] = 400;
    //size[1] = 200;
    //Mat tmp = Mat(size, CV_8UC3, Scalar(0, 255, 0));
    Mat src = imread("1.jpg");
    src.resize(src.rows / 2, src.cols / 2);
    //Mat tmp = Mat(src);
    //Mat tmp = Mat(src.rows, src.cols, src.type(),src.data);
    //Mat tmp = Mat(src.size(), src.type(), src.data);
    Mat tmp = Mat(700,800, CV_8UC3, src.data+800*3);
    cout <<"构造Mat对象的高度为: " << tmp.rows << endl;
    cout << "构造Mat对象的宽度为: " << tmp.cols << endl;
    cout << "构造Mat对象的通道数为: " << tmp.channels() << endl;
    cout << "构造Mat对象的位深度为: " << tmp.depth() << endl;
    cout << "构造Mat对象的数据类型为: " << tmp.type() << endl;
    cout << "构造Mat对象的Size为: " << tmp.size() << endl;
    cout << "构造Mat对象的Step为: " << tmp.step << endl;
    imshow("构造图像", tmp);
    waitKey(0);
}

试运行,结果如下: 

Mat (const Mat &m, const Range &rowRange, const Range &colRange=Range::all());

Mat (const Mat &m, const Rect &roi);

Mat (const Mat &m, const Range *ranges);

Mat (const Mat &m, const std::vector< Range > &ranges);

m 分配给构建对象的Mat对象

rowRange 行范围

colRange 列范围

roi 感兴趣的矩形区域

ranges Range数组或Range的vector 容器

用此构造函数构建的Mat对象不会拷贝数据,修改新构建对象的数据反而来修改新构建Mat对象的数据会修改已有Mat对象m的数据,实质上已有图像构建感兴趣区域对象。

修改上面示例代码,来演示构造函数的使用,修改后的代码如下:

// OpenCVMatTest.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。


#include <iostream>
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

int main()
{
    //Mat tmp(100,200, CV_8U);
    //Mat tmp(100, 200, CV_8UC2);
    //Mat tmp(100, 200, CV_8SC3);
    //Mat tmp = Mat(Size(400, 200), CV_8UC3, Scalar(255,0,0));
    //int size[] = {400,200};
    // Mat tmp = Mat(2, size, CV_8UC3, Scalar(0,255,0));
    //Mat tmp = Mat(1, size, CV_8UC3, Scalar(0, 255, 0));
    //vector<int> size(2);
    //size[0] = 400;
    //size[1] = 200;
    //Mat tmp = Mat(size, CV_8UC3, Scalar(0, 255, 0));
    Mat src = imread("1.jpg");
    src.resize(src.rows / 2, src.cols / 2);
    //Mat tmp = Mat(src);
    //Mat tmp = Mat(src.rows, src.cols, src.type(),src.data);
    //Mat tmp = Mat(src.size(), src.type(), src.data);
    //Mat tmp = Mat(700,800, CV_8UC3, src.data+800*3);
    Range rowRange = Range(0, 700);
    Range colRange = Range(0, 700);
    Mat tmp = Mat(src, rowRange, colRange);
    cout <<"构造Mat对象的高度为: " << tmp.rows << endl;
    cout << "构造Mat对象的宽度为: " << tmp.cols << endl;
    cout << "构造Mat对象的通道数为: " << tmp.channels() << endl;
    cout << "构造Mat对象的位深度为: " << tmp.depth() << endl;
    cout << "构造Mat对象的数据类型为: " << tmp.type() << endl;
    cout << "构造Mat对象的Size为: " << tmp.size() << endl;
    cout << "构造Mat对象的Step为: " << tmp.step << endl;
    imshow("构造图像", tmp);
    waitKey(0);
}


试运行,结果如下:

 修改上面示例代码,来演示构造函数的使用,修改后的代码如下:

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

int main()
{
    //Mat tmp(100,200, CV_8U);
    //Mat tmp(100, 200, CV_8UC2);
    //Mat tmp(100, 200, CV_8SC3);
    //Mat tmp = Mat(Size(400, 200), CV_8UC3, Scalar(255,0,0));
    //int size[] = {400,200};
    // Mat tmp = Mat(2, size, CV_8UC3, Scalar(0,255,0));
    //Mat tmp = Mat(1, size, CV_8UC3, Scalar(0, 255, 0));
    //vector<int> size(2);
    //size[0] = 400;
    //size[1] = 200;
    //Mat tmp = Mat(size, CV_8UC3, Scalar(0, 255, 0));
    Mat src = imread("1.jpg");
    src.resize(src.rows / 2, src.cols / 2);
    //Mat tmp = Mat(src);
    //Mat tmp = Mat(src.rows, src.cols, src.type(),src.data);
    //Mat tmp = Mat(src.size(), src.type(), src.data);
    //Mat tmp = Mat(700,800, CV_8UC3, src.data+800*3);
    //Range rowRange = Range(0, 700);
    //Range colRange = Range(0, 700);
    //Mat tmp = Mat(src, rowRange, colRange);
    Rect rec = Rect(100, 0, 700, 700);
    Mat tmp = Mat(src, rec);
    cout <<"构造Mat对象的高度为: " << tmp.rows << endl;
    cout << "构造Mat对象的宽度为: " << tmp.cols << endl;
    cout << "构造Mat对象的通道数为: " << tmp.channels() << endl;
    cout << "构造Mat对象的位深度为: " << tmp.depth() << endl;
    cout << "构造Mat对象的数据类型为: " << tmp.type() << endl;
    cout << "构造Mat对象的Size为: " << tmp.size() << endl;
    cout << "构造Mat对象的Step为: " << tmp.step << endl;
    imshow("构造图像", tmp);
    waitKey(0);
}

试运行,结果如下:

 修改上面代码,来演示另一构造函数的使用,修改后的代码如下:

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

int main()
{
    //Mat tmp(100,200, CV_8U);
    //Mat tmp(100, 200, CV_8UC2);
    //Mat tmp(100, 200, CV_8SC3);
    //Mat tmp = Mat(Size(400, 200), CV_8UC3, Scalar(255,0,0));
    //int size[] = {400,200};
    // Mat tmp = Mat(2, size, CV_8UC3, Scalar(0,255,0));
    //Mat tmp = Mat(1, size, CV_8UC3, Scalar(0, 255, 0));
    //vector<int> size(2);
    //size[0] = 400;
    //size[1] = 200;
    //Mat tmp = Mat(size, CV_8UC3, Scalar(0, 255, 0));
    Mat src = imread("1.jpg");
    src.resize(src.rows / 2, src.cols / 2);
    //Mat tmp = Mat(src);
    //Mat tmp = Mat(src.rows, src.cols, src.type(),src.data);
    //Mat tmp = Mat(src.size(), src.type(), src.data);
    //Mat tmp = Mat(700,800, CV_8UC3, src.data+800*3);
    //Range rowRange = Range(0, 700);
    //Range colRange = Range(0, 700);
    //Mat tmp = Mat(src, rowRange, colRange);
    //Rect rec = Rect(100, 0, 700, 700);
    //Mat tmp = Mat(src, rec);
    Range rowRange = Range(0, 700);
    Range colRange = Range(100, 700);
    Range ranges[] = {rowRange, colRange};
    Mat tmp = Mat(src, ranges);
    cout <<"构造Mat对象的高度为: " << tmp.rows << endl;
    cout << "构造Mat对象的宽度为: " << tmp.cols << endl;
    cout << "构造Mat对象的通道数为: " << tmp.channels() << endl;
    cout << "构造Mat对象的位深度为: " << tmp.depth() << endl;
    cout << "构造Mat对象的数据类型为: " << tmp.type() << endl;
    cout << "构造Mat对象的Size为: " << tmp.size() << endl;
    cout << "构造Mat对象的Step为: " << tmp.step << endl;
    imshow("构造图像", tmp);
    waitKey(0);
}

试运行,结果如下:

 修改上面代码,来演示另一构造函数的使用,修改后的代码如下:

// OpenCVMatTest.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。


#include <iostream>
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

int main()
{
    //Mat tmp(100,200, CV_8U);
    //Mat tmp(100, 200, CV_8UC2);
    //Mat tmp(100, 200, CV_8SC3);
    //Mat tmp = Mat(Size(400, 200), CV_8UC3, Scalar(255,0,0));
    //int size[] = {400,200};
    // Mat tmp = Mat(2, size, CV_8UC3, Scalar(0,255,0));
    //Mat tmp = Mat(1, size, CV_8UC3, Scalar(0, 255, 0));
    //vector<int> size(2);
    //size[0] = 400;
    //size[1] = 200;
    //Mat tmp = Mat(size, CV_8UC3, Scalar(0, 255, 0));
    Mat src = imread("1.jpg");
    src.resize(src.rows / 2, src.cols / 2);
    //Mat tmp = Mat(src);
    //Mat tmp = Mat(src.rows, src.cols, src.type(),src.data);
    //Mat tmp = Mat(src.size(), src.type(), src.data);
    //Mat tmp = Mat(700,800, CV_8UC3, src.data+800*3);
    //Range rowRange = Range(0, 700);
    //Range colRange = Range(0, 700);
    //Mat tmp = Mat(src, rowRange, colRange);
    //Rect rec = Rect(100, 0, 700, 700);
    //Mat tmp = Mat(src, rec);
    Range rowRange = Range(0, 700);
    Range colRange = Range(100, 700);
    //Range ranges[] = {rowRange, colRange};
    //Mat tmp = Mat(src, ranges);
    vector<Range> ranges1(2);
    ranges1[0] = rowRange;
    ranges1[1] = colRange;
    Mat tmp = Mat(src, ranges1);
    cout <<"构造Mat对象的高度为: " << tmp.rows << endl;
    cout << "构造Mat对象的宽度为: " << tmp.cols << endl;
    cout << "构造Mat对象的通道数为: " << tmp.channels() << endl;
    cout << "构造Mat对象的位深度为: " << tmp.depth() << endl;
    cout << "构造Mat对象的数据类型为: " << tmp.type() << endl;
    cout << "构造Mat对象的Size为: " << tmp.size() << endl;
    cout << "构造Mat对象的Step为: " << tmp.step << endl;
    imshow("构造图像", tmp);
    waitKey(0);
}

由于篇幅关系,OpenCV构造函数暂时介绍在这里,将在下篇博文中继续介绍OpenCV Mat类。

        本篇 博文示例是基于OpenCV4.8(opencv目录位于d盘根目录下)及VS2022。示例源码已上传到CSDN,其链接为:https://download.csdn.net/download/billliu66/88831683

   

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/389443.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【知识图谱--第三讲知识图谱的存储与查询】

知识图谱的存储与查询 基于关系型数据库的知识图谱存储基于原生图数据库的知识图谱存储原生图数据库实现原理浅析 基于关系型数据库的知识图谱存储 基于原生图数据库的知识图谱存储 原生图数据库实现原理浅析

每日一题——LeetCode1437.是否所有1都至少相隔k个元素

方法一 两次遍历&#xff1a; 第一次遍历保存所有1的位置到res里&#xff0c;第二次遍历res检查是否所有相邻元素之间间隔都>k var kLengthApart function(nums, k) {let res[]for(let i0;i<nums.length;i){if(nums[i]1){res.push(i)}}for(let i1;i<res.length;i){…

Python 中实现线性搜索算法

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站零基础入门的AI学习网站~。 前言 线性搜索算法&#xff0c;也称为顺序搜索算法&#xff0c;是一种简单但常用的搜索技术&#xff0c;用于查…

VMwareWorkstation17.0虚拟机安装Windows2.03完整详细步骤图文教程

VMwareWorkstation17.0虚拟机安装Windows2.03完整详细步骤图文教程 第一篇 下载Windows2.03第二篇 配置Windows2.03虚拟机机器环境第三篇 启动Windows2.03系统 第一篇 下载Windows2.03 1.Windows2.0原版软盘下载地址是 暂不提供&#xff0c;后续更新 2.Windows2.03虚拟机镜像下…

P1228 地毯填补问题题解

题目 相传在一个古老的阿拉伯国家里&#xff0c;有一座宫殿。宫殿里有个四四方方的格子迷宫&#xff0c;国王选择驸马的方法非常特殊&#xff0c;也非常简单&#xff1a;公主就站在其中一个方格子上&#xff0c;只要谁能用地毯将除公主站立的地方外的所有地方盖上&#xff0c;…

MATLAB知识点:poissrnd函数(★★☆☆☆)生成泊松分布的随机数

讲解视频&#xff1a;可以在bilibili搜索《MATLAB教程新手入门篇——数学建模清风主讲》。​ MATLAB教程新手入门篇&#xff08;数学建模清风主讲&#xff0c;适合零基础同学观看&#xff09;_哔哩哔哩_bilibili 节选自第3章&#xff1a;课后习题讲解中拓展的函数 在讲解第三…

开源PDF工具 Apache PDFBox 认识及使用(知识点+案例)

文章目录 前言源码获取一、认识PDFBox二、导入依赖三、基础功能demo1&#xff1a;读取pdf所有内容demo2&#xff1a;读取所有页内容&#xff08;分页&#xff09;demo3&#xff1a;添加页眉、页脚demo4&#xff1a;添加居中45文字水印demo5&#xff1a;添加图片到右上角 参考文…

(四)【Jmeter】 JMeter的界面布局与组件概述

JMeter的界面布局 中文版&#xff1a; 英文版&#xff1a; JMeter的主界面包括菜单栏、工具栏、树形结构面板、视图面板等部分。 菜单栏&#xff1a;菜单栏包含了文件(File)、编辑(Edit)、查找(Search)、选项(Options)、工具(Tools)、帮助(Help)等菜单项&#xff0c;用于对…

WordPress作者页面链接的用户名自动变成16位字符串串插件Smart User Slug Hider

WordPress默认的作者页面URL链接地址格式为“你的域名/author/admin”&#xff0c;其中admin就是你的用户名&#xff0c;这样的话就会暴露我们的用户名。 为了解决这个问题&#xff0c;前面boke112百科跟大家分享了『如何将WordPress作者存档链接中的用户名改为昵称或ID』一文…

推荐在线图像处理程序源码

对于喜爱图像编辑的朋友们来说&#xff0c;Photoshop无疑是处理照片的利器。然而&#xff0c;传统的Photoshop软件不仅需要下载安装&#xff0c;还对电脑配置有一定的要求&#xff0c;这无疑增加了使用的门槛。 现在&#xff0c;我们为您带来一款革命性的在线PS修图工具——基…

紫微斗数双星组合:廉贞破军在卯酉

文章目录 前言内容总结 前言 紫微斗数双星组合&#xff1a;廉贞破军在卯酉 内容 紫微斗数双星组合&#xff1a;廉贞破军在卯酉 性格分析 廉贞星、破军星二星同宫&#xff0c;具有冒险开创的精神和领导能力&#xff0c;忍耐力强&#xff0c;工作积极稳重&#xff0c;冲劲大&a…

(17)Hive ——MR任务的map与reduce个数由什么决定?

一、MapTask的数量由什么决定&#xff1f; MapTask的数量由以下参数决定 文件个数文件大小blocksize 一般而言&#xff0c;对于每一个输入的文件会有一个map split&#xff0c;每一个分片会开启一个map任务&#xff0c;很容易导致小文件问题&#xff08;如果不进行小文件合并&…

软件实例分享,药店进销存软件医药系统进销存教程

软件实例分享&#xff0c;药店进销存软件医药系统进销存教程 一、前言 以下软件程序教程以 佳易王药店进销存管理系统V16.0为例说明 软件文件下载可以点击最下方官网卡片——软件下载——试用版软件下载 软件可以对药品的有效期进行管理&#xff0c;可以查询还有多少天到期的…

如何查找Windows的桌面文件夹?这里提供详细步骤

当你的电脑上有不同的用户时&#xff0c;Windows 11、10、…上的桌面文件夹或桌面目录特别有用&#xff0c;那么哪里才是真正的桌面文件夹目录。 自己的Windows桌面目录 1、启动Windows资源管理器 2、按F4键并输入%UserProfile% 3、点击桌面 这是你个人桌面的正确文件夹路径…

【数据分享】1980s~2020年青藏高原中分辨率土地覆被数据

各位同学们好&#xff0c;今天和大伙儿分享的是1980s~2020年青藏高原中分辨率土地覆被数据。如果大家有下载处理数据等方面的问题&#xff0c;您可以私信或评论。 吴炳方. (2023). 青藏高原中分辨率土地覆被数据&#xff08;1980s-2020&#xff09;. 国家青藏高原数据中心. 1 …

【STM32 CubeMX】I2C查询方式

文章目录 前言一、CubeMX配置IIC二、查询方式的使用2.1 分析一种情况2.2 Master模式2.3 Mem模式 总结 前言 在STM32 CubeMX环境中&#xff0c;I2C&#xff08;Inter-Integrated Circuit&#xff09;通信协议的查询方式是一种简单而常见的通信方式。通过查询方式&#xff0c;微…

【并发编程】AQS原理

&#x1f4dd;个人主页&#xff1a;五敷有你 &#x1f525;系列专栏&#xff1a;并发编程 ⛺️稳中求进&#xff0c;晒太阳 1. 概述 全称是 AbstractQueuedSynchronizer&#xff0c;是阻塞式锁和相关的同步器工具的框架 特点&#xff1a; 用 state 属性来表示资源的状…

【漏洞复现】某情侣飞行棋源码未授权访问漏洞

Nx01 产品简介 情侣飞行棋源码是一款专为情侣设计的互动游戏。通过游戏的方式&#xff0c;它可以帮助情侣们建立共同兴趣&#xff0c;增加互动&#xff0c;增进了解&#xff0c;培养默契&#xff0c;并创造美好的回忆。 Nx02 漏洞描述 某情侣飞行棋源码存在未授权访问漏洞&…

讲解用Python处理Excel表格

我们今天来一起探索一下用Python怎么操作Excel文件。与word文件的操作库python-docx类似&#xff0c;Python也有专门的库为Excel文件的操作提供支持&#xff0c;这些库包括xlrd、xlwt、xlutils、openpyxl、xlsxwriter几种&#xff0c;其中我最喜欢用的是openpyxl&#xff0c;这…

[嵌入式系统-16]:RT-Thread -2- 主要功能功能组件详解与API函数说明

目录 一、RT-Thread主要功能组件 二、内核组件 2.1 概述 2.2 API 三、设备驱动 3.1 概述 3.2 API 四、通信组件 4.1 概述 4.4 API 五、网络组件 5.1 概述 5.2 API 5.3 补充&#xff1a;MQTT协议 六、文件系统 6.1 概述 6.2 API 七、GUI 组件 7.1 概述 7.2 …