Opencv 例程讲解 4 ----图片容器Mat
来源:互联网 发布:java简历工作经历 编辑:程序博客网 时间:2024/05/22 08:11
在前面的几个例程中,我们都有用到一个类 Mat,它作为opencv中图像数据,特征点,查表数组,直方图等数据的容器,可能是opencv中运用最普遍的一个类,几乎大多数的API都为这一数据类型留有接口。这次例程中,我们将看下opencv例程中是怎样展示这样一个强大的类的。对应的例程为 (TUTORIAL) mat_the_basic_image_container。
源代码如下:
/* For description look into the help() function. */#include "opencv2/core/core.hpp"#include <iostream>using namespace std;using namespace cv;static void help(){ cout << "\n--------------------------------------------------------------------------" << endl << "This program shows how to create matrices(cv::Mat) in OpenCV and its serial" << " out capabilities" << endl << "That is, cv::Mat M(...); M.create and cout << M. " << endl << "Shows how output can be formated to OpenCV, python, numpy, csv and C styles." << endl << "Usage:" << endl << "./cvout_sample" << endl << "--------------------------------------------------------------------------" << endl << endl;}int main(int,char**){ help(); // create by using the constructor Mat M(2,2, CV_8UC3, Scalar(0,0,255)); cout << "M = " << endl << " " << M << endl << endl; // create by using the create function() M.create(4,4, CV_8UC(2)); cout << "M = "<< endl << " " << M << endl << endl; // create multidimensional matrices int sz[3] = {2,2,2}; Mat L(3,sz, CV_8UC(1), Scalar::all(0)); // Cannot print via operator << // Create using MATLAB style eye, ones or zero matrix Mat E = Mat::eye(4, 4, CV_64F); cout << "E = " << endl << " " << E << endl << endl; Mat O = Mat::ones(2, 2, CV_32F); cout << "O = " << endl << " " << O << endl << endl; Mat Z = Mat::zeros(3,3, CV_8UC1); cout << "Z = " << endl << " " << Z << endl << endl; // create a 3x3 double-precision identity matrix Mat C = (Mat_<double>(3,3) << 0, -1, 0, -1, 5, -1, 0, -1, 0); cout << "C = " << endl << " " << C << endl << endl; Mat RowClone = C.row(1).clone(); cout << "RowClone = " << endl << " " << RowClone << endl << endl; // Fill a matrix with random values Mat R = Mat(3, 2, CV_8UC3); randu(R, Scalar::all(0), Scalar::all(255)); // Demonstrate the output formating options cout << "R (default) = " << endl << R << endl << endl; cout << "R (python) = " << endl << format(R,"python") << endl << endl; cout << "R (numpy) = " << endl << format(R,"numpy" ) << endl << endl; cout << "R (csv) = " << endl << format(R,"csv" ) << endl << endl; cout << "R (c) = " << endl << format(R,"C" ) << endl << endl; Point2f P(5, 1); cout << "Point (2D) = " << P << endl << endl; Point3f P3f(2, 6, 7); cout << "Point (3D) = " << P3f << endl << endl; vector<float> v; v.push_back( (float)CV_PI); v.push_back(2); v.push_back(3.01f); cout << "Vector of floats via Mat = " << Mat(v) << endl << endl; vector<Point2f> vPoints(20); for (size_t i = 0; i < vPoints.size(); ++i) vPoints[i] = Point2f((float)(i * 5), (float)(i % 7)); cout << "A vector of 2D Points = " << vPoints << endl << endl; return 0;}
可以看出,这个例程首先介绍了Mat 的几种基本的创建方法,包括利用构造函数创建,利用create函数创建;创建N-dimensional矩阵的方法等;接着展示了以不同风格输出mat数据的方法,包括默认风格,python风格,numpy风格,csv风格和c风格;最后,展示了opencv中二位点,三维点,序列以及序列点的数据的创建和输出。下面给出上述代码各自对应的输出结果。
1.利用构造函数创建,函数原型为 Mat(int rows, int cols, int type, const Scalar& s); Scalar 为一个四通道的double序列。CV_8UC3表示通道数位3,数据类型为CV_8U,还有其他几种类似的构造函数,有Scalar 参数的以Scalar的值进行初始化,没有设定初始化值的,初始化值不确定,但似乎有一定的规律,见下面create的结果。
//! constructs 2D matrix of the specified size and type // (_type is CV_8UC1, CV_64FC3, CV_32SC(12) etc.) Mat(int rows, int cols, int type); Mat(Size size, int type); //! constucts 2D matrix and fills it with the specified value _s. Mat(int rows, int cols, int type, const Scalar& s); Mat(Size size, int type, const Scalar& s);
// create by using the constructor Mat M(2,2, CV_8UC3, Scalar(0,0,255)); cout << "M = " << endl << " " << M << endl << endl;
M =
[0, 0, 255, 0, 0, 255;
0, 0, 255, 0, 0, 255]
2.利用create 函数创建,函数原型为void create(int rows, int cols, int type); 第一个参数为列数,第二个参数为函数,第三参数为type,CV_8UC(2) 表示通道数位2,数据类型为CV_8U的type
// create by using the create function() M.create(4,4, CV_8UC(2)); cout << "M = "<< endl << " " << M << endl << endl;M =
[205, 205, 205, 205, 205, 205, 205, 205;
205, 205, 205, 205, 205, 205, 205, 205;
205, 205, 205, 205, 205, 205, 205, 205;
205, 205, 205, 205, 205, 205, 205, 205]
3创建n-维的矩阵,注意这种Mat 不支持 cout<<输出,函数原型为Mat(int ndims, const int* sizes, int type, const Scalar& s); 同样存在一个不带初始化值的版本
Mat(int ndims, const int* sizes, int type);
// create multidimensional matrices int sz[3] = {2,2,2}; Mat L(3,sz, CV_8UC(1), Scalar::all(0));
4 创建matlab风格的矩阵,不详细介绍了,一看就明白
// Create using MATLAB style eye, ones or zero matrix Mat E = Mat::eye(4, 4, CV_64F); cout << "E = " << endl << " " << E << endl << endl; Mat O = Mat::ones(2, 2, CV_32F); cout << "O = " << endl << " " << O << endl << endl; Mat Z = Mat::zeros(3,3, CV_8UC1); cout << "Z = " << endl << " " << Z << endl << endl;E =
[1, 0, 0, 0;
0, 1, 0, 0;
0, 0, 1, 0;
0, 0, 0, 1]
O =
[1, 1;
1, 1]
Z =
[0, 0, 0;
0, 0, 0;
0, 0, 0]
5. 通过模板类Mat_创建,它是Mat 的派生模板类,两者之间可以相互隐式转换。Mat_主要实现对Mat 数据的迭代访问,可以利用坐标自己对像素进行操作,如果看过上一个例程的话,应该会对这个类型有影响。这里是用这个类型读入数据。
// create a 3x3 double-precision identity matrix Mat C = (Mat_<double>(3,3) << 0, -1, 0, -1, 5, -1, 0, -1, 0); cout << "C = " << endl << " " << C << endl << endl;C =
[0, -1, 0;
-1, 5, -1;
0, -1, 0]
6. 展示了Mat 对列数据的操作
Mat RowClone = C.row(1).clone(); cout << "RowClone = " << endl << " " << RowClone << endl << endl;RowClone =
[-1, 5, -1]
7. 利用随机数函数randu 初始化数据,函数原型为 void randu(InputOutputArray dst, InputArray low, InputArray high); 值的范围为[low, high)
// Fill a matrix with random values Mat R = Mat(3, 2, CV_8UC3); randu(R, Scalar::all(0), Scalar::all(255));
8 展示了几种风格的输出
// Demonstrate the output formating options cout << "R (default) = " << endl << R << endl << endl; cout << "R (python) = " << endl << format(R,"python") << endl << endl; cout << "R (numpy) = " << endl << format(R,"numpy" ) << endl << endl; cout << "R (csv) = " << endl << format(R,"csv" ) << endl << endl; cout << "R (c) = " << endl << format(R,"C" ) << endl << endl;R (default) =
[91, 2, 79, 179, 52, 205;
236, 8, 181, 239, 26, 248;
207, 218, 45, 183, 158, 101]
R (python) =
[[[91, 2, 79], [179, 52, 205]],
[[236, 8, 181], [239, 26, 248]],
[[207, 218, 45], [183, 158, 101]]]
R (numpy) =
array([[[91, 2, 79], [179, 52, 205]],
[[236, 8, 181], [239, 26, 248]],
[[207, 218, 45], [183, 158, 101]]], type='uint8')
R (csv) =
91, 2, 79, 179, 52, 205
236, 8, 181, 239, 26, 248
207, 218, 45, 183, 158, 101
R (c) =
{91, 2, 79, 179, 52, 205,
236, 8, 181, 239, 26, 248,
207, 218, 45, 183, 158, 101}
9 2维点,3维点,序列,点序列,比较简单,就不多加介绍了。注意序列不支持直接用cout<<输出,但可以转换成Mat进行输出。
Point2f P(5, 1); cout << "Point (2D) = " << P << endl << endl; Point3f P3f(2, 6, 7); cout << "Point (3D) = " << P3f << endl << endl; vector<float> v; v.push_back( (float)CV_PI); v.push_back(2); v.push_back(3.01f); cout << "Vector of floats via Mat = " << Mat(v) << endl << endl; vector<Point2f> vPoints(20); for (size_t i = 0; i < vPoints.size(); ++i) vPoints[i] = Point2f((float)(i * 5), (float)(i % 7)); cout << "A vector of 2D Points = " << vPoints << endl << endl;
Point (2D) = [5, 1]
Point (3D) = [2, 6, 7]
Vector of floats via Mat = [3.1415927; 2; 3.01]
A vector of 2D Points = [0, 0; 5, 1; 10, 2; 15, 3; 20, 4; 25, 5; 30, 6; 35, 0; 40, 1; 45, 2; 50, 3; 55, 4; 60, 5; 65, 6; 70, 0; 75, 1; 80, 2; 85, 3; 90, 4; 95, 5]
- Opencv 例程讲解 4 ----图片容器Mat
- Opencv 例程讲解1 ----如何载入并显示图片
- Opencv 例程讲解 6 ---- 图片融合 addWeighted到底有多快?
- Opencv 例程讲解8 ----如何实现Mat以及自定义类型的读写操作
- mat opencv 保存图片
- opencv Mat - 图像的容器
- opencv学习篇(4)Mat - 基本图像容器
- Opencv 例程讲解8 --- 扩展, 基于图片列表的简易浏览器
- linux openCV 显示图片例程
- Opencv 例程讲解 开头篇----window下例程编译
- OpenCV 学习笔记之Mat类讲解
- opencv数据容器Mat,cvMat和IplImage
- 学习opencv(3)---Mat - 基本图像容器
- opencv数据容器Mat,cvMat和IplImage
- OpenCV基础类容器Mat类详解
- opencv之图像容器Mat简介
- [opencv][MFC]显示mat图片于mfc
- OpenCV HSV图片处理 Mat元素操作
- 成为JavaGC专家Part I — 深入浅出Java垃圾回收机制
- 成为JavaGC专家Part I — 深入浅出Java垃圾回收机制
- spring mvc 多文件 上传 按天生成目录 ,删除,限制为图片代码,实际项目中应用代码
- 桥接模式——Head First Design Patterns
- DPMM和HDP 非参数贝叶斯(2)
- Opencv 例程讲解 4 ----图片容器Mat
- 夜读Web Service
- 基于标准的多媒体视频对讲系统
- Xshell 乱码 解决
- 考试的题
- 性能调优、虚拟机、垃圾回收、软硬件协调相关文章和视频 — Part1
- 在Windows平台上绿色安装postgresQL
- 1. Android学习路线图介绍
- jQuery中的$.ajax()方法