当前位置:网站首页>Explain the opencv function cv:: add() in detail, and attach sample code and running results of various cases

Explain the opencv function cv:: add() in detail, and attach sample code and running results of various cases

2022-06-13 04:59:00 Haohong image algorithm

function cv::add() Used to implement two Mat Matrix like addition , Or add a matrix to a scalar .

function cv::add() The operation formula of is as follows :
 Insert picture description here
As can be seen from the above description :

  • 1 function add() You can mask .
  • 2 The function saturates the result of the addition (saturate) operation , For example , If the data type is uhar, that 1+255=255, Not equal to 256. If the data type of the output matrix is CV_32S, Will not be saturated (saturate) operation , The original words of the official document are as follows :
    “Saturation is not applied when the output array has the depth CV_32S. You may even get result of an incorrect sign in the case of overflow.”
  • 3 When adding multi-channel matrices , Each channel is added separately .
  • 4 Two identical data types When the matrix of is added to the matrix ( That is, the first case above ) You can use the operator + Instead of , namely :
cv::add(A1, B1, C1);

amount to :

C1 = A1+B1;

Although it can be operated equivalently , However, haohongjun still suggests that you use standard functional operation , This can improve the robustness of the code .

function add() The prototype is as follows :

void cv::add( 	InputArray  src1,
				InputArray 	src2,
				OutputArray dst,
				InputArray 	mask = noArray(),
				int 	dtype = -1 
				)	

The first four parameters have nothing to say , Here is the last parameter dtype, It is used to set the data type of the output matrix , The details are as follows :
The input arrays and the output array can all have the same or different depths.
For example, you can add a 16-bit unsigned array to a 8-bit signed array and store the sum as a 32-bit floating-point array. Depth of the output array is determined by the dtype parameter.
In the second and third cases above, as well as in the first case, when src1.depth() == src2.depth(), dtype can be set to the default -1. In this case, the output array will have the same depth as the input array, be it src1, src2 or both.

The above paragraph is simple and clear , No translation . It should be noted that , When two added matrices have the same data type , Parameters dtype You can use the default value -1. When the data types of two added matrices are inconsistent , The data type of the output matrix must be set , Otherwise, an error will be reported when the program runs , For example, the following error report :

OpenCV Error: Bad argument (When the input arrays in add/subtract/multiply/divide functions have different types, the output array type must be explicitly specified) in cv::arithm_op, file C:\builds\master_PackSlave-win32-vc12-shared\opencv\modules\core\src\arithm.cpp, line 2011

 Insert picture description here
Next , The sample code above :

Sample code 1( The matrix of the same data type is added to the matrix )

//OpenCV edition :3.0.0
//VS edition :2013

#include <opencv2/opencv.hpp>

#include <iostream>
using namespace std;


int main()
{
    

	cv::Mat A1 = (cv::Mat_<uchar>(2, 3) << 1, 2, 3, 4, 5, 6);
	cout << "A1 The data in is :\n" << A1 << endl << endl;


	cv::Mat B1 = (cv::Mat_<uchar>(2, 3) << 2, 3, 4, 5, 6, 250);
	cout << "B1 The data in is :\n" << B1 << endl << endl;


	// The matrix of the same data type is added to the matrix 
	cv::Mat C1;
	cv::add(A1, B1, C1);
	cout << "C1 The data in is :\n" << C1 << endl << endl;

	return(0);
}

The operation results are as follows :
 Insert picture description here
Be careful :C1 The last element in the because of saturation operation from 256 Turned into 255.

Sample code 2( Matrices of different data types are added to each other )

//OpenCV edition :3.0.0
//VS edition :2013

#include <opencv2/opencv.hpp>

#include <iostream>
using namespace std;

int main()
{
    

	cv::Mat A1 = (cv::Mat_<uchar>(2, 3) << 1, 2, 3, 4, 5, 6);
	cout << "A1 The data in is :\n" << A1 << endl << endl;


	cv::Mat B1 = (cv::Mat_<int>(2, 3) << 2, 3, 4, 5, 6, 250);
	cout << "B1 The data in is :\n" << B1 << endl << endl;


	// Matrices of different data types are added to each other 
	cv::Mat C1;
	cv::InputArray mask1 = cv::noArray();
	cv::add(A1, B1, C1, mask1, CV_16U);
	cout << "C1 The data in is :\n" << C1 << endl << endl;

	return(0);
}

The operation results are as follows :
 Insert picture description here
Be careful , The following result statement :

cv::add(A1, B1, C1, mask1, CV_16U);

It's written in

cv::add(A1, B1, C1);

The program will run because A1 And B1 An error is reported because of different data types , As shown in the figure below :
 Insert picture description here

Sample code 3( Add a matrix to a scalar )

//OpenCV edition :3.0.0
//VS edition :2013

#include <opencv2/opencv.hpp>

#include <iostream>
using namespace std;


int main()
{
    

	cv::Mat A1 = (cv::Mat_<uchar>(2, 3) << 1, 2, 3, 4, 5, 6);
	cout << "A1 The data in is :\n" << A1 << endl << endl;


	uchar b1 = 1;
	int b2 = 2;

	cv::Mat C1, C2;
	cv::InputArray mask1 = cv::noArray();
	cv::add(A1, b1, C1);// Both addends have the same data type 
	cv::add(A1, b2, C2, mask1, CV_8U);// Two addends have different data types 
	cout << "C1 The data in is :\n" << C1 << endl << endl;
	cout << "C2 The data in is :\n" << C2 << endl << endl;


	return(0);
}

The operation results are as follows :
 Insert picture description here
Also pay attention : When the data types of two addends are inconsistent , If you do not set the data type of the output matrix , Although no error will be reported at this time , At this point, the function automatically handles , But for the robustness and controllability of the program , Haohongjun still suggests that you control the data types according to the above example code , Because you don't know what this automatic process will look like .
The sample code and running results of the function automatically perform type conversion according to the data conditions are as follows :

//OpenCV edition :3.0.0
//VS edition :2013

#include <opencv2/opencv.hpp>

#include <iostream>
using namespace std;


int main()
{
    

	cv::Mat A1 = (cv::Mat_<float>(2, 3) << 1, 2, 3, 4, 5, 6);
	cout << "A1 The data in is :\n" << A1 << endl << endl;


	uchar b1 = 1;
	double b2 = 2.3;

	cv::Mat C1, C2;
	cv::add(A1, b1, C1);
	cv::add(A1, b2, C2);
	cout << "C1 The data in is :\n" << C1 << endl << endl;
	cout << "C2 The data in is :\n" << C2 << endl << endl;


	return(0);
}

 Insert picture description here
The result of the above example code is what we expected , But we put A1 The data type of the element in is changed to uchar type , Maybe it's not the result we want :

//OpenCV edition :3.0.0
//VS edition :2013

#include <opencv2/opencv.hpp>

#include <iostream>
using namespace std;


int main()
{
    

	cv::Mat A1 = (cv::Mat_<uchar>(2, 3) << 1, 2, 3, 4, 5, 6);
	cout << "A1 The data in is :\n" << A1 << endl << endl;

	uchar b1 = 1;
	double b2 = 2.3;

	cv::Mat C1, C2;
	cv::add(A1, b1, C1);
	cv::add(A1, b2, C2);
	cout << "C1 The data in is :\n" << C1 << endl << endl;
	cout << "C2 The data in is :\n" << C2 << endl << endl;


	return(0);
}

 Insert picture description here
According to the truth ,C2 The data in should all have decimal places , But the result is not , This is the result of automatic function processing , Some automatic processing is not the result we want .

Sample code 4( Matrix addition with mask operation )

The sample code is as follows :

//OpenCV edition :3.0.0
//VS edition :2013

#include <opencv2/opencv.hpp>

#include <iostream>
using namespace std;


int main()
{
    

	cv::Mat A1 = (cv::Mat_<uchar>(2, 3) << 1, 2, 3, 4, 5, 6);
	cout << "A1 The data in is :\n" << A1 << endl << endl;

	cv::Mat B1 = (cv::Mat_<uchar>(2, 3) << 2, 3, 4, 5, 6, 250);
	cout << "B1 The data in is :\n" << B1 << endl << endl;

	cv::Mat mask1(2, 3, CV_8UC1, cv::Scalar(1));
	mask1.at<uchar>(0, 1) = 0;

	cv::Mat C1;
	cv::add(A1, B1, C1, mask1);
	cout << "C1 The data in is :\n" << C1 << endl << endl;

	return(0);
}

The operation results are as follows :
 Insert picture description here
The above first 0 That's ok , The first 1 The elements of the column are not masked by the addition operation , So the result is 0.

原网站

版权声明
本文为[Haohong image algorithm]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/164/202206130454021784.html