4_OpenCV矩阵的算术运算

本文包括加法、减法、乘法、除法、指数运算、对数ln、幂运算,开方运算,求和,求对角线的和等。

目录

1. 矩阵加法

1.1 cv::add()

1.2. cv::addWeighted

1.3 cv::scaleAdd()

2. 矩阵除法

3. 指数运算

4. 自然对数运算log()

5. 矩阵乘法

6. 矩阵求幂 cv::pow()

7. 计算平方根 cv::sqrt()

8. 减法 cv::subtract()

9. 求和 cv::sum()

10. 求对角线的总和 cv::trace()


1. 矩阵加法

计算矩阵加法时要注意数组越界的问题。

1.1 cv::add()

两个矩阵简单的相加运算,将src1中的所有元素加到src2中的相应元素中,并将结果放入dst中。可以使用加法或累加运算符实现。dst = src1 + src2; 或src2 += src1;

函数原型:

void cv::add(
	cv::InputArray src1,
	cv::InputArray src2,
	cv::OutputArray dst,  // result array
	cv::InputArray mask = cv::noArray(),  // optional, do only where nonzero
	int dtype = -1  // Output type for result array
);

dst_i = saturate(| src1_i + src2_i |)

1.2. cv::addWeighted

cv::addWeighted()函数与cv::add()类似,但cv::addWeighted()的计算公式是:

dst_i = saturate(src_i * α + src2_i * β + γ)

cv::addWeighted()函数原型:

void cv::addWeighted(
	cv::InputArray src1,   // First Input array
	double alpha,  // Weight for first array
	cv::InputArray src2,  // second input array
	double beta,  // weight for second input array
	double gamma,  // offset added to weight sum
	cv::OutputArray dst,  // result array
	int dtype = -1
);

如果两个源图像的类型相同,那么可以是任意类型,可以有任意通道。

该函数的应用之一是可以实现alpha混合(本质上是实现透明效果)。alpha混合时,α(取值在0-1之间)是src1的混合强度,将β=1-α,γ设置为0,可以转换为标准的alpha混合方程:

dst_i = asturate(src1_i * α + src2_i * (1-α))

示例代码1-1:

	std::string str_src1 = "alpha_src1.jpg";
	std::string str_src2 = "alpha_src2.jpg";

	cv::Mat img1 = cv::imread(str_src1.c_str());
	cv::Mat img2 = cv::imread(str_src2.c_str());
	if (img1.empty() || img2.empty()) {
		std::cout << "ERROR: Open image FAIL!\n";
		return;
	}
	int nX = 66;  // 如下值按照需要更改
	int nY = 16;
	int nROIW = 246 - nX;
	int nROIH = 161 - nY;
	double alpha = 0.4;
	double beta = 1 - alpha;
	double gamma = 0.0;
	cv::Mat roi1(img1, cv::Rect(0, 0, nROIW, nROIH));
	cv::Mat roi2(img2, cv::Rect(nX, nY, nROIW, nROIH));

	cv::addWeighted(roi1, alpha, roi2, beta, gamma, roi1);
	cv::namedWindow(str_src1, cv::WINDOW_NORMAL);
	cv::imshow(str_src1, img1);
	cv::waitKey(0);
	cv::destroyAllWindows();

结果显示

1.3 cv::scaleAdd()

cv::scaleAdd()函数用于计算两个矩阵src1和src2的和,在求和之前,将比例因子scale应用于第一个矩阵,结果放在矩阵dst中。函数原型:

void cv::scaleAdd(
	cv::InputArray src1,  // first input array
	double scale,  // scale factor applied to first array
	cv::InputArray src2,  // second input array
	cv::OutputArray dst,  // result array
);

计算公式:

该函数也可以直接用矩阵代数运算实现:dst = scale*src1 + src2;

 使用上面的示例代码1-1把其中图像融合的代码改成cv::scaleAdd()函数,如下:

	cv::scaleAdd(roi1, alpha, roi2, roi1);
//	cv::addWeighted(roi1, alpha, roi2, beta, gamma, roi1);

显示的结果(右边的是cv::addWeighted()函数显示的结果),可以明显看到cv::addWeighted()可以实现透明的效果。

1.4 矩阵累加

可以使用cv::accumulate()函数把8位整型的图像累加到一幅浮点型的图像中。

使用示例:

	std::string strFilename = "flower.jpg";
	cv::Mat srcImg = cv::imread(strFilename);
	if (srcImg.empty()){
		std::cout << "Fail: open file " << strFilename << " FAILED!\n" << std::endl;
		return;
	}

	std::vector<cv::Mat> planes;
	cv::split(srcImg, planes);
	cv::Mat b = planes[0], g = planes[1], r = planes[2];
	cv::Mat s = cv::Mat::zeros(b.size(), CV_32F);

	cv::accumulate(b, s);
	cv::accumulate(g, s);
	cv::accumulate(r, s);

2. 矩阵除法

cv::divide()函数实现除法运算,将src1中的所有元素除以src2中的相应元素,然后将结果放在dst中。函数原型:

cv::divide(
	cv::InputArray src1,  // First input array 分子
	cv::InputArray src2,  // second input array 分母
	cv::OutputArray dst,  // result array (scale*src1/src2)
	double scale = 1.0,  // multiplicative scale factor
	int dtype = -1  // dst data type -1=get from src2
);
cv::divide(
	double scale,  // numerator for all divisions
	cv::InputArray src2,  // input array 分母
	cv::OutputArray dst,  // result array (scale/src2)
	int dtype = -1  /// dst data type,-1=get from src2
);

3. 指数运算

cv::exp()函数计算矩阵中所有元素的指数,并将结果放在dst中。函数原型:

void cv::exp(
    cv::InputArray src,
    cv::OutputArray dst);

使用示例:

	float fdata[] = { 0,1,2,3,4,5,6,7,8,9,10,11 };
	cv::Mat m(4, 3, CV_32FC1,fdata);
	std::cout << "m = \n " << m << std::endl;
	cv::Mat dst;
	cv::exp(m, dst);
	std::cout << "dst = \n " << dst << std::endl;

显示结果:

4. 自然对数运算log()

cv::log()函数计算矩阵中的元素的自然对数,当矩阵的值小于或等于零时,目标对应像素上会被标记为一个大的负数。函数原型:

void cv::log(
	cv::InputArray src,
	cv::OutputArray dst
);

 使用示例:

	float fdata[] = { 0,1,2,3,4,5,6,7,8,9,10,11 };
	cv::Mat m(4, 3, CV_32FC1, fdata);
	std::cout << "m = \n " << m << std::endl;
	cv::Mat dst;
	cv::log(m, dst);
	std::cout << "dst = \n " << dst << std::endl;

显示结果:

5. 矩阵乘法

cv::multiply()函数实现一个简单的乘法,将src1中的元素乘以src2中的相应元素,把及热锅放在dst中。函数原型:

void multiply(
	cv::InputArray src1,  // first input array
	cv::InputArray src2,  // second input array
	cv::OutputArray dst,  // result array
	double scale = 1.0,  // overall scale factor
	int dtype = -1  // output type for result array
);

6. 矩阵求幂 cv::pow()

函数cv::pow()对矩阵逐元素取p次幂。在p为整数的情况下,直接进行幂运算。如果p为非整数,首先计算源矩阵的绝对值,然后取p次幂。

函数原型:

void cv::pow(
	cv::InputArray src,  // input array
	double p,  // power for exponentiation
	cv::OutputArray dst  // result array
);

计算公式:

7. 计算平方根 cv::sqrt()

cv::sqrt计算矩阵中逐元素的平方根,多个通道分别进行处理。函数声明:

void cv::sqrt(
	cv::InputArray src,
	cv::OutputArray dst
);

8. 减法 cv::subtract()

cv::subtract()函数是一个简单的减法函数,函数声明:

void cv::subtract(
	cv::InputArray src1,  // first input array
	cv::InputArray src2,  // second input array
	cv::OutputArray dst,  // result array
	cv::InputArray mask = cv::noArray(),  // optional, do only where nonzero
	int stype = -1  // output type for rtesult array
);

计算公式: ,该函数从src1中减去src2的相应元素,把结果放在dst中。该函数相当于dst = src1-src2;,也支持累加:src1 -= src2。

9. 求和 cv::sum()

cv::sum()函数计算矩阵arr各个通道的所有像素的总和,返回值是cv::Scalar类型,cv::sum支持多通道计算,每个通道的和被放在cv::Scalar返回值的相应分量中。函数声明:

cv::Scalar cv::sum(
	cv::InputArray arr
);

计算公式:

10. 求对角线的总和 cv::trace()

对角线的总和又称为矩阵的迹。迹是在cv::diag()的基础上实现的。因此输入的矩阵不需要是方阵。支持多通道矩阵,但是迹被计算为标量,因此标量的每个分量是相应通道上的和,最多有四个通道。函数声明:

cv::Scalar cv::sum(
	cv::InputArray arr
);

 计算公式:

​​​​​​​

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值