C++ OpenCV中Mat类变量的运算

两种运算:
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;
}

运行结果
在这里插入图片描述
以上

  • 12
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值