代码环境:Visual studio2017和Anaconda;
参考书籍:张平《OpenCV算法精解》;
编程语言:Python和C++;
Python3基础学习:Python3基础
C++基础学习:C++基础
1.初识Mat类
// 1.初识Mat // 1.1 Mat是Matrix的缩写,代表矩阵或数组的意思,该类声明在opencv2corecore.hpp中; // 1.2 构造Mat对象相当于构造一个矩阵,需要四个要素:行数(高)、列数(宽)、通道数、数据类型; // 1.3 Mat类构造函数语法格式:Mat(int rows,int cols,int type) // 1.3.1 rows:矩阵的行数; // 1.3.2 cols:矩阵的列数; // 1.3.3 type:类型,包括通道数和数据类型; // type可以设置的值: // CV_8UC(n)、CV_8SC(n)、CV_16SC(n)、CV_16UC(n)、CV_32SC(n)、CV_32FC(n)、CV_64FC(n)、CV_64FC(n); // 说明: // a.8U、8S、16S、16U、32S、32F、64F前的数字代表Mat中每一个数值所占的bit数,1byte=8bit; // b.32F即占4个字节的float类型,64F即占8个字节的double类型,32S即占4字节的int类型,8U即占1字节的uchar类型; // c.C(n)代表通道数,n=1,构造单通道或称二维矩阵,n>1,构造多通道矩阵即三维矩阵;2.构造单通道Mat对象
// 2.构造单通道Mat对象 #include3.获得单通道Mat的基本信息#include using namespace std; using namespace cv; int main(int argc,char *argv[]) { Mat array1 = Mat(3, 4, CV_32FC(1)); // 构造3行4列的矩阵; Mat ones = Mat::ones(3, 4, CV_32FC1); // 构造3行4列全1的float类型的单通道矩阵; Mat zeros = Mat::zeros(3, 4, CV_32FC1); // 构造3行4列全0的float类型的单通道矩阵; cout << "3行4列全1矩阵:" << "n" << ones << endl; cout << "---------------" << endl; cout << "3行4列全0矩阵:" << "n" << zeros << endl; return 0; }
// 3.获得单通道Mat的基本信息 #include4.访问单通道Mat对象中的值#include using namespace std; using namespace cv; int main(int argc,char *argv[]) { // 1.使用成员变量rows和cols获取矩阵的行数和列数; Mat array1 = (Mat_ (3, 2) << 11, 12, 33, 43, 51, 16); // 构造目标矩阵; cout << "矩阵行数:" << array1.rows << endl; // 打印矩阵的行数; cout << "矩阵列数:" << array1.cols << endl; // 打印矩阵的列数; // 2.使用成员函数size()获取矩阵尺寸; Size size = array1.size(); cout << "矩阵尺寸:" << array1.size << endl; // 3.使用成员函数channels()得到矩阵的通道数; cout << "矩阵通道数:" << array1.channels() << endl; // 4.使用成员函数total()得到矩阵的行数乘以列数,即面积; cout << "矩阵面积:" << array1.total() << endl; // 5.使用成员变量dims获取矩阵的维数; cout << "矩阵维数:" << array1.dims << endl; return 0; }
// 4.访问单通道Mat对象中的值 // 4.1 利用成员函数at访问对象中的值; #include#include using namespace std; using namespace cv; int main(int argc,char *argv[]) { // 1.利用成员函数at访问对象中的值; Mat array1 = (Mat_ (3, 2) << 11, 12, 33, 43, 51, 16); // 构造单通道矩阵; for (int r = 0; r < array1.rows; r++) { for (int c = 0; c < array1.cols; c++) { cout << array1.at (r, c) << ","; // 第r行第c列的值; } cout << endl; } return 0; }
// 4.2 利用成员函数ptr访问对象中的值; // 对于Mat中的数值在内存中的存储,每一行的值是存储在连续的内存区域中,通过成员函数ptr获得指向每一行首地址的指针; #include#include using namespace std; using namespace cv; int main(int argc,char *argv[]) { // 2.利用成员函数ptr访问对象中的值; Mat array1 = (Mat_ (3, 2) << 1, 2, 3, 4, 5, 6); // 构造单通道矩阵; for (int r = 0; r < array1.rows; r++) { const int *ptr = array1.ptr (r); // 获得第r行行首的地址; for (int c = 0; c < array1.cols; c++) { cout << ptr[c] << ","; // 打印第r行的所有值; } cout << endl; } return 0; }
// 4.3 利用成员函数isContinuous和ptr // 每一行的所有值存储在连续的内存区域中,行与行之间可能会有间隔,如果isContinuous返回值为true,则代表行与行之间也是连续存储的,即所有值都是连续存储的; #include5.向量类Vec#include using namespace std; using namespace cv; int main(int argc,char *argv[]) { // 3.利用成员函数isContinous和ptr访问对象中的值; Mat array1 = (Mat_ (3, 2) << 1, 2, 3, 4, 5, 6); // 构造单通道矩阵; if (array1.isContinuous()) { int *ptr = array1.ptr (0); // 得到矩阵的第一个值的地址; for (int n = 0; n < array1.rows*array1.cols; n++) { cout << ptr[n] << ","; } } return 0; }
// 5.向量类Vec // 此处的向量理解为数学意义上的列向量,构造一个_cn×1的列向量,数据类型为_Tp; // 格式:Vec#include #include using namespace std; using namespace cv; int main(int argc,char *argv[]) { // 5.向量类Vec Vec vi(1, 2, 3, 4); // 构造一个长度为4,数据类型为int且初始化为1,2,3,4的列向量; cout << "向量的行数:" << vi.rows << endl; cout << "向量的列数:" << vi.cols << endl; // 使用[]或()访问元素; cout << "访问第0个元素:" << vi[0] << endl; cout << "访问第3个元素:" << vi(3) << endl; return 0; }



