本文包括加法、减法、乘法、除法、指数运算、对数ln、幂运算,开方运算,求和,求对角线的和等。
目录
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
);
计算公式: