对于学过的东西,想系统记录一下,这里记录的是在Ai 旅途中常用到的opencv 相关知识,快速带你进阶opencv
opencv c++ 中最常见的就是Mat类型。Mat 它是一个类,它所创建的对象类似于python 版opencv 中numpy 数据结构,因此也可以把他理解为一个存放矩阵的容器。Mat类的详细介绍可以看官网的API,OpenCV: cv::Mat Class Reference
如何创建Mat 对象,关键要知道它有哪些构造函数,下面介绍常用的一些构造函数。
Mat()是默认构造函数 。如下隐式创建一个Mat型的m,它不包含任何数据。
#include
#include
using namespace std;
using namespace cv;
int main()
{
Mat m; // 隐式调用, 显示调用为: Mat m = Mat();
return 0;
}
Mat m(4, 4, CV_8UC3);
rows是矩阵的行,可以理解为图片的宽;cols是矩阵的列,可以理解为图片的高;type是mat的类型,形式为CV_深度_通道数。具体参看第4章节。
如下创建4*4的3通道的蓝色的一个图
#include "opencv01.h"
#include
#include
using namespace std;
using namespace cv;
int main()
{
Mat m(4, 4, CV_8UC3);
namedWindow("m", WINDOW_NORMAL);
m = Scalar(255, 0, 0); //BGR
cout << endl << m << endl;
imshow("m", m);
waitKey(0);
return 0;
}
Mat m(4, 4, CV_8UC3, Scalar(255, 0, 0));
与3.2一个意思。
Mat m(Size(4, 4), CV_8UC3, Scalar(255, 0, 0));
与3.2一个意思。
创建一个全0的3维数组
int ar[] = {3,2,4};
Mat m(3, ar, CV_8UC1, Scalar::all(0));
//复制构造函数
Mat m = src; //等价于Mat m(src)
Mat m(src);
Mat m = imread(string path); //读图
//复制构造函数 + 静态方法
Mat m1 = Mat::zeros(Size(4, 5), CV_8UC3); //全0
Mat m2 = Mat::ones(Size(4, 5), CV_8UC3); //全1
Mat m3 = Mat::eye(Size(4, 5), CV_8UC3); //单位矩阵
//creat方法
Mat m;
m.create(int _rows, int _cols, int _type);
m.create(Size _sz, int _type);
...
...
Mat m(cv::Size(4,5), CV_8UC3, Scalar(0,255,0));
cout << endl << m << endl;
//属性
cout << "维度:" << m.dims << endl;
cout << "行:" << m.rows << endl;
cout << "列:" << m.cols << endl;
cout << "形状:" << m.size << endl; //宽、高
cout << "宽:" << m.size[0] << "\t" << "高:" << m.size[1] << endl;
//方法
cout << "通道数:" << m.channels() << endl;
cout << "深度:" << m.depth() << endl;
...
结果:
[ 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0;
0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0;
0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0;
0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0;
0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0]
维度:2
行:5
列:4
形状:5 x 4
宽:5 高:4
通道数:3
深度:0
以下表二是opencv 中定义的所有类型,其形式是CV_深度_通道数,如CV_8UC3,代表深度为8位无符号3通道数据类型。
mat 中有个depth()的成员函数,其返回值就是深度,如下表一:
对于图像来说基本上只会用到CV_8UC(n),其他看看了解一下就可以了。一般图像,记住一下几个就可以了。
C1 :单通道,灰色
C3 :三通道,BGR
C4 :四通道,BGRA, A代表透明度
像素深度 = 8 * 通道数。因为我们正常显示的图片都是CV_8U。imshow函数在显示图像时,会将各种类型的数据都映射到[0, 255]。
我们看一下代码:
#include
using namespace std;
using namespace cv;
int main()
{
Mat m1(512, 512, CV_8UC3, Scalar(0, 255, 0));
Mat m2(512, 512, CV_16UC3, Scalar(0, 255, 0));
imshow("m1", m1);
imshow("m2", m2);
imwrite("m1.jpg", m1);
imwrite("m2.jpg", m2);
waitKey(0);
return 0;
}
结果:由于m2是CV_16UC3类型,其值[0, 65535]映射到[0, 255]就看起来是黑色的,
然后我们看一下保存的m1.jpg和m2.jpg,如下,我们可以看到图片都是绿色的,而且位深度都是8*3 = 24, 这说明,我们的jpg图片数据只能是8U格式。因此我们在用opencv做图像处理的时候一般定义mat为8U的格式。
表一:
返回值 | 深度 | 含义 | 取值范围 |
0 | CV_8U | 8位无符号整数 | 0~255 |
1 | CV_8S | 8位有符号整数 | -128~127 |
2 | CV_16U | 16位无符号整数 | 0~65535 |
3 | CV_16S | 16位有符号整数 | -32768~35767 |
4 | CV_32S | 32位有符号整数 | -2147483648~-2147483647 |
6 | CV_32F | 32位单精度浮点数 | -FLA_MAX~FLA_MAX |
7 | CV_64F | 64位双精度浮点数 | -DBL_MAX~DBL_MAX |
表二:
#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)) |