- 前言
这次主要介绍了Mat类中,一些区域的选取和数学计算,里面的函数和用法都已经在代码中进行了解释。
#include<opencv2\opencv.hpp>
#include<iostream>
using namespace std;
using namespace cv;
template <class T>
void display(string str, Mat& src) //将矩阵数据进行展示
{
cout << str << endl;
int cols = src.cols;
int rows = src.rows;
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
cout << src.at<T>(i, j) << ",";
}
cout << endl;
}
}
int main()
{
//----------------------------------------------------------------------
//创建一个矩阵,并且获取其基本信息
//----------------------------------------------------------------------
Mat matrix = (Mat_<int>(5, 5) << 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25);//创建一个5行5列的矩阵,int类型
cout << "尺寸:" << (Size)matrix.size()<< endl; //打印尺寸
cout << "通道数:" << matrix.channels() << endl;//打印通道数
cout << "行数乘以列数:" << matrix.total() << endl;//和通道数无关
cout << "维度:" << matrix.dims << endl;//矩阵维度
//----------------------------------------------------------------------
//获取Mat矩阵中的某一区域值
//----------------------------------------------------------------------
//1.使用成员函数row(i)或着col(j)
Mat mr = matrix.row(3); //得到矩阵的第3行
Mat mc = matrix.col(3); //得到矩阵的第3列
display<int>("矩阵的行",mr);
display<int>("矩阵的列",mc);
//2.使用成员成员函数rowRange(),colRange()
Mat r_rang = matrix.rowRange(Range(2, 4)); //获取matrix的第2,3行
display<int>("获取第2,3行",r_rang);
Mat c_rang = matrix.colRange(Range(2, 4)); //获取第2,3列
display<int>("获取第2,3列",c_rang);
//这里的c_rang和r_rang都是指向原来的矩阵的。他们的地址都是一样的
//3.使用clone和copyTo
r_rang = matrix.rowRange(2, 4).clone();//将第2,3行克隆一份,修改了r_rang,matrix也不会变
matrix.colRange(2, 4).copyTo(c_rang); //将matrix中的第2,3列复制到c_rang中
display<int>("赋值第2,3行", r_rang);
display<int>("赋值第2,3列", c_rang);
//4.使用Rect类
// 一下三种方式都是获取一个区域
/*
1 2 3 4 5
6 7 8 9 10 8 9
11 12 13 14 15 ---> 13 14
16 17 18 19 20
21 22 23 24 25
*/
Mat roi1 = matrix(Rect(Point(2, 1),Point(4, 3))); //左上角的坐标,右下角的坐标 区间:左闭右开
Mat roi2 = matrix(Rect(2, 1, 2, 2)); //起始坐标+宽度和高度
Mat roi3 = matrix(Rect(Point(2, 1), Size(2, 2)));//起始坐标+尺寸
display<int>("获取矩阵的区域方法一:", roi1);
display<int>("获取矩阵的区域方法二:", roi2);
display<int>("获取矩阵的区域方法三:", roi3);
//----------------------------------------------------------------------
//关于矩阵的运算
//----------------------------------------------------------------------
//1.矩阵相加
//方法一:利用重载运算符 一般用在矩阵类型相同的部分
Mat src1 = (Mat_<int>(2, 3) << 23, 123, 90, 100, 250, 0);
Mat src2 = (Mat_<int>(2, 3) << 125, 150, 60, 100, 10, 40);
Mat dst = src1 + src2;
display<int>("运算符矩阵相加",dst);
//方法二:利用add函数
src2.convertTo(dst, CV_8U);
add(src1, dst, dst,Mat(),CV_64FC1);//可是用于不同的数据类型的矩阵
//第四个类型参数 只有类型是相同的才可以使用默认值-1
display<float>("add函数矩阵相加", dst);
//2.矩阵相减
//方法一:矩阵相减 利用重载运算符
dst = src1 - src2;
display<int>("运算符矩阵相减", dst);
//方法二:使用subtract()
subtract(src1, src2, dst);
display<int>("substract矩阵相减", dst);
//3.点乘运算 两个矩阵对应位置的数相乘
//方法一,利用Mat里面的成员函数 mul
dst = src1.mul(src2); //两个数据类型必须相同才可以
display<int>("mul矩阵点乘", dst);
//方法二:利用multiply函数,可以用于不同的数据类型
multiply(src1, src2, dst);
display<int>("multiply矩阵点乘", dst);
//4.点除运算 两个矩阵对应位置相除
dst = src1 / src2;
display<int>("点除运算", dst);
//5.矩阵乘法
//注意!!!矩阵乘法只能接受float或者double类型,对于其他类型的矩阵乘法会报错
//注意!!!矩阵乘法只能接受float或者double类型,对于其他类型的矩阵乘法会报错
//注意!!!矩阵乘法只能接受float或者double类型,对于其他类型的矩阵乘法会报错
//方法一:利用重载运算符进行计算
Mat src3 = (Mat_<float>(2, 3) << 1.0, 2, 3, 4, 5, 6);
Mat src4 = (Mat_<float>(3, 2) << 6.0, 5, 4, 3, 2, 1);
dst = src3*src4;
display<float>("利用运算符进行矩阵乘法", dst);
//注:如果是双通道,那就是当做一个复数矩阵相乘,列如
Mat src5 = (Mat_<Vec2f>(2, 1) << Vec2f(1, 2), Vec2f(3, 4));
Mat src6 = (Mat_<Vec2f>(1, 2) << Vec2f(10, 20), Vec2f(5, 15));
dst = src5*src6;
display<Vec2f>("双通道矩阵乘法", dst);
//方法二利用Opencv给出的gemm函数 (geem是generalized matrix multiplication的缩写)
gemm(src3, src4, 1, NULL, 0, dst, 0); //函数参数flag为0时:和输出结果为:dst = src1*src2*alpha + src3*beta
display<float>("gemm函数进行矩阵乘法", dst);
//6.其他运算
//(1)幂指数
Mat src7 = (Mat_<float>(2,2) << 2, 3, 4, 5);
pow(src7, 2, dst);
display<float>("幂指数运算pow:", dst);
//(2)开平方运算
sqrt(src7, dst);
display<float>("开放运算sqrt:", dst);
//(3)指数运算
exp(src7, dst);
display<float>("指数运算exp:", dst);
//(4)对数运算 log是以e为底的 也就是ln
log(src7, dst);
display<float>("对数运算log:", dst);
system("pause");
return 0;
}