椒盐噪声加入及运动模糊后维纳滤波器的实现

####椒盐噪声的加入
代码:

//椒和盐噪声密度均是0.1
void salt(Mat in)
{
	int i, j;
	int n = in.cols*in.rows*0.1;
	for (int k = 0; k < n / 2; k++)
	{
		i = rand() % in.cols;
		j = rand() % in.rows;
		in.at<uchar>(j, i) = 255;
	}
}
void pepper(Mat in)
{
	int i, j;
	int n = in.cols*in.rows*0.1;
	for (int k = 0; k < n / 2; k++)
	{
		i = rand() % in.cols;
		j = rand() % in.rows;
		in.at<uchar>(j, i) = 0;
	}
}
Mat addspnoise(Mat in)
{
	salt(in);
	pepper(in);
	return in;
}

由于是椒盐一起加入的,所以逆谐波滤波出后看起来并不好看
逆谐波滤波Q为-0.5时
椒盐噪声加入及运动模糊后维纳滤波器的实现
椒盐噪声加入及运动模糊后维纳滤波器的实现
椒盐噪声加入及运动模糊后维纳滤波器的实现
椒盐噪声加入及运动模糊后维纳滤波器的实现
逆谐波滤波Q为0.5时
椒盐噪声加入及运动模糊后维纳滤波器的实现
在这里插入图片描述
椒盐噪声加入及运动模糊后维纳滤波器的实现
椒盐噪声加入及运动模糊后维纳滤波器的实现
椒盐噪声加入及运动模糊后维纳滤波器的实现

运动模糊及维纳滤波器的实现:

//a,b,T为运动模糊参数,详见数字图像处理第三版
//运动模糊和维纳放在一个函数中了,以便处理
Mat Winner1(Mat in, float a, float b, float T)
{
	in.convertTo(in, 5);
	int nHeight = in.rows;
	int nWidth = in.cols;
	int P = 2 * nHeight;
	int Q = 2 * nWidth;
	int i, j;
	float U = 0.0;
	float pi_u = 0.0;
	Mat fp = Mat::zeros(P, Q, 5);
	for (int j = 0; j < nHeight; j++)
	{
		for (int i = 0; i < nWidth; i++)
		{
			fp.at<float>(j, i) = in.at<float>(j, i)*pow(-1, j + i);

		}
	}
	Mat planes[] = { Mat_<float>(fp), Mat::zeros(fp.size(), CV_32F) };
	Mat H[] = { Mat::zeros(fp.size(), CV_32F) , Mat::zeros(fp.size(), CV_32F) };
	Mat H_A = Mat::zeros(P, Q, 5);
	Mat out=Mat::zeros(nHeight, nWidth, 5);
	Mat complex;
	merge(planes, 2, complex);
	dft(complex, complex);
	split(complex, planes);
	float P0, P1;
	for (int j = 0; j < P; j++)
	{
		for (int i = 0; i < Q; i++)
		{

			pi_u = CV_PI * ((j - nHeight)*a + (i - nWidth) * b) + 1e-20;
			H[0].at<float>(j, i) = (T / pi_u)*(sin(pi_u))*(cos(pi_u));
			H[1].at<float>(j, i) = -(T / pi_u)*(sin(pi_u))*(sin(pi_u));
			P0 = H[0].at<float>(j, i);
			P1 = H[1].at<float>(j, i);
			H_A.at<float>(j, i) = P0 * P0 + P1 * P1;
			U = H_A.at<float>(j, i) / (H_A.at<float>(j, i) + K);
			planes[0].at<float>(j, i) = U * planes[0].at<float>(j, i);
			planes[1].at<float>(j, i) = U * planes[1].at<float>(j, i);
		}
	}
	Mat complex_cp;
	merge(planes, 2, complex_cp);
	Mat iDft[] = { Mat::zeros(planes[1].size(),CV_32F),Mat::zeros(planes[1].size(),CV_32F) };
	idft(complex_cp, complex_cp);
	split(complex_cp, iDft);

	for (int j = 0; j < nHeight; j++)
	{
		for (int i = 0; i < nWidth; i++)
		{
			out.at<float>(j, i) = iDft[0].at<float>(j, i)*pow(-1, j + i);
		}
	}

	normalize(out, out, 0, 255, CV_MINMAX);
	in.convertTo(in, 0);
	out.convertTo(out, 0);
	return out;
}

输入图像:
椒盐噪声加入及运动模糊后维纳滤波器的实现
运动模糊图像:
椒盐噪声加入及运动模糊后维纳滤波器的实现
Winne滤波递推以及MSE计算,最终K=0.009,MSE=901.999
椒盐噪声加入及运动模糊后维纳滤波器的实现

椒盐噪声加入及运动模糊后维纳滤波器的实现
约束最小二乘y迭代,最终y为

椒盐噪声加入及运动模糊后维纳滤波器的实现
椒盐噪声加入及运动模糊后维纳滤波器的实现