递归实现高斯滤波(Recursive implementation of the Gaussian filter)

/*GaussFilterIIR参数说明:递归实现高斯滤波(Recursive implementation of the Gaussian filter)
特点:不需设定滤波窗口,复杂度跟窗口大小无关,滤波窗口较大时速度提升明显
GaussFilterIIR(
Uchar* input,   输入图像
float* output,  输出图像(用于清晰度计算必须是float型,因为滤波后梯度本身非常小,小于1的梯度占多数)
float sigma,    标准差
int rowSize,    图像行数
int colSize     图像列数
)
*/
static int GaussFilterIIR(Uchar* input, float* output, float sigma, int rowSize, int colSize)
{
	int wide = OFF_BORDER_WIDTH;//距离边框宽度
	wide = maxf(wide, 3);
	float* dx = (float*)malloc(rowSize * colSize * sizeof(float));//横向卷积
	float* w1 = (float*)malloc(rowSize * colSize * sizeof(float));
	float* w2 = (float*)malloc(rowSize * colSize * sizeof(float));
	float q = 0;
	if (sigma >= 2.5)
	{
		q = 0.98711f*sigma - 0.96330f;
	}
	else if (sigma >= 0.5 && sigma < 2.5)
	{
		q = 3.97156f - 4.14554f*sqrt(1 - 0.26891f*sigma);
	}
	else
	{
		q = 0.114770501626396f;
	}
	float b0 = 1.57825f + 2.44413f*q + 1.4281f*q*q + 0.422205f*q*q*q;
	float b1 = 2.44413f*q + 2.85619f*q*q + 1.26661f*q*q*q;
	float b2 = -1.4281f*q*q - 1.26661f*q*q*q;
	float b3 = 0.422205f*q*q*q;
	float B = 1 - (b1 + b2 + b3) / b0;
	//横向卷积
	for (int i = wide; i < rowSize - wide; i++)
	{
		for (int j = wide; j < colSize - wide; j++)
		{
			if ((j - 3) < wide)
			{
				w1[i * colSize + wide - 1] = input[i * colSize + wide];
				w1[i * colSize + wide - 2] = input[i * colSize + wide];
				w1[i * colSize + wide - 3] = input[i * colSize + wide];
			}
			w1[i * colSize + j] = B*input[i * colSize + j] + (b1* w1[i * colSize + j - 1] + b2* w1[i * colSize + j - 2] + b3* w1[i * colSize + j - 3]) / b0;
		}
	}
	for (int i = wide; i < rowSize - wide; i++)
	{
		for (int j = colSize - wide - 1; j >= wide; j--)
		{
			if ((j + 3) >(colSize - wide - 1))
			{
				dx[i * colSize + colSize - wide] = w1[i * colSize + colSize - wide - 1];
				dx[i * colSize + colSize - wide + 1] = w1[i * colSize + colSize - wide - 1];
				dx[i * colSize + colSize - wide + 2] = w1[i * colSize + colSize - wide - 1];
			}
			dx[i * colSize + j] = B*w1[i * colSize + j] + (b1* dx[i * colSize + j + 1] + b2* dx[i * colSize + j + 2] + b3* dx[i * colSize + j + 3]) / b0;
		}
	}
	//纵向卷积
	for (int i = wide; i < rowSize - wide; i++)
	{
		for (int j = wide; j < colSize - wide; j++)
		{
			if ((i - 3) < wide)
			{
				w2[(wide - 1) * colSize + j] = dx[wide * colSize + j];
				w2[(wide - 2) * colSize + j] = dx[wide * colSize + j];
				w2[(wide - 3) * colSize + j] = dx[wide * colSize + j];
			}
			w2[i * colSize + j] = B*dx[i * colSize + j] + (b1* w2[(i - 1) * colSize + j] + b2* w2[(i - 2) * colSize + j] + b3* w2[(i - 3) * colSize + j]) / b0;
		}
	}
	for (int i = rowSize - wide - 1; i >= wide; i--)
	{
		for (int j = wide; j < colSize - wide; j++)
		{
			if ((i + 3) >(rowSize - wide - 1))
			{
				w2[(rowSize - wide) * colSize + j] = dx[(rowSize - wide - 1) * colSize + j];
				w2[(rowSize - wide + 1) * colSize + j] = dx[(rowSize - wide - 1) * colSize + j];
				w2[(rowSize - wide + 2) * colSize + j] = dx[(rowSize - wide - 1) * colSize + j];
			}
			output[i * colSize + j] = B*w2[i * colSize + j] + (b1* output[(i + 1) * colSize + j] + b2* output[(i + 2) * colSize + j] + b3* output[(i + 3) * colSize + j]) / b0;
		}
	}
	free(dx);
	free(w1);
	free(w2);
	dx = NULL;
	w1 = NULL;
	w2 = NULL;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/u013297911/article/details/88056735