图像处理时间噪声空间噪声

2019-04-16 11:14:31 minjiuhong 阅读数 1358

噪声图像

图像中噪声的由来多种多样,本文主要介绍高斯白噪声(噪声服从正太分布,功率谱均匀)和开关不正常使用时产生的椒盐噪声的处理。

高斯噪声

高斯噪声在日常生活中存在比较普遍,下面我将为图像添加高斯噪声。

// 生成高斯噪声
double generateGaussianNoise(double mu, double sigma)
{
	static double V1, V2, S;
	static int phase = 0;
	double X;
	double U1, U2;
	if (phase == 0) {
		do {
			U1 = (double)rand() / RAND_MAX;
			U2 = (double)rand() / RAND_MAX;

			V1 = 2 * U1 - 1;
			V2 = 2 * U2 - 1;
			S = V1 * V1 + V2 * V2;
		} while (S >= 1 || S == 0);

		X = V1 * sqrt(-2 * log(S) / S);
	}
	else {
		X = V2 * sqrt(-2 * log(S) / S);
	}
	phase = 1 - phase;
	return mu + sigma * X;
}


//为图像添加高斯噪声  
cv::Mat addGaussianNoise(cv::Mat &srcImag, double mu = 0, double sigma = 5)
{
	cv::Mat dstImage = srcImag.clone();
	int channels = dstImage.channels();
	int rowsNumber = dstImage.rows;
	int colsNumber = dstImage.cols*channels;
	//判断图像的连续性  
	if (dstImage.isContinuous())
	{
		colsNumber *= rowsNumber;
		rowsNumber = 1;
	}
	for (int i = 0; i < rowsNumber; i++)
	{
		for (int j = 0; j < colsNumber; j++)
		{
			//添加高斯噪声  
			int val = dstImage.ptr<uchar>(i)[j] +
				generateGaussianNoise(mu, sigma);
			if (val < 0)
				val = 0;
			if (val > 255)
				val = 255;
			dstImage.ptr<uchar>(i)[j] = (uchar)val;
		}
	}
	return dstImage;
}

椒盐噪声

椒盐噪声可认为是胡椒噪声和盐粒噪声的混合版本。

// 添加椒盐噪声op=0, 添加盐粒噪声op=1, 添加胡椒噪声op=2
cv::Mat addSaltNoise(const cv::Mat src, int n, int op)
{
	cv::Mat dst = src.clone();
	if (op == 0 || op == 1)
	{
		for (int k = 0; k < n; k++)
		{
			int i = rand() % dst.rows;
			int j = rand() % dst.cols;
			// 通道判定
			if (dst.channels() == 1)
			{
				dst.at<uchar>(i, j) = 255;				// 添加盐噪声
			}
			else
			{
				dst.at<cv::Vec3b>(i, j)[0] = 255;
				dst.at<cv::Vec3b>(i, j)[1] = 255;
				dst.at<cv::Vec3b>(i, j)[2] = 255;
			}
		}
	}
	if (op == 0 || op == 2)
	{
		for (int k = 0; k < n; k++)
		{
			int i = rand() % dst.rows;
			int j = rand() % dst.cols;
			// 通道判定
			if (dst.channels() == 1)
			{
				dst.at<uchar>(i, j) = 0;				// 添加椒噪声
			}
			else
			{
				dst.at<cv::Vec3b>(i, j)[0] = 0;
				dst.at<cv::Vec3b>(i, j)[1] = 0;
				dst.at<cv::Vec3b>(i, j)[2] = 0;
			}
		}
	}
	return dst;
}

算术均值滤波、几何均值滤波、谐波均值滤波、逆谐波滤波

算数均值滤波是求区域内的均值,而几何均值滤波是求区域内的乘积后的开方。前者处理过后图像对比后者更模糊,但两者的平滑作用基本相同。谐波均值滤波对盐粒噪声和高斯噪声的去噪比较有效,而逆谐波滤波对胡椒噪声的去噪效果较好,但这两者都不能处理椒盐噪声,因为它们分别只能处理一种极值点情况。

// 任务一
void test1(int op)
{
	// 1.1.打开原始图像
	cv::Mat src = open_image(op, "原始图像");
	// 1.2.添加1000个椒盐噪声
	cv::Mat dst1 = addSaltNoise(src, 10000, 0);
	someFilter(src, dst1, "椒盐噪声");


	// 2 添加胡椒噪声
	cv::Mat dst2 = addSaltNoise(src, 10000, 2);
	someFilter(src, dst2, "胡椒噪声");

	// 3 添加盐粒噪声
	cv::Mat dst3 = addSaltNoise(src, 10000, 1);
	someFilter(src, dst3, "盐粒噪声");

	// 4. 添加高斯噪声
	cv::Mat dst4 = addGaussianNoise(src);
	someFilter(src, dst4, "高斯噪声");
}
// 滤波(算术,几何, 谐波, 逆谐波)
void someFilter(cv::Mat src, cv::Mat dst, string name)
{
	// 1 算术滤波
	cv::Mat filter1 = inverseHarm(dst, 0);
	// 2.几何滤波
	cv::Mat filter2 = gmMeanFilter(dst, 7);
	// 3.谐波滤波
	cv::Mat filter3 = inverseHarm(dst, -1);
	// 4.逆谐波滤波
	cv::Mat filter4 = inverseHarm(dst, 1.5);
	// 5.显示图像
	show_img(src, "原始图像");
	show_img(dst, name);
	show_img(filter1, "算术滤波");
	show_img(filter2, "几何滤波");
	show_img(filter3, "谐波均值滤波");
	show_img(filter4, "逆谐波滤波Q=1.5");
	// 6.等待按键
	cv::waitKey();
	cv::destroyAllWindows();
}

// 逆谐波滤波Q>0 谐波均值滤波Q=-1 算数均值滤波Q=0
cv::Mat inverseHarm(cv::Mat src, float Q, int size = 5)
{
	cv::Mat dst = src.clone();
	for (int i = size / 2; i < (src.rows - size / 2); i++)
		for (int j = size / 2; j < (src.cols - size / 2); j++)
		{
			if (dst.channels() == 1)
			{
				double sum1=0, sum2=0;
				for (int m = -size / 2; m <= size / 2; m++)
					for (int n = -size / 2; n <= size / 2; n++)
					{
						sum1 += pow(src.at<uchar>(i + m, j + n) + 0.001, Q + 1);
						sum2 += pow(src.at<uchar>(i + m, j + n) + 0.001, Q);
						//printf("%f    ", sum2);
					}
				// printf("%f    ", sum2);
				// 大于255的转换为255, 小于0的转化为0
				dst.at<uchar>(i, j) = cv::saturate_cast<int>(sum1 / sum2);
			}
			else
			{
				double sum1[3] = { 0 }, sum2[3] = { 0 };
				for (int m = -size / 2; m <= size / 2; m++)
					for (int n = -size / 2; n <= size / 2; n++)
						for (int k = 0; k <= 2; k++)
						{
							if (dst.at<cv::Vec3b>(i + m, j + n)[k] != 0)
							{
								sum1[k] += pow(src.at<cv::Vec3b>(i + m, j + n)[k], Q + 1);
								sum2[k] += pow(src.at<cv::Vec3b>(i + m, j + n)[k], Q);
							}
							//printf("%f    ", sum2);
						}
				// printf("%f    ", sum2);
				// 大于255的转换为255, 小于0的转化为0
				dst.at<cv::Vec3b>(i, j)[0] = cv::saturate_cast<int>(sum1[0] / sum2[0]);
				dst.at<cv::Vec3b>(i, j)[1] = cv::saturate_cast<int>(sum1[1] / sum2[1]);
				dst.at<cv::Vec3b>(i, j)[2] = cv::saturate_cast<int>(sum1[2] / sum2[2]);

			}
		}
	return dst;
}


// 几何均值滤波
cv::Mat gmMeanFilter(cv::Mat src, int size = 5)
{
	cv::Mat dst = src.clone();
	for (int i = size / 2; i < (src.rows - size / 2); i++)
		for (int j = size / 2; j < (src.cols - size / 2); j++)
		{
			if (dst.channels() == 1)
			{
				double sum = 1;
				for (int m = -size / 2; m <= size / 2; m++)
					for (int n = -size / 2; n <= size / 2; n++)
					{
						if (dst.at<uchar>(i + m, j + n) != 0)
						{
							sum *= pow(dst.at<uchar>(i + m, j + n), 1.0/(size * size));
							
						}
					}
				// printf("  %f", sum);
				dst.at<uchar>(i, j) = cv::saturate_cast<int>(sum);
			}
			else
			{
				double sum[3] = {1, 1, 1};
				for (int m = -size/2; m <= size/2; m++)
					for (int n = -size/2; n <= size/2; n++)
						for (int k = 0; k <= 2; k++)
						{
							if (dst.at<cv::Vec3b>(i + m, j + n)[k] != 0)
							{
								sum[k] *= dst.at<cv::Vec3b>(i + m, j + n)[k];
							}
						}

				dst.at<cv::Vec3b>(i, j)[0] = cv::saturate_cast<int>(pow(sum[0], 1.0/(size*size)));
				dst.at<cv::Vec3b>(i, j)[1] = cv::saturate_cast<int>(pow(sum[1], 1.0/(size*size)));
				dst.at<cv::Vec3b>(i, j)[2] = cv::saturate_cast<int>(pow(sum[2], 1.0/(size*size)));

			}
		}
	return dst;
}

效果展示

胡椒噪声
盐粒噪声
椒盐噪声
高斯噪声

自适应均值滤波

自适应均值滤波能够有效去噪同时保留原始图像的信息,但相对的会增加图像的计算量。它的主要思想是,通过对局部方差和噪声方差的比值来确定原像素点值和均值的占比,比值大表示这个局域是边缘部分,原像素点占比大,保留原图像边缘信息;比值小,表示是平坦局域,均值占比大,可有效滤除噪声。

// 任务三
void test3(int op)
{
	// 1.打开原始图像
	cv::Mat src = open_image(op, "原始图像");
	// 2. 添加高斯噪声
	cv::Mat dst = addGaussianNoise(src, 0, 10);
	// 3 算术滤波7x7
	cv::Mat filter1 = inverseHarm(dst, 0, 7);
	// 4.几何滤波7x7
	cv::Mat filter2 = gmMeanFilter(dst, 7);
	// 5. 自适应均值滤波
	cv::Mat filter3 = suitableMeanFilter(dst, 7, 100);
	// 6.显示图像
	show_img(src, "原始图像");
	show_img(dst, "高斯噪声图像");
	show_img(filter1, "算术均值滤波");
	show_img(filter2, "几何均值滤波");
	show_img(filter3, "自适应均值滤波");
	// 7.等待按键
	cv::waitKey();
	cv::destroyAllWindows();

}
// 自适应局部降低噪声滤波器
cv::Mat suitableMeanFilter(cv::Mat src, int size = 7, double noiseSigma = 1000)
{
	double mu, sigma, rate;
	cv::Mat dst = src.clone();
	for (int i = size / 2; i < (src.rows - size / 2); i++)
		for (int j = size / 2; j < (src.cols - size / 2); j++)
		{
			if (dst.channels() == 1)
			{
				double* num = new double[size*size];
				int p = 0;
				for (int m = -size / 2; m <= size / 2; m++)
					for (int n = -size / 2; n <= size / 2; n++)
					{
						if (dst.at<uchar>(i + m, j + n) != 0)
						{
							num[p] = dst.at<uchar>(i + m, j + n);
							p++;
						}
					}

				countMV(num, size);
				// std::cout << num[12] << endl;

				// printf("  %f", sum);
				mu = num[0];
				sigma = num[1];
				rate = noiseSigma / sigma;
				if (rate > 1)
					rate = 1;
				// std::cout << rate << "--";
				dst.at<uchar>(i, j) = cv::saturate_cast<int>(dst.at<uchar>(i, j) - rate * (dst.at<uchar>(i, j) - mu));

				delete[]num;
			}
			else
			{
				double** num = new double*[3];
				for (int s = 0; s < 3; s++)
					num[s] = new double[size*size];
				int p[3] = { 0, 0, 0 };
				for (int k = 0; k < 3; k++)
				{
					for (int m = -size / 2; m <= size / 2; m++)
						for (int n = -2; n <= 2; n++)
							if (dst.at<cv::Vec3b>(i + m, j + n)[k] != 0)
							{
								num[k][p[k]] = dst.at<cv::Vec3b>(i + m, j + n)[k];
								p[k]++;
							}

					countMV(num[k]);
					mu = num[k][0];
					sigma = num[k][1];
					rate = noiseSigma / sigma;
					if (rate > 1)
						rate = 1;
					dst.at<cv::Vec3b>(i, j)[k] = cv::saturate_cast<int>(dst.at<cv::Vec3b >(i, j)[k] - rate * (dst.at<cv::Vec3b >(i, j)[k] - mu));

					
				}
				delete[]num;
			}
		}
	return dst;
}

效果展示

高斯噪声

中值滤波

中值滤波是一种非线性滤波器,它对极值噪声的去噪比较好,但同时会带来模糊图像的问题。

// 任务二
void test2(int op)
{
	// 1.1.打开原始图像
	cv::Mat src = open_image(op, "原始图像");
	// 1.2.添加1000个椒盐噪声
	cv::Mat dst1 = addSaltNoise(src, 10000, 0);
	// 2 添加胡椒噪声
	cv::Mat dst2 = addSaltNoise(src, 10000, 2);
	// 3 添加盐粒噪声
	cv::Mat dst3 = addSaltNoise(src, 10000, 1);

	// 4.中值滤波
	cv::Mat filter1 = middleFilter(dst1, 9);
	cv::Mat filter2 = middleFilter(dst2, 9);
	cv::Mat filter3 = middleFilter(dst3, 9);

	// 5.显示图像
	show_img(src, "原始图像");
	show_img(dst1, "椒盐噪声");
	show_img(dst2, "胡椒噪声");
	show_img(dst3, "盐粒噪声");
	show_img(filter1, "中值滤波-椒盐");
	show_img(filter2, "中值滤波-胡椒");
	show_img(filter3, "中值滤波-盐粒");

	// 6.等待按键
	cv::waitKey();
	cv::destroyAllWindows();
}

// 找到中值
double findNumber(double* num, int start, int end, int n)
{
	int p = start;
	double temp, stand = num[start];
	for (int i = start + 1; i < end; i++)
	{
		if (num[i] < stand)
		{
			num[p] = num[i];
			p++;
			num[i] = num[p];
		}
	}
	if (p == n)
		return stand;
	else if (p > n)
		return findNumber(num, start, p, n);
	else
		return findNumber(num, p + 1, end, n);
}


// 中值滤波
cv::Mat middleFilter(cv::Mat src, int size = 5)
{
	cv::Mat dst = src.clone();
	for (int i = size/2; i < (src.rows - size/2); i++)
		for (int j = size/2; j < (src.cols - size/2); j++)
		{
			if (dst.channels() == 1)
			{
				double* num = new double[size*size];
				int p = 0;
				for (int m = -size/2; m <= size/2; m++)
					for (int n = -size/2; n <= size/2; n++)
					{
						if (dst.at<uchar>(i + m, j + n) != 0)
						{
							num[p] = dst.at<uchar>(i + m, j + n);
							p++;
						}
					}

				// insert_sort(num);
				// std::cout << num[12] << endl;
				
				// printf("  %f", sum);
				dst.at<uchar>(i, j) = cv::saturate_cast<int>(findNumber(num, 0, size*size, size*size/2));
				
				delete[]num;
			}
			else
			{
				double** num = new double*[3];
				for (int s = 0; s < 3; s++)
					num[s] = new double[size*size];
				int p[3] = { 0, 0, 0 };
				for (int m = -size/2; m <= size/2; m++)
					for (int n = -2; n <= 2; n++)
						for (int k = 0; k <= 2; k++)
						{
							if (dst.at<cv::Vec3b>(i + m, j + n)[k] != 0)
							{
								num[k][p[k]] = dst.at<cv::Vec3b>(i + m, j + n)[k];
								p[k]++;
							}
						}

				dst.at<cv::Vec3b>(i, j)[0] = cv::saturate_cast<int>(findNumber(num[0], 0, size*size, size*size/2));
				dst.at<cv::Vec3b>(i, j)[1] = cv::saturate_cast<int>(findNumber(num[1], 0, size*size, size*size/2));
				dst.at<cv::Vec3b>(i, j)[2] = cv::saturate_cast<int>(findNumber(num[2], 0, size*size, size*size/2));

				delete[]num;
			}
		}
	return dst;
}

效果展示

自适应中值滤波

自适应中值滤波是一种对胡椒噪声处理良好的滤波方法,它既能有效滤除椒盐噪声同时极大的保留原始图像信息。这种方法的主要思想是确定一个最大模板,通过几个判别来确定图像的像素值,如果中值是极值的话,就增加模板大小,这样就可以用最小模板来确定中值,减少图像的模糊,否则,继续判定原像素点是否为极值,如果是,输出中值,否则输出原像素值,这个思想可以尽量的保留原图像信息。

// 任务四
void test4(int op)
{
	// 1.1.打开原始图像
	cv::Mat src = open_image(op, "原始图像");
	// 1.2.添加1000个椒盐噪声
	cv::Mat dst = addSaltNoise(src, 10000, 0);

	// 2.自适应中值滤波
	cv::Mat filter1 = suitableMiddleFilter(dst);
	// 3.中值滤波
	cv::Mat filter2 = middleFilter(dst, 7);

	// 4.显示图像
	show_img(src, "原始图像");
	show_img(dst, "椒盐噪声");
	show_img(filter1, "自适应中值滤波");
	show_img(filter2, "中值滤波");

	// 5.等待按键
	cv::waitKey();
	cv::destroyAllWindows();
}
// 自适应中值滤波
cv::Mat suitableMiddleFilter(cv::Mat src, int size = 7)
{
	int zmid, zxy, zmin, zmax, output, p, _size, a[3] = { 0 };
	double* num = new double[size*size];
	double** nums = new double*[3];
	for (int s = 0; s < 3; s++)
		nums[s] = new double[size*size];
	cv::Mat dst = src.clone();
	for (int i = size / 2; i < (src.rows - size / 2); i++)
		for (int j = size / 2; j < (src.cols - size / 2); j++)
		{
			if (dst.channels() == 1)
			{
				_size = 3;
				while (_size <= size)
				{
					p = 0;
					for (int m = -_size / 2; m <= _size / 2; m++)
						for (int n = -_size / 2; n <= _size / 2; n++)
						{
							if (dst.at<uchar>(i + m, j + n) != 0)
							{
								num[p] = dst.at<uchar>(i + m, j + n);
								p++;
							}
						}

					zmid = findNumber(num, 0, _size*_size, _size*_size/2), zxy = dst.at<uchar>(i, j), zmin = findNumber(num, 0, _size*_size, 0), zmax = findNumber(num, 0, _size*_size, _size*_size-1);
					if (zmid - zmin > 0 && zmid - zmax < 0)
					{
						if (zxy - zmin > 0 && zxy - zmax)
						{
							output = zxy;
							_size += 2;
						}
						else
						{
							output = zmid;
							_size += 2;
						}
					}
					else if (_size == size)
					{
						output = zmid;
						_size += 2;
					}
					else
					{
						_size += 2;
					}

					// std::cout << num[12] << endl;

					// printf("  %f", sum);

				}
				dst.at<uchar>(i, j) = cv::saturate_cast<int>(output);
			}
			else
			{

				for (int k = 0; k < 3; k++)
				{
					_size = 3;
					while (_size <= size)
					{
						a[k] = 0;
						for (int m = -size / 2; m <= size / 2; m++)
							for (int n = -2; n <= 2; n++)
							{
								if (dst.at<cv::Vec3b>(i + m, j + n)[k] != 0)
								{
									nums[k][a[k]] = dst.at<cv::Vec3b>(i + m, j + n)[k];
									a[k]++;
								}
							}

						insert_sort(nums[k]);
						zmid = nums[k][_size*_size / 2], zxy = dst.at<cv::Vec3b>(i, j)[k], zmin = nums[k][0], zmax = nums[k][_size*_size - 1];
						if (zmid - zmin > 0 && zmid - zmax < 0)
						{
							if (zxy - zmin > 0 && zxy - zmax)
							{
								dst.at<cv::Vec3b>(i, j)[k] = zxy;
								_size += 2;
							}
							else
							{
								dst.at<cv::Vec3b>(i, j)[k] = zmid;
								_size += 2;
							}
						}
						else if (_size == size)
						{
							dst.at<cv::Vec3b>(i, j)[k] = zmid;
							_size += 2;
						}
						else
						{
							_size += 2;
						}


					}
				}
			}
		}
	delete []num;
	delete []nums;
	return dst;
}

效果展示

椒盐噪声
2016-05-07 20:15:59 lpsl1882 阅读数 12463

常见的噪声模型有(z是噪声值,μ表示均值,s2表示方差):

1、高斯噪声

2、瑞里噪声μ=a+sqrt(pi*b/4),s2=b(4-pi)/4

3、伽马噪声 μ=b/a,s2=b/a^2

4、指数分布噪声 μ=1/a,s2=1/a^2

5、均匀分布噪声 μ=(a+b)/2,s2=(b-a)^2/12

6、椒盐噪声其中盐表示亮点,椒表示暗点。

7、周期噪声,比如空间域图像受到正弦波信号干扰。

 

现在我们来试着给图像加上噪声。C++,python,matlab提供了普通随机数和服从高斯分布的随机数,可以直接生成椒盐噪声、均匀分布噪声和高斯噪声。但是剩下的几种噪声模型,要生成服从这些噪声模型的随机数就不太容易了。假设我们只能获取普通随机数,现在要把普通随机数变成服从特定函数分布的随机数,在连续系统下是很困难的,但是离散系统下有多种方法可以使用。比如给出一个很大的、有重复元素的集合,集合内元素的数量比上集合总数就是该元素在特定函数分布中应该出现的概率,这样随机获取集合的元素,出现某种元素的概率是服从特定的分布的。我使用另外一种方法。

假设当前图像像素范围为[0,255],我们将当前概率密度函数映射为p(x),x属于[0,255],然后通过累加方法求出概率函数F(x),x属于[0,255],注意这里F(255)=1,否则需要进行归一化。之后我获取普通随机数r,搜索得出r的值处于F(i)和F(i+1)之间,那么我就把i或者i+1作为获取到的服从p(x)分布的随机数。

获取服从分布的随机数r之后,再通过随机数生成(x,y)位置,给该点像素值加上r作为噪声。

https://github.com/artzers/NGImageProcessor.git ImageNoiseGenerator.py

2017-12-16 17:36:21 u012123989 阅读数 19862

python数字图像处理-图像噪声与去噪算法

figure_1.png

图像噪声

椒盐噪声

概述: 椒盐噪声(salt & pepper noise)是数字图像的一个常见噪声,所谓椒盐,椒就是黑,盐就是白,椒盐噪声就是在图像上随机出现黑色白色的像素。椒盐噪声是一种因为信号脉冲强度引起的噪声,产生该噪声的算法也比较简单。

给一副数字图像加上椒盐噪声的步骤如下:

  1. 指定信噪比 SNR (其取值范围在[0, 1]之间)
  2. 计算总像素数目 SP, 得到要加噪的像素数目 NP = SP * (1-SNR)
  3. 随机获取要加噪的每个像素位置P(i, j)
  4. 指定像素值为255或者0。
  5. 重复3,4两个步骤完成所有像素的NP个像素
  6. 输出加噪以后的图像

高斯噪声

概述: 加性高斯白噪声(Additive white Gaussian noise,AWGN)在通信领域中指的是一种功率谱函数是常数(即白噪声), 且幅度服从高斯分布的噪声信号. 这类噪声通常来自感光元件, 且无法避免.

去噪算法

中值滤波

概述: 中值滤波是一种非线性空间滤波器, 它的响应基于图像滤波器包围的图像区域中像素的统计排序, 然后由统计排序结果的值代替中心像素的值. 中值滤波器将其像素邻域内的灰度中值代替代替该像素的值. 中值滤波器的使用非常普遍, 这是因为对于一定类型的随机噪声, 它提供了一种优秀的去噪能力, 比小尺寸的均值滤波器模糊程度明显要低. 中值滤波器对处理脉冲噪声(也称椒盐噪声)非常有效, 因为该噪声是以黑白点叠加在图像上面的.

与中值滤波相似的还有最大值滤波器和最小值滤波器.

均值滤波

概述: 均值滤波器的输出是包含在滤波掩模领域内像素的简单平均值. 均值滤波器最常用的目的就是减噪. 然而, 图像边缘也是由图像灰度尖锐变化带来的特性, 所以均值滤波还是存在不希望的边缘模糊负面效应.

均值滤波还有一个重要应用, 为了对感兴趣的图像得出一个粗略描述而模糊一幅图像. 这样, 那些较小物体的强度与背景揉合在一起了, 较大物体变得像斑点而易于检测.掩模的大小由即将融入背景中的物体尺寸决定.

代码

https://github.com/wangshub/python-image-process

2017-08-23 08:31:51 u013883974 阅读数 24436

 

 

图像的空域噪声以及二维降噪算法介绍

 

 

1 图像噪声的成因

  图像在生成和传输过程中常常因受到各种噪声的干扰和影响而是图像降质,这对后续图像的处理和图像视觉效应将产生不利影响。噪声种类很多,比如:电噪声,机械噪声,信道噪声和其他噪声。因此,为了抑制噪声,改善图像质量,便于更高层次的处理,必须对图像进行去噪预处理。

2 图像噪声的特征

  图像噪声使得图像模糊,甚至淹没图像特征,给分析带来困难。

  图像噪声一般具有以下特点:

  (1) 噪声在图像中的分布和大小不规则,即具有随机性。

  (2) 噪声与图像之间一般具有相关性。例如,摄像机的信号和噪声相关,黑暗部分噪声大,明亮部分噪声小。又如,数字图像中的量化噪声与图像相位相关,图像内容

           接近平坦时,量化噪声呈现伪轮廓,但图像中的随机噪声会因为颤噪效应反而使量化噪声变得不很明显。

      (3) 噪声具有叠加性。在串联图像传输系统中,各部分窜入噪声若是同类噪声可以进行功率相加,依次信噪比要下降。

3 图像噪声的分类

3.1加性噪声和乘性噪声

      按噪声和信号之间的关系,图像噪声可分为加性噪声和乘性噪声。为了分析处理方便,往往将乘性噪声近似认为是加性噪声,而且总是假定信号和噪声是互相独立的。

假定信号为S(t),噪声为n(t),如果混合叠加波形是S(t)+n(t)的形式,则称其为加性噪声。加性嗓声和图像信号强度是不相关的,如图像在传输过程中引进的“信道噪声”电视摄像机扫描图像的噪声等。

      如果叠加波形为S(t)[1+n(t)]的形式,则称其为乘性噪声。乘性噪声则与信号强度有关,往往随图像信号的变化而变化,如飞点扫描图像中的嗓声、电视扫描光栅、胶片颗粒造成等。

3.2 外部噪声和内部噪声

      按照产生原因,图像噪声可分为外部噪声和内部噪声。外部噪声,即指系统外部干扰以电磁波或经电源串进系统内部而引起的噪声。如外部电气设备产生的电磁波干扰、天体放电产生的脉冲干扰等。由系统电气设备内部引起的噪声为内部噪声,如内部电路的相互干扰。内部噪声一般又可分为以下四种:(1)由光和电的基本性质所引起的噪声。(2)电器的机械运动产生的噪声。(3)器材材料本身引起的噪声。(4)系统内部设备电路所引起的噪声。

3.3 平稳噪声非平稳噪声

      按照统计特性,图像噪声可分为平稳噪声和非平稳噪声。统计特性不随时间变化的噪声称为平稳噪声。统计特性随时间变化的噪声称为非平稳噪声。

3.4其它几类噪声

       量化嗓声是数字图像的主要噪声源,其大小显示出数字图像和原始图像的差异,减少这种嗓声的最好办法就是采用按灰度级概率密度函数选择化级的最优化措施。

      “椒盐”噪声:此类嗓声如图像切割引起的即黑图像上的白点,白图像上的黑点噪声,在变换域引入的误差,使图像反变换后造成的变换噪声等。

      按噪声幅度随时间分布形状来定义,如其幅度分布是按高斯分布的就称其为高斯噪声,而按雷利分布的就称其为雷利噪声。

      按噪声频谱形状来命,如频谱均匀分布的噪声称为白噪声;频谱与频率成反比的称为1/f 噪声;而与频率平方成正比的称为三角噪声等等。

      根据经常影响图像质量的噪声源又可分电子噪声和光电子噪声。电子噪声:在阻性器件中由于电子随机热运动而造成的电子噪声是三种模型中最简单的。光电子噪声:

光电子噪声是由光的统计本质和图像传感器中光电转换过程引起的。

4 图像的噪声模型

      实际获得的图像含有的噪声,根据不同分类可将噪声进行不同的分类。从噪声的概率分布情况来看,可分为高斯噪声、瑞利噪声、伽马噪声、指数噪声和均匀噪声。

4.1 高斯噪声

      由于高斯噪声在空间和频域中数学上的易处理性,这种噪声(也称为正态噪声)模型经常被用于实践中。事实上,这种易处理性非常方便,使高斯模型经常用于临界情况下 。

  高斯随机变量z的PDF由下式给出:

                                                                      

     其中z表示灰度值,μ表示z的平均值或期望值,σ表示z的标准差。标准差的平方σ2称为z的方差。当z服从式(1.3.1)的分布时候,其值有70%落在[(μ-σ),(μ+σ)]内,且有95%落在[(μ-2σ),( μ+2σ)]范围内。 

4.2 瑞利噪声

     瑞利噪声的概率密度函数由下式给出:

                                                                    

     概率密度的均值和方差由下式给出:

                                                                               

4.3 伽马(爱尔兰)噪声

     伽马噪声的PDF由下式给出:

                                                                   

      其中,a>0,b为正整数且“!”表示阶乘。其密度的均值和方差由下式给出:

                                                                                 

      尽管经常被用来表示伽马密度,严格地说,只有当分母为伽马函数Г(b)时才是正确的。当分母如表达式所示时,该密度近似称为爱尔兰密度。

4.4 指数分布噪声

      指数噪声的PDF可由下式给出:

                                                                    

      其中a>0。概率密度函数的期望值和方差是:

                                                                              

4.5 均匀噪声分布

     均匀噪声分布的概率密度,由下式给出:

                                                                

    概率密度函数的期望值和方差可由下式给出:

                                                                             

1.3.6 脉冲噪声(椒盐噪声)

  (双极)脉冲噪声的PDF可由下式给出:

                                                              

  如果b>a,灰度值b在图像中将显示为一个亮点,相反,a的值将显示为一个暗点。若Pa或Pb为零,则脉冲噪声称为单极脉冲。如果Pa和Pb均不可能为零,尤其是它们近似相等时,脉冲噪声值将类似于随机分布在图像上的胡椒和盐粉微粒。由于这个原因,双极脉冲噪声也称为椒盐噪声。同时,它们有时也称为散粒和尖峰噪声。

  噪声脉冲可以是正的,也可以是负的。标定通常是图像数字化过程的一部分。因为脉冲干扰通常与图像信号的强度相比较大,因此,在一幅图像中,脉冲噪声总是数字化为最大值(纯黑或纯白)。这样,通常假设a,b是饱和值,从某种意义上看,在数字化图像中,它们等于所允许的最大值和最小值。由于这一结果,负脉冲以一个黑点(胡椒点)出现在图像中。由于相同的原因,正脉冲以白点(盐点)出现在图像中。对于一个8位图像,这意味着a=0(黑)。b=255(白)。

5 常见图像去噪算法简介

  图像噪声在数字图像处理技术中的重要性越来越明显,如高放大倍数航片的判读,X射线图像系统中的噪声去除等已经成为不可缺少的技术步骤。图像去噪算法可以分为以下几类:

  (1)空间域滤波

   空域滤波是在原图像上直接进行数据运算,对像素的灰度值进行处理。常见的空间域图像去噪算法有邻域平均法、中值滤波、低通滤波等。

  (2)变换域滤波

  图像变换域去噪方法是对图像进行某种变换,将图像从空间域转换到变换域,再对变换域中的变换系数进行处理,再进行反变换将图像从变换域转换到空间域来达到去除图像嗓声的目的。将图像从空间域转换到变换域的变换方法很多,如傅立叶变换、沃尔什-哈达玛变换、余弦变换、K-L变换以及小波变换等。而傅立叶变换和小波变换则是常见的用于图像去噪的变换方法。

  (3)偏微分方程

  偏微分方程是近年来兴起的一种图像处理方法,主要针对低层图像处理并取得了很好的效果。偏微分方程具有各向异性的特点,应用在图像去噪中,可以在去除噪声的同时,很好的保持边缘。偏微分方程的应用主要的一类是一种是基本的迭代格式,通过随时间变化的更新,使得图像向所要得到的效果逐渐逼近,以及对其改进后的后续工作。该方法在确定扩散系数时有很大的选择空间,在前向扩散的同时具有后向扩散的功能,所以,具有平滑图像和将边缘尖锐化的能力[5]。偏微分方程在低噪声密度的图像处理中取得了较好的效果,但是在处理高噪声密度图像时去噪效果不好,而且处理时间明显高出许多。

  (4)变分法

  另一种利用数学进行图像去噪方法是基于变分法的思想,确定图像的能量函数,通过对能量函数的最小化工作,使得图像达到平滑状态,现在得到广泛应用的全变分TV模型就是这一类。这类方法的关键是找到合适的能量方程,保证演化的稳定性,获得理想的结果。

  (5)形态学噪声滤除器

  将开与闭结合可用来滤除噪声,首先对有噪声图像进行开运算,可选择结构要素矩阵比噪声尺寸大,因而开运算的结果是将背景噪声去除;再对前一步得到的图像进行闭运算,将图像上的噪声去掉。据此可知,此方法适用的图像类型是图像中的对象尺寸都比较大,且没有微小细节,对这类图像除噪效果会较好。

 

几种降噪算法总结

 

顺便补充下

 

 

在图像处理中,我们会频繁用到这三个概念,这里整理了网上优秀的博客。供大家交流学习。

一、什么是时域

    时域是描述数学函数物理信号对时间的关系。例如一个信号的时域波形可以表达信号随着时间的变化。

二、什么是频域

    频域(频率域)——自变量是频率,即横轴是频率,纵轴是该频率信号的幅度,也就是通常说的频谱图。频谱图描述了信号的频率结构及频率与该频率信号幅度的关系。

三、什么是空间域

   空间域又称图像空间(image space)。由图像像元组成的空间。在图像空间中以长度(距离)为自变量直接对像元值进行处理称为空间域处理。

 

 

 

 

 

 

 

 

 

 

以时间作为变量所进行的研究就是时域

以频率作为变量所进行的研究就是频域

以空间坐标作为变量进行的研究就是空间域

以波数作为变量所进行的研究称为波数域

 

 

时域和频域

最近在上数字图像处理,时域和频域的概念我没有直观的概念,搜索一下,归纳如下:

 

1.最简单的解释

频域就是频率域,

平常我们用的是时域,是和时间有关的,

这里只和频率有关,是时间域的倒数。时域中,X轴是时间,

频域中是频率。频域就是分析它的频率特性!

2. 图像处理中:

  空间域,频域,变换域,压缩域等概念!

只是说要将图像变换到另一种域中,然后有利于进行处理和计算

比如说:图像经过一定的变换(Fourier变换,离散yuxua DCT 变换),图像的频谱函数统计特性:图像的大部分能量集中在低,中频,高频部分的分量很弱,仅仅体现了图像的某些细节。

2.离散傅立叶变换

一般有离散傅立叶变换和其逆变换

3.DCT变换

示波器用来看时域内容,频普仪用来看频域内容!!!

时域是信号在时间轴随时间变化的总体概括。

频域是把时域波形的表达式做傅立叶变化得到复频域的表达式,所画出的波形就是频谱图。是描述频率变化和幅度变化的关系。

时域做频谱分析变换到频域;空间域做频谱分析变换到波数域;

信号通过系统,在时域中表现为卷积,而在频域中表现为相乘。

无论是傅立叶变换还是小波变换,其实质都是一样的,既:将信号在时间域和频率域之间相互转换,从看似复杂的数据中找出一些直观的信息,再对它进行分 析。由于信号往往在频域比有在时域更加简单和直观的特性,所以,大部分信号分析的工作是在频域中进行的。音乐——其实就是时/频分析的一个极好例子,乐谱 就是音乐在频域的信号分布,而音乐就是将乐谱变换到时域之后的函数。从音乐到乐谱,是一次傅立叶或小波变换;从乐谱到音乐,就是一次傅立叶或小波逆变换。

 时域(时间域)——自变量是时间,即横轴是时间,纵轴是信号的变化。其动态信号x(t)是描述信号在不同时刻取值的函数。
频域(频率域)——自变量是频率,即横轴是频率,纵轴是该频率信号的幅度,也就是通常说的频谱图。频谱图描述了信号的频率结构及频率与该频率信号幅度的关系。
对信号进行时域分析时,有时一些信号的时域参数相同,但并不能说明信号就完全相同。因为信号不仅随时间变化,还与频率、相位等信息有关,这就需要进一步分析信号的频率结构,并在频率域中对信号进行描述。
动态信号从时间域变换到频率域主要通过傅立叶级数和傅立叶变换实现。周期信号靠傅立叶级数,非周期信号靠傅立叶变换。

很简单时域分析的函数是参数是t,也就是y=f(t),频域分析时,参数是w,也就是y=F(w)
两者之间可以互相转化。时域函数通过傅立叶或者拉普拉斯变换就变成了频域函数。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

释文: 以空间频率(即波数)为自变量描述图像的特征,可以将一幅图像像元值在空间上的变化分解为

具有不同振幅、空间频率和相位的简振函数的线性叠加,图像中各种空问频率成分的组成和分布称为

空间频谱。

 

这种对图像的空间频率特征进行分解、处理和分析称为空间频率域处理或波数域处理。

和时间域与频率域可互相转换相似,空间域与空间频率域也可互相转换。

在空间频率域中可以引用已经很成熟的频率域技术,处理的一般步骤为:

①对图像施行二维离散傅立叶变换或小波变换,将图像由图像空间转换到频域空间。

②在空间频率域中对图像的频谱作分析处理,以改变图像的频率特征。

即设计不同的数字滤波器,对图像的频谱进行滤波。频率域处理主要用于与图像空间频率有关的处理中。

如图像恢复、图像重建、辐射变换、边缘增强、图像锐化、图像平滑、噪声压制、频谱分析、纹理分析

等处理和分析中。

须注意,空间频率(波数)的单位为米 -l或(毫米)-1等。

 

2019-07-02 20:57:49 qq_37486501 阅读数 4995

噪声分类:

  • 高斯噪声
  1. 是随机噪声, 服从高斯分布
  2. 主要特点表现为:麻点
  • 椒盐噪声
  1. 胡椒噪声、盐噪声
  2. 主要特点表现为:黑白点

噪声的描述

  1. 均方误差 MSE : MSE越大,失真率越大
  2. 峰值信噪比 PSNR: PSNR越大,失真度越小

图像平滑(去噪)

  1. 平滑的目的: 在表刘源是图像基本特征的前提下, 消除或衰减噪声的影响, 提高视觉效果

  2. 基础知识:
    (1): 滤波: 使用空间模版(滤波器)处理图像的过程
    (2): 模版与模版运算: 模版和邻域大小相同

  3. 常用图像平滑方法(空间平滑滤波):

  • 均值滤波 (邻域平均法)——线性空间滤波
    MATLAB实现均值滤波,见我的博客:
    https://blog.csdn.net/qq_37486501/article/details/80274928
    (1): 基本思想: 某像素点灰度值=邻域中所有像素灰度值平均值 来代替
    (2): 优点: 在一定程度上可衰减噪声影响——拉小灰度差异
    (3): 缺点: 图像的边缘轮廓细节变模糊——边缘轮廓也做均值,导致的变模糊

  • 中值滤波(中位数)——非线性滤波
    MATLAB实现中值滤波,见我的博客:
    https://blog.csdn.net/qq_37486501/article/details/80274960
    (1): 基本思想: 某像素的灰度值=窗口内所有像素的灰度中值 来代替
    (2):窗口:
    有不同形状(
    一维:线状
    二维:十字、正方形、菱形、圆形)
    有不同大小(窗口大小中必含奇数元素, 为了保证中心像素值)
    (3): 优点:
    在去噪同时,较好的保持边缘轮廓细节
    适合处理椒盐噪声(因为: 不是去噪声点, 而使改变其灰度值)

  • 小波去噪
    将信号通过小波变换(采用Mallat算法)后,信号产生的小波系数含有信号的重要信息,将信号经小波分解后小波系数较大,噪声的小波系数较小,并且噪声的小波系数要小于信号的小波系数,通过选取一个合适的阀值,大于阀值的小波系数被认为是有信号产生的,应予以保留,小于阀值的则认为是噪声产生的,置为零从而达到去噪的目的。

  • 高斯滤波
    高斯滤波是一种线性平滑滤波,适用于消除高斯噪声,广泛应用于图像处理的减噪过程。高斯滤波就是对整幅图像进行加权平均的过程,每一个像素点的值,都由其本身和邻域内的其他像素值经过加权平均后得到。高斯滤波的具体操作是:用一个模板(或称卷积、掩模)扫描图像中的每一个像素,用模板确定的邻域内像素的加权平均灰度值去替代模板中心像素点的值。

  • 双边滤波器去噪
    双边滤波器(Bilateral filter)是一种可以保边去噪的滤波器。可以滤除图像数据中的噪声,且还会保留住图像的边缘、纹理等(因噪声是高频信号,边缘、纹理也是高频信息,高斯滤波会在滤除噪声的同时使得边缘模糊)。是使用一个卷积核(模板矩阵),叠加到待处理像素点上,使用对应邻域像素点的加权求和来作为新的输出像素点的值一种方法,简单来说,双边滤波和高斯滤波一样,不同只在于模板矩阵的不同。