文章目录
前言
最近心血来潮,想具体的去学习一下图像处理,所以报了知识星球的一个OpenCV研习社,将自己每天的学习,分享一下。写个 blog 加深一下知识。
一、函数解析
1、加法(add)
CV_EXPORTS_W void add(InputArray src1, InputArray src2, OutputArray dst,
InputArray mask = noArray(), int dtype = -1);
参数一:输入的数组或标量。
参数二:输入的数组或标量。
参数三:输出数组,其大小和通道数与输入数组相同;该深度由dtype或src1 / src2定义。
参数四:可选操作掩码; 8位单通道数组,指定要更改的输出数组的元素。
参数五:输出数组的可选深度。
功能:计算两个数组或一个数组、一个标量的每个元素和。
2、减法(subtract)
CV_EXPORTS_W void subtract(InputArray src1, InputArray src2, OutputArray dst,
InputArray mask = noArray(), int dtype = -1);
参数一:输入的数组或标量。
参数二:输入的数组或标量。
参数三:输出数组,其大小和通道数与输入数组相同;该深度由dtype或src1 / src2定义。
参数四:可选操作掩码; 这是一个8位单通道数组,用于指定元素要更改的输出数组。
参数五:输出数组的可选深度。
功能:计算两个数组或单个数组、标量之间的每个元素差。
3、乘法(multiply)
CV_EXPORTS_W void multiply(InputArray src1, InputArray src2,
OutputArray dst, double scale = 1, int dtype = -1);
参数一:第一个输入数组。
参数二:第二个输入数组,其大小和类型与src1相同。
参数三:输出与src1大小和类型相同的数组。
参数四:比例因子。
参数五:输出数组的可选深度。
功能:计算两个数组的每个元素缩放后的乘积。
4、除法(divide)
CV_EXPORTS_W void divide(InputArray src1, InputArray src2, OutputArray dst,
double scale = 1, int dtype = -1);
参数一:第一个输入数组。
参数二:第二个输入数组,其大小和类型与src1相同。
参数三:输出与src2大小和类型相同的数组。
参数四:比例因子。
参数五:输出数组的可选深度; 如果为-1,则dst将具有深度src2.depth(),
但是在逐个数组除法的情况下,只能在src1.depth() == src2.depth() 时传递-1。
功能:按数组对两个数组或标量的每个元素进行除法。
注意:图像的数据类型、通道数目、大小必须相同
二、代码示例
int main(int argc, char* argv[])
{
Mat src1 = imread("C:/Users/XMuser/Desktop/图片/LinuxLogo.jpg");
Mat src2 = imread("C:/Users/XMuser/Desktop/图片/WindowsLogo.jpg");
if (src1.empty() || src2.empty())
{
printf("could not load image....\n");
return -1;
}
imshow("input1", src1);
imshow("input2", src2);
//加法
Mat add_result = Mat::zeros(src1.size(), src1.type());
add(src1, src2, add_result);
imshow("add_result", add_result);
//减法
Mat sub_result = Mat::zeros(src1.size(), src1.type());
subtract(src1, src2, sub_result);
imshow("sub_result", sub_result);
//乘法
Mat mul_result = Mat::zeros(src1.size(), src1.type());
multiply(src1, src2, mul_result);
imshow("mul_result", mul_result);
//除法
Mat div_result = Mat::zeros(src1.size(), src1.type());
divide(src1, src2, div_result);
imshow("div_result", div_result);
waitKey(0);
return 0;
}
三、结果展示
四、进一步学习
这里我们将进一步学习,如果不使用 OpenCV 本身自带的算数函数,自己想实现相同效果,该怎么写。
1、以加法为例
int main(int argc, char* argv[])
{
Mat src1 = imread("C:/Users/XMuser/Desktop/图片/LinuxLogo.jpg");
Mat src2 = imread("C:/Users/XMuser/Desktop/图片/WindowsLogo.jpg");
if (src1.empty() || src2.empty())
{
printf("could not load image....\n");
return -1;
}
imshow("input1", src1);
imshow("input2", src2);
int height = src1.rows;
int width = src1.cols;
int b1 = 0, g1 = 0, r1 = 0;
int b2 = 0, g2 = 0, r2 = 0;
Mat result = Mat::zeros(src1.size(), src1.type());
for (int row = 0; row < height; row++)
{
for (int col = 0; col < width; col++)
{
b1 = src1.at<Vec3b>(row, col)[0];
g1 = src1.at<Vec3b>(row, col)[1];
r1 = src1.at<Vec3b>(row, col)[2];
b2 = src2.at<Vec3b>(row, col)[0];
g2 = src2.at<Vec3b>(row, col)[1];
r2 = src2.at<Vec3b>(row, col)[2];
//1、类似C++的强制类型转换,转换为uchar;2、防止数据溢出
result.at<Vec3b>(row, col)[0] = saturate_cast<uchar>(b1 + b2);
result.at<Vec3b>(row, col)[1] = saturate_cast<uchar>(g1 + g2);
result.at<Vec3b>(row, col)[2] = saturate_cast<uchar>(r1 + r2);
}
}
imshow("output", result);
waitKey(0);
return 0;
}
2、结果展示
五、官方教学
传送门:官方教程