数字图像处理——图像的空间域增强OpenCV 实验二均值滤波和中值滤波

图像平滑

下一篇图像锐化

众所周知,实际获得的图像在形成、传输、接收和处理的过程中,不可避免地存在着外部和内部的噪声干扰。噪声恶化了图像质量,使图像模糊,给分析带来困难。因此,去除噪声,恢复原始图像时图像处理中的一个重要内容。消除图像噪声的工作称之为图像平滑或滤波。

 

图像平滑方法包括空域法和频域法两大类。在空域法中,图像平滑常用的方法是采用均值滤波或中值滤波
 

均值滤波

对于均值滤波,它是采用一个有奇数点的滑动窗口在图像上滑动,将窗口中心点对应的图像像素点的灰度值用窗口内的各个点的灰度值的平均值代替,在取均值过程中,如果窗口规定了各个像素点所占的权重,也就是各个像素点的系数,则称为加权均值滤波。
 

中值滤波

对于中值滤波,窗口中心点所对应像素的灰度值用窗口内所有像素的中间值代替。实现均值或中值滤波时,可以定义一个n*n的模板数组。另外,读者需要注意一点,在用窗口扫描图像过程中,对于图像四个边缘的像素点,可以不处理;也可以用灰度值为"0"的像素点扩展图像的边缘。

OpenCV实现

编程实现车牌图像的去噪,分别采用均值滤波器和中值滤波器进行处理,比较两种滤波器效果。

原图:

在这里插入图片描述

结果图:

效果

均值滤波器

首先需要求出传入像素点的九宫格像素值的均值。

//求均值
uchar getAverage(Mat src,int i, int j,int way) {
	uchar newData;
	newData = (
		src.at<Vec3b>(i-1, j)[way] + src.at<Vec3b>(i - 1, j)[way] + src.at<Vec3b>(i - 1, j+1)[way] + 
		src.at<Vec3b>(i, j - 1)[way] +src.at<Vec3b>(i , j)[way] + src.at<Vec3b>(i, j + 1)[way] + 
		src.at<Vec3b>(i + 1, j - 1)[way] + src.at<Vec3b>(i+1, j )[way] + src.at<Vec3b>(i + 1, j+1)[way]
		) / 9;

	return newData;
}

然后遍历像素点进行更新,注意边框上的像素因为不满足九宫格,会直接赋值原来的像素值。

//均值滤波
Mat AverageFilter(const Mat& src, Mat& dst) {
	if (!src.data) return src;
	
	for (int i = 0; i < src.rows; ++i)
		for (int j = 0; j < src.cols; ++j) {

			if (i >= 1 && j >= 1 && i < src.rows - 1 && j < src.cols - 1) {
				dst.at<Vec3b>(i, j)[0] = getAverage(src, i, j, 0);
				dst.at<Vec3b>(i, j)[1] = getAverage(src, i, j, 1);
				dst.at<Vec3b>(i, j)[2] = getAverage(src, i, j, 2);
			}
			else {

				dst.at<Vec3b>(i, j)[0] = src.at<Vec3b>(i, j)[0];
				dst.at<Vec3b>(i, j)[1] = src.at<Vec3b>(i, j)[1];
				dst.at<Vec3b>(i, j)[2] = src.at<Vec3b>(i, j)[2];
			}
		}
	return dst;
}

在这里插入图片描述

中值滤波器

需要求出传入像素点的九宫格像素值的中值。

//求中值
uchar getMedian(Mat src, int a, int b, int way) {
	uchar newArray[9];
	newArray[0] = src.at<Vec3b>(a - 1, b - 1)[way];
	newArray[1] = src.at<Vec3b>(a - 1, b )[way];
	newArray[2] = src.at<Vec3b>(a - 1, b + 1)[way];
	newArray[3] = src.at<Vec3b>(a , b -1)[way];
	newArray[4] = src.at<Vec3b>(a , b )[way];
	newArray[5] = src.at<Vec3b>(a , b + 1)[way];
	newArray[6] = src.at<Vec3b>(a + 1, b -1)[way];
	newArray[7] = src.at<Vec3b>(a + 1, b)[way];
	newArray[8] = src.at<Vec3b>(a + 1, b+1)[way];
	int len = (int)sizeof(newArray) / sizeof(uchar);
	uchar temp;
	for (int i = 0; i < len - 1; i++)
		for (int j = 0; j < len - 1 - i; j++)
			if (newArray[j] > newArray[j + 1])
			{
				temp = newArray[j];
				newArray[j] = newArray[j + 1];
				newArray[j + 1] = temp;
			}
	

	return  newArray[4];
}

然后遍历像素点进行更新,注意边框上的像素因为不满足九宫格,会直接赋值原来的像素值。

//中值滤波
Mat MedianFilter(const Mat& src, Mat& dst) {
	if (!src.data) return src;
	for (int i = 0; i < src.rows; ++i) {
		for (int j = 0; j < src.cols; ++j) {
			if (i >= 1 && j >= 1 && i < src.rows - 1 && j < src.cols - 1) {
				dst.at<Vec3b>(i, j)[0] = getMedian(src, i, j, 0);
				dst.at<Vec3b>(i, j)[1] = getMedian(src, i, j, 1);
				dst.at<Vec3b>(i, j)[2] = getMedian(src, i, j, 2);
			}
			else {
				dst.at<Vec3b>(i, j)[0] = src.at<Vec3b>(i, j)[0];
				dst.at<Vec3b>(i, j)[1] = src.at<Vec3b>(i, j)[1];
				dst.at<Vec3b>(i, j)[2] = src.at<Vec3b>(i, j)[2];
			}
		}
	}
	return dst;
}

在这里插入图片描述

所有代码

#include<opencv2\opencv.hpp>
#include<iostream>

using namespace cv;
using namespace std;

//2021.4.25
//Solye
//求均值
uchar getAverage(Mat src,int i, int j,int way) {
	uchar newData;
	newData = (
		src.at<Vec3b>(i-1, j)[way] + src.at<Vec3b>(i - 1, j)[way] + src.at<Vec3b>(i - 1, j+1)[way] + 
		src.at<Vec3b>(i, j - 1)[way] +src.at<Vec3b>(i , j)[way] + src.at<Vec3b>(i, j + 1)[way] + 
		src.at<Vec3b>(i + 1, j - 1)[way] + src.at<Vec3b>(i+1, j )[way] + src.at<Vec3b>(i + 1, j+1)[way]
		) / 9;

	return newData;
}


//均值滤波
Mat AverageFilter(const Mat& src, Mat& dst) {
	if (!src.data) return src;
	
	for (int i = 0; i < src.rows; ++i)
		for (int j = 0; j < src.cols; ++j) {

			if (i >= 1 && j >= 1 && i < src.rows - 1 && j < src.cols - 1) {
				dst.at<Vec3b>(i, j)[0] = getAverage(src, i, j, 0);
				dst.at<Vec3b>(i, j)[1] = getAverage(src, i, j, 1);
				dst.at<Vec3b>(i, j)[2] = getAverage(src, i, j, 2);
			}
			else {

				dst.at<Vec3b>(i, j)[0] = src.at<Vec3b>(i, j)[0];
				dst.at<Vec3b>(i, j)[1] = src.at<Vec3b>(i, j)[1];
				dst.at<Vec3b>(i, j)[2] = src.at<Vec3b>(i, j)[2];
			}
		}
	return dst;
}
//求中值
uchar getMedian(Mat src, int a, int b, int way) {
	uchar newArray[9];
	newArray[0] = src.at<Vec3b>(a - 1, b - 1)[way];
	newArray[1] = src.at<Vec3b>(a - 1, b )[way];
	newArray[2] = src.at<Vec3b>(a - 1, b + 1)[way];
	newArray[3] = src.at<Vec3b>(a , b -1)[way];
	newArray[4] = src.at<Vec3b>(a , b )[way];
	newArray[5] = src.at<Vec3b>(a , b + 1)[way];
	newArray[6] = src.at<Vec3b>(a + 1, b -1)[way];
	newArray[7] = src.at<Vec3b>(a + 1, b)[way];
	newArray[8] = src.at<Vec3b>(a + 1, b+1)[way];
	int len = (int)sizeof(newArray) / sizeof(uchar);
	uchar temp;
	for (int i = 0; i < len - 1; i++)
		for (int j = 0; j < len - 1 - i; j++)
			if (newArray[j] > newArray[j + 1])
			{
				temp = newArray[j];
				newArray[j] = newArray[j + 1];
				newArray[j + 1] = temp;
			}
	return  newArray[4];
}

//中值滤波
Mat MedianFilter(const Mat& src, Mat& dst) {
	if (!src.data) return src;
	for (int i = 0; i < src.rows; ++i) {
		for (int j = 0; j < src.cols; ++j) {
			if (i >= 1 && j >= 1 && i < src.rows - 1 && j < src.cols - 1) {
				dst.at<Vec3b>(i, j)[0] = getMedian(src, i, j, 0);
				dst.at<Vec3b>(i, j)[1] = getMedian(src, i, j, 1);
				dst.at<Vec3b>(i, j)[2] = getMedian(src, i, j, 2);
			}
			else {
				dst.at<Vec3b>(i, j)[0] = src.at<Vec3b>(i, j)[0];
				dst.at<Vec3b>(i, j)[1] = src.at<Vec3b>(i, j)[1];
				dst.at<Vec3b>(i, j)[2] = src.at<Vec3b>(i, j)[2];
			}
		}
	}
	return dst;
}

int main()
{
	Mat src = imread("XXXXXXXXXX.bmp");
	Mat averageFilter;
	Mat medianFilter;
	averageFilter.create(src.rows, src.cols, src.type());
	medianFilter.create(src.rows, src.cols, src.type());

	imshow("原图", src);
	imshow("均值滤波", AverageFilter(src, averageFilter));
	imshow("中值滤波", MedianFilter(src,medianFilter));

	waitKey();

}

下一篇 图像锐化

图像锐化

https://blog.csdn.net/weixin_44394801/article/details/116132496

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雪野Solye

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值