数字图像处理——空间滤波(去噪)

噪声图像

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

高斯噪声

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

// 生成高斯噪声
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, "逆谐波滤
  • 6
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值