两种运算:
1、Mat类变量与常数的运算:加、减、乘、除。即矩阵与常数的运算。
2、Mat类变量与Mat类变量之间的运算:加、减、矩阵乘法、内积(点乘)、对应位乘法。
1、Mat类变量与常数的运算:加、减、乘、除。即矩阵与常数的运算。
要注意的就是:
1、Mat类变量与常数的运算中的加法和乘法都满足交换律的。
2、常数与Mat类变量运算结果的数据类型保留Mat类变量的数据类型。
3、cv::Mat 类的对象有一个成员函数type()用来返回矩阵元素的数据类型,返回值是 int 类型,不同的返回值代表不同的类型,具体对应关系如下所示:
1.1 下面是验证Mat类变量与常数的运算(加、减、乘、除),及其满足交换律
#include<iostream>
#include<opencv2\opencv.hpp>
using namespace std;
using namespace cv;
int main() {
// 定义Mat类变量并赋值
cv::Mat a = (cv::Mat_<int>(3, 3) << 1, 2, 3, 4, 5, 6, 7, 8, 9);
cv::Mat b = (cv::Mat_<int>(3, 3) << 11, 12, 13, 14, 15, 16, 17, 18, 19);
cv::Mat c = (cv::Mat_<double>(3, 3) << 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0);
cv::Mat d = (cv::Mat_<double>(3, 3) << 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9);
// 定义其他的Mat类型变量
cv::Mat a1, a11, a2, a22, a3, a33, a4, a44;
a1 = a + 1; // 等价于1+a
cout << "Mat类变量与常数的和a+1: " << endl;
cout << a1 << endl;
a11 = 1 + a; // 等价于a+1
cout << "常数与Mat类变量的和1+a: " << endl;
cout << a11 << endl;
cout << endl;
a2 = a - 1;
cout << "Mat类变量与常数的差a-1:" << endl;
cout << a2 << endl;
a22 = 1 - a;
cout << "常数与Mat类变量的差1-a:" << endl;
cout << a22 << endl;
cout << endl;
a3 = a * 2; // 等价于2*a
cout << "Mat类变量与常数的乘积a*2:" << endl;
cout << a3 << endl;
a33 = 2 * a; // 等价于a*2
cout << "常数与Mat类变量的乘积2*a:" << endl;
cout << a33 << endl;
cout << endl;
a4 = a / 1;
cout << "Mat类变量与常数的比值a/1: " << endl;
cout << a4 << endl;
a44 = 1 / a;
cout << "常数与Mat类变量的比值1/a: " << endl;
cout << a44 << endl;
return 0;
}
运行结果
1.2.1 下面是验证“常数与Mat类变量运算结果的数据类型保留Mat类变量的数据类型”
#include<iostream>
#include<opencv2\opencv.hpp>
using namespace std;
using namespace cv;
int main() {
// 定义Mat类变量并赋值
cv::Mat a = (cv::Mat_<int>(3, 3) << 1, 2, 3, 4, 5, 6, 7, 8, 9);
cout << "Mat类变量a的数据类型:" << a.type() << endl;
cv::Mat b = (cv::Mat_<double>(3, 3) << 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0);
cout << "Mat类变量b的数据类型:" << b.type() << endl;
cout << endl;
// 定义其他的Mat类型变量
cv::Mat a1, a11, a2, a22, a3, a33, a4, a44;
a1 = a + 1;
cout << "Mat类变量与常数的和a+1: " << endl;
cout << a1 << endl;
cout << "打印a1变量的数据类型:" << a1.type() << endl; //应该是CV_32S么?
a11 = a + 1.0;
cout << "Mat类变量与常数的和a+1.0:" << endl;
cout << a11 << endl;
cout << "打印a11变量的数据类型:" << a11.type() << endl; //应该是CV_32S么?
cout << endl;
a2 = a - 1;
cout << "Mat类变量与常数的差a-1: " << endl;
cout << a2 << endl;
cout << "打印a2变量的数据类型:" << a2.type() << endl; //应该是CV_32S么?
a22 = a - 1.0;
cout << "Mat类变量与常数的差a-1.0:" << endl;
cout << a22 << endl;
cout << "打印a22变量的数据类型:" << a22.type() << endl; //应该是CV_32S么?
cout << endl;
a3 = a * 2;
cout << "Mat类变量与常数的积a*2: " << endl;
cout << a3 << endl;
cout << "打印a3变量的数据类型:" << a3.type() << endl; //应该是CV_32S么?
a33 = a * 2.0;
cout << "Mat类变量与常数的和a*2.0:" << endl;
cout << a33 << endl;
cout << "打印a33变量的数据类型:" << a33.type() << endl; //应该是CV_32S么?
cout << endl;
a4 = a / 1;
cout << "Mat类变量与常数的商a/1: " << endl;
cout << a4 << endl;
cout << "打印a4变量的数据类型:" << a4.type() << endl; //应该是CV_32S么?
a44 = a / 1.0;
cout << "打印a44变量与常数的商a/1.0: " << endl;
cout << a44 << endl;
cout << "打印a44变量的数据类型:" << a44.type() << endl; //应该是CV_32S么?
return 0;
}
由于Mat类变量a的数据类型是CV_32S,因此后面运算的所有结果的数据类型都是CV_32S,运行结果如下:
1.2.2 下面依然是验证“常数与Mat类变量运算结果的数据类型保留Mat类变量的数据类型”
#include<iostream>
#include<opencv2\opencv.hpp>
using namespace std;
using namespace cv;
int main() {
// 定义Mat类变量并赋值
cv::Mat a = (cv::Mat_<int>(3, 3) << 1, 2, 3, 4, 5, 6, 7, 8, 9);
cout << "Mat类变量a的数据类型:" << a.type() << endl;
cv::Mat b = (cv::Mat_<double>(3, 3) << 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0);
cout << "Mat类变量b的数据类型:" << b.type() << endl;
cout << endl;
// 定义其他的Mat类型变量
cv::Mat b1, b11, b2, b22, b3, b33, b4, b44;
b1 = b + 1;
cout << "Mat类变量与常数的和b+1: " << endl;
cout << b1 << endl;
cout << "打印b1变量的数据类型:" << b1.type() << endl; //应该是CV_64F么?
b11 = b + 1.0;
cout << "Mat类变量与常数的和b+1.0:" << endl;
cout << b11 << endl;
cout << "打印b11变量的数据类型:" << b11.type() << endl; //应该是CV_64F么?
cout << endl;
b2 = b - 1;
cout << "Mat类变量与常数的差b-1: " << endl;
cout << b2 << endl;
cout << "打印b2变量的数据类型:" << b2.type() << endl; //应该是CV_64F么?
b22 = b - 1.0;
cout << "Mat类变量与常数的差b-1.0:" << endl;
cout << b22 << endl;
cout << "打印b22变量的数据类型:" << b22.type() << endl; //应该是CV_64F么?
cout << endl;
b3 = b * 2;
cout << "Mat类变量与常数的积b*2: " << endl;
cout << b3 << endl;
cout << "打印b3变量的数据类型:" << b3.type() << endl; //应该是CV_64F么?
b33 = b * 2.0;
cout << "Mat类变量与常数的和b*2.0:" << endl;
cout << b33 << endl;
cout << "打印b33变量的数据类型:" << b33.type() << endl; //应该是CV_64F么?
cout << endl;
b4 = b / 1;
cout << "Mat类变量与常数的商b/1: " << endl;
cout << b4 << endl;
cout << "打印b4变量的数据类型:" << b4.type() << endl; //应该是CV_64F么?
b44 = b / 1.0;
cout << "打印b44变量与常数的商b/1.0: " << endl;
cout << b44 << endl;
cout << "打印b44变量的数据类型:" << b44.type() << endl; //应该是CV_64F么?
return 0;
}
由于Mat类变量a的数据类型是CV_64F,因此后面运算的所有结果的数据类型都是CV_64F,运行结果如下:
2、Mat类变量与Mat类变量之间的运算:加、减、矩阵乘法、内积(点乘)、对应位乘法。
2.1 两个Mat类变量之间的加、减运算
需要注意的是,参与运算的两个Mat类变量之间的数据类型一定要相同,否则会报错!
#include<iostream>
#include<opencv2\opencv.hpp>
using namespace std;
using namespace cv;
int main() {
// 定义Mat类变量并赋值
cv::Mat a = (cv::Mat_<int>(3, 3) << 1, 2, 3, 4, 5, 6, 7, 8, 9);
cv::Mat b = (cv::Mat_<int>(3, 3) << 11, 12, 13, 14, 15, 16, 17, 18, 19);
cv::Mat c = (cv::Mat_<double>(3, 3) << 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0);
cv::Mat d = (cv::Mat_<double>(3, 3) << 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9);
cout << endl;
// 定义其他的Mat类型变量
cv::Mat a1, a2, a3, a4, a5, a6;
a1 = a + b;
a2 = a - b;
a3 = c + d;
a4 = c - d;
//a5 = a + c; //Mat类变量a与c的类型不同,会报错
//a6 = a - c; //Mat类变量a与c的类型不同,会报错
cout << "两个CV_32S类型的Mat类变量相加:" << endl;
cout << a1 << endl;
cout << "两个CV_32S类型的Mat类变量相减:" << endl;
cout << a2 << endl;
cout << "两个CV_64F类型的Mat类变量相加:" << endl;
cout << a3 << endl;
cout << "两个CV_64F类型的Mat类变量相减:" << endl;
cout << a4 << endl;
return 0;
}
运行结果如下
2.2 两个Mat类变量之间的数学乘积
需要注意的是:
1、两个Mat类变量之间的“*”运算要求第一个Mat类矩阵的列数必须与第二个Mat类矩阵的行数相同;
2、该运算要求Mat类中的数据类型必须是CV_32FC1、CV_64FC1、CV_32FC2、CV_64FC2这四种中的一种,也就是对于一个二维的Mat类矩阵,其保存的数据类型必须是float类型或者是double类型。
#include<iostream>
#include<opencv2\opencv.hpp>
using namespace std;
using namespace cv;
int main() {
// 定义Mat类变量并赋值
cv::Mat a = (cv::Mat_<int>(3, 3) << 1, 2, 3, 4, 5, 6, 7, 8, 9);
cv::Mat b = (cv::Mat_<int>(3, 3) << 11, 12, 13, 14, 15, 16, 17, 18, 19);
cv::Mat c = (cv::Mat_<double>(3, 3) << 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0);
cv::Mat d = (cv::Mat_<double>(3, 3) << 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9);
cout << endl;
// 定义其他的Mat类型变量
cv::Mat a1, a2;
//a1 = a * b; //参与运算的两个Mat类变量不满足类型,会报错!
//a1 = a * c; //参与运算的两个Mat类变量不满足类型,会报错!
a2 = c * d;
cout << a2 << endl;
return 0;
}
运行结果
2.3 两个Mat类变量之间的内积(点积)
有一点需要注意,貌似做点积运算的两个Mat类变量的数据类型必须相同,否则失败!
#include<iostream>
#include<opencv2\opencv.hpp>
using namespace std;
using namespace cv;
int main() {
// 定义Mat类变量并赋值
cv::Mat a = (cv::Mat_<int>(3, 3) << 1, 2, 3, 4, 5, 6, 7, 8, 9);
cv::Mat b = (cv::Mat_<int>(3, 3) << 11, 12, 13, 14, 15, 16, 17, 18, 19);
cv::Mat c = (cv::Mat_<double>(3, 3) << 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0);
cv::Mat d = (cv::Mat_<double>(3, 3) << 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9);
cout << endl;
// 定义其他的Mat类型变量
double a1, a2, a3, a4, a5, a6;
a1 = a.dot(b); //两个Mat类变量都会类型相同(都是int型),是可以点积的
a2 = b.dot(a); //两个Mat类变量都会类型相同(都是int型),是可以点积的
a3 = c.dot(d); //两个Mat类变量都会类型相同(都是double型),是可以点积的
a4 = d.dot(c); //两个Mat类变量都会类型相同(都是double型),是可以点积的
//a5 = a.dot(c); //两个Mat类变量都会类型不相同(一个是int型,另一个是double型),点积失败!
//a6 = c.dot(a); //两个Mat类变量都会类型不相同(一个是double型,另一个是int型),点积失败!
cout << "a1 = " << a1 << endl;
cout << "a2 = " << a2 << endl;
cout << "a3 = " << a3 << endl;
cout << "a4 = " << a4 << endl;
return 0;
}
运行结果
** 2.4 两个Mat类变量之间的对应位乘法**
有一点需要注意,与点积(内积)比较类似,参与对应位乘法运算的两个Mat类变量的数据类型必须相同,否则失败!
#include<iostream>
#include<opencv2\opencv.hpp>
using namespace std;
using namespace cv;
int main() {
// 定义Mat类变量并赋值
cv::Mat a = (cv::Mat_<int>(3, 3) << 1, 2, 3, 4, 5, 6, 7, 8, 9);
cv::Mat b = (cv::Mat_<int>(3, 3) << 11, 12, 13, 14, 15, 16, 17, 18, 19);
cv::Mat c = (cv::Mat_<double>(3, 3) << 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0);
cv::Mat d = (cv::Mat_<double>(3, 3) << 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9);
cout << endl;
// 定义其他的Mat类型变量
cv::Mat a1, a2, a3, a4, a5, a6;
a1 = a.mul(b); //两个Mat类变量都会类型相同(都是int型),是可以对应位乘法的
a2 = b.mul(a); //两个Mat类变量都会类型相同(都是int型),是可以对应位乘法的
a3 = c.mul(d); //两个Mat类变量都会类型相同(都是double型),是可以对应位乘法的
a4 = d.mul(c); //两个Mat类变量都会类型相同(都是double型),是可以对应位乘法的
//a5 = a.mul(c); //两个Mat类变量都会类型不相同(一个是int型,另一个是double型),对应位乘失败!
//a6 = c.mul(a); //两个Mat类变量都会类型不相同(一个是double型,另一个是int型),对应位乘法失败!
cout << "a1 = " << a1 << endl;
cout << "a2 = " << a2 << endl;
cout << "a3 = " << a3 << endl;
cout << "a4 = " << a4 << endl;
return 0;
}
运行结果
以上