[Data denoising] SG-polynomial smoothing algorithm

1. Introduction

When processing industrial data, industrial data has fine grain, large noise, and large volume. With the increase of measurement points, the data dimension is high, the complexity is high, and the correlation is strong, but this correlation is relative, because there is Sometimes the data is too noisy to show this correlation.

I recently learned about five-point cubic smoothing, because in my work, I encountered the point set of lane lines detected by the five-point cubic smoothing algorithm to smooth the lane line model, remove noise points, and facilitate the fitting of lane line equations in post-processing.

Explanation of cited literature:

"Generally speaking, the data collected in the data acquisition system is often superimposed with noise.
The noise is divided into two types, one is periodic and the other is irregular. The former represents 50 Hz power frequency interference, and the latter The ones represent random signals."
"Due to the existence of random interference, the curves drawn by random signals are mostly broken lines , which indicates that the high-frequency components in the sampling data are relatively rich. In order to eliminate or weaken the influence of interference and improve the smoothness of the curve, The sampled data needs to be smoothed.
The commonly used smoothing methods are: average method , spline function method and five-point cubic smoothing method .

  • The averaging method is relatively simple, and the filtering effect is also poor;
  • The spline function method uses spline interpolation to approach the sampling point to achieve smoothing. The algorithm is diverse and the effect is good. However, using this method is relatively complicated to calculate and the control of the smoothing range is poor;
  • The five-point cubic smoothing method uses polynomial least squares approximation to perform smoothing and filtering on the sampling points. The algorithm is simple and the effect is good. "

2. Principle

insert image description here
The 5 points with equal wavelength intervals in a section of the spectrum are recorded as the X set, and the polynomial smoothing is to use the polynomial fitting values ​​of the data at the wavelength points Xm-2, Xm-1, Xm, Xm+1, and Xm+2. Replace Xm, and move sequentially until the spectrum is traversed.

insert image description here

5 point 3rd degree polynomial smoothing

Assuming that n equidistant points are known, and the observed (or experimental) data on it is
x0<x1<...<xn-1,
then two adjacent points can be taken before and after each data point, and a cubic polynomial can be used to

Y=a0 + a1x + a2x^2 + a3x^3

Make an approximation.

Determine the coefficients a0, a1, a2, a3 according to the principle of least squares, and finally the five-point cubic smoothing formula can be obtained as follows:
insert image description here
This formula requires the number of data points n≥5, when the number of data points is more than 5, it is considered symmetrical, except in Use the formulas (4-1), (4-2) and (4-4), (4-5) at both ends respectively, and the rest are smoothed with the formula (4-3), which is equivalent to each sub-interval Smoothing with different cubic least squares polynomials.

3. Code

1. 3-point linear smoothing

//3点线性平滑
int LinearSmooth3(double* input, long size) {
    
    
	double *output = new double[size];
	long i(0);
 
	if (size < 3)
	{
    
    
		for (i = 0; i <= size - 1; i++)
		{
    
    
			output[i] = input[i];
		}
	}
	else
	{
    
    
		output[0] = (5.0 * input[0] + 2.0 * input[1] - input[2]) / 6.0;
		for (i = 1; i <= size - 2; i++)
		{
    
    
			output[i] = (input[i - 1] + input[i] + input[i + 1]) / 3.0;
		}
		output[size - 1] = (5.0 * input[size - 1] + 2.0 * input[size - 2] - input[size - 3]) / 6.0;
	}
 
	for (i = 0; i < size; i++)
	{
    
    
		input[i] = output[i];
	}
 
	delete[] output;
 
	return 0;
}

2. 5-point linear smoothing

//5点线性平滑
int LinearSmooth5(double* input, long size) {
    
    
	double *output = new double[size];
	long i(0);
 
	if (size < 5)
	{
    
    
		for (i = 0; i <= size - 1; i++)
		{
    
    
			output[i] = input[i];
		}
	}
	else
	{
    
    
		output[0] = (3.0 * input[0] + 2.0 * input[1] + input[2] - input[4]) / 5.0;
		output[1] = (4.0 * input[0] + 3.0 * input[1] + 2 * input[2] + input[3]) / 10.0;
		for (i = 2; i <= size - 3; i++)
		{
    
    
			output[i] = (input[i - 2] + input[i - 1] + input[i] + input[i + 1] + input[i + 2]) / 5.0;
		}
		output[size - 2] = (4.0 * input[size - 1] + 3.0 * input[size - 2] + 2 * input[size - 3] + input[size - 4]) / 10.0;
		output[size - 1] = (3.0 * input[size - 1] + 2.0 * input[size - 2] + input[size - 3] - input[size - 5]) / 5.0;
	}
 
	for (i = 0; i < size; i++)
	{
    
    
		input[i] = output[i];
	}
 
	delete[] output;
 
	return 0;
}

3. 5-point quadratic linear smoothing

//5点二次线性平滑
int LinearSmooth52(double* input, long size) {
    
    
	double *output = new double[size];
	long i(0);
 
	if (size < 5)
	{
    
    
		for (i = 0; i <= size - 1; i++)
		{
    
    
			output[i] = input[i];
		}
	}
	else
	{
    
    
		output[0] = (31.0 * input[0] + 9.0 * input[1] - 3.0 * input[2] - 5.0 * input[3] + 3.0 * input[4]) / 35.0;
		output[1] = (9.0 * input[0] + 13.0 * input[1] + 12 * input[2] + 6.0 * input[3] - 5.0 *input[4]) / 35.0;
		for (i = 2; i <= size - 3; i++)
		{
    
    
			output[i] = (-3.0 * (input[i - 2] + input[i + 2]) +
				12.0 * (input[i - 1] + input[i + 1]) + 17 * input[i]) / 35.0;
		}
		output[size - 2] = (9.0 * input[size - 1] + 13.0 * input[size - 2] + 12.0 * input[size - 3] + 6.0 * input[size - 4] - 5.0 * input[size - 5]) / 35.0;
		output[size - 1] = (31.0 * input[size - 1] + 9.0 * input[size - 2] - 3.0 * input[size - 3] - 5.0 * input[size - 4] + 3.0 * input[size - 5]) / 35.0;
	}
 
	for (i = 0; i < size; i++)
	{
    
    
		input[i] = output[i];
	}
 
	delete[] output;
 
	return 0;
}

4. 5 point 3 linear smoothing

//5点三次线性平滑
int LinearSmooth53(double* input, long size) {
    
    
	double *output = new double[size];
	long i(0);
 
	if (size < 5)
	{
    
    
		for (i = 0; i <= size - 1; i++)
			output[i] = input[i];
	}
	else
	{
    
    
		output[0] = (69.0 * input[0] + 4.0 * input[1] - 6.0 * input[2] + 4.0 * input[3] - input[4]) / 70.0;
		output[1] = (2.0 * input[0] + 27.0 * input[1] + 12.0 * input[2] - 8.0 * input[3] + 2.0 * input[4]) / 35.0;
		for (i = 2; i <= size - 3; i++)
		{
    
    
			output[i] = (-3.0 * (input[i - 2] + input[i + 2]) + 12.0 * (input[i - 1] + input[i + 1]) + 17.0 * input[i]) / 35.0;
		}
		output[size - 2] = (2.0 * input[size - 5] - 8.0 * input[size - 4] + 12.0 * input[size - 3] + 27.0 * input[size - 2] + 2.0 * input[size - 1]) / 35.0;
		output[size - 1] = (-input[size - 5] + 4.0 * input[size - 4] - 6.0 * input[size - 3] + 4.0 * input[size - 2] + 69.0 * input[size - 1]) / 70.0;
	}
 
	for (i = 0; i < size; i++)
	{
    
    
		input[i] = output[i];
	}
 
	delete[] output;
 
	return 0;
}

5. 7-point linear smoothing

//7点线性平滑
int LinearSmooth7(double* input, long size) {
    
    
	double *output = new double[size];
	long i(0);
 
	if (size < 7)
	{
    
    
		for (i = 0; i <= size - 1; i++)
		{
    
    
			output[i] = input[i];
		}
	}
	else
	{
    
    
		output[0] = (13.0 * input[0] + 10.0 * input[1] + 7.0 * input[2] + 4.0 * input[3] +
			input[4] - 2.0 * input[5] - 5.0 * input[6]) / 28.0;
		output[1] = (5.0 * input[0] + 4.0 * input[1] + 3 * input[2] + 2 * input[3] +
			input[4] - input[6]) / 14.0;
		output[2] = (7.0 * input[0] + 6.0 * input[1] + 5.0 * input[2] + 4.0 * input[3] +
			3.0 * input[4] + 2.0 * input[5] + input[6]) / 28.0;
		for (i = 3; i <= size - 4; i++)
		{
    
    
			output[i] = (input[i - 3] + input[i - 2] + input[i - 1] + input[i] + input[i + 1] + input[i + 2] + input[i + 3]) / 7.0;
		}
		output[size - 3] = (7.0 * input[size - 1] + 6.0 * input[size - 2] + 5.0 * input[size - 3] +
			4.0 * input[size - 4] + 3.0 * input[size - 5] + 2.0 * input[size - 6] + input[size - 7]) / 28.0;
		output[size - 2] = (5.0 * input[size - 1] + 4.0 * input[size - 2] + 3.0 * input[size - 3] +
			2.0 * input[size - 4] + input[size - 5] - input[size - 7]) / 14.0;
		output[size - 1] = (13.0 * input[size - 1] + 10.0 * input[size - 2] + 7.0 * input[size - 3] +
			4 * input[size - 4] + input[size - 5] - 2 * input[size - 6] - 5 * input[size - 7]) / 28.0;
	}
 
	for (i = 0; i < size; i++)
	{
    
    
		input[i] = output[i];
	}
 
	delete[] output;
 
	return 0;
}

6. 7 point quadratic linear smoothing

//7点二次线性平滑
int LinearSmooth72(double* input, long size) {
    
    
	double *output = new double[size];
	long i(0);
 
	if (size < 7)
	{
    
    
		for (i = 0; i <= size - 1; i++)
		{
    
    
			output[i] = input[i];
		}
	}
	else
	{
    
    
		output[0] = (32.0 * input[0] + 15.0 * input[1] + 3.0 * input[2] - 4.0 * input[3] -
			6.0 * input[4] - 3.0 * input[5] + 5.0 * input[6]) / 42.0;
		output[1] = (5.0 * input[0] + 4.0 * input[1] + 3.0 * input[2] + 2.0 * input[3] +
			input[4] - input[6]) / 14.0;
		output[2] = (1.0 * input[0] + 3.0 * input[1] + 4.0 * input[2] + 4.0 * input[3] +
			3.0 * input[4] + 1.0 * input[5] - 2.0 * input[6]) / 14.0;
		for (i = 3; i <= size - 4; i++)
		{
    
    
			output[i] = (-2.0 * (input[i - 3] + input[i + 3]) +
				3.0 * (input[i - 2] + input[i + 2]) +
				6.0 * (input[i - 1] + input[i + 1]) + 7.0 * input[i]) / 21.0;
		}
		output[size - 3] = (1.0 * input[size - 1] + 3.0 * input[size - 2] + 4.0 * input[size - 3] +
			4.0 * input[size - 4] + 3.0 * input[size - 5] + 1.0 * input[size - 6] - 2.0 * input[size - 7]) / 14.0;
		output[size - 2] = (5.0 * input[size - 1] + 4.0 * input[size - 2] + 3.0 * input[size - 3] +
			2.0 * input[size - 4] + input[size - 5] - input[size - 7]) / 14.0;
		output[size - 1] = (32.0 * input[size - 1] + 15.0 * input[size - 2] + 3.0 * input[size - 3] -
			4.0 * input[size - 4] - 6.0 * input[size - 5] - 3.0 * input[size - 6] + 5.0 * input[size - 7]) / 42.0;
	}
 
	for (i = 0; i < size; i++)
	{
    
    
		input[i] = output[i];
	}
 
	delete[] output;
 
	return 0;
}

Guess you like

Origin blog.csdn.net/All_In_gzx_cc/article/details/128079606