(5)OpenCV 4 学习之像素算数操作

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zl_95520/article/details/88897496


一、函数解析

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、结果展示

在这里插入图片描述

五、官方教学

传送门:官方教程

猜你喜欢

转载自blog.csdn.net/zl_95520/article/details/88897496