冈萨雷斯数字图像处理第三章空间滤波

3.5.1均值滤波

1.数学原理
概念:“把每个像素都用周围的8个像素来做均值操作 ”
作用:平滑图像的用处, 有的图像的锐度很高,用这样的均值算法,可以把锐度降低。使得图像看上去更加自然
两种3x3的平滑滤波器(线性滤波):3x3平均滤波器R=1/9 ∑Zi------滤波器模板系数都为1; 3x3加权滤波器R=1/16∑Zi,滤波器模板系数不同,中心点影响最大。
均值滤波就是将滤波器模板和图像像素进行卷积。

需要注意的是滤波模板(卷积核)必须为奇数
在这里插入图片描述

2.实现代码
第一;opencv自带的均值滤波函数为
void blur(InputArray src, OutputArray dst, Size ksize, Point anchor=Point(-1,-1), int borderType=BORDER_DEFAULT )
参数解释:
. InputArray src: 输入图像,可以是Mat类型,图像深度是CV_8U、CV_16U、CV_16S、CV_32F以及CV_64F其中的某一个。
. OutputArray dst: 输出图像,深度和类型与输入图像一致
. Size ksize: 滤波模板(卷积核)kernel的尺寸,一般使用Size(w, h)来指定,如Size(3,3)
. Point anchor=Point(-1, -1): 字面意思是锚点(卷积核的中心点),也就是处理的像素位于kernel的什么位置,默认值为(-1, -1)即位于kernel中心点,如果没有特殊需要则不需要更改
. int borderType=BORDER_DEFAULT: 用于推断图像外部像素的某种边界模式,有默认值BORDER_DEFAULT

#include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h>
#include <vector>
#include <opencv2/imgproc/imgproc.hpp>
#include<cmath>
using namespace std;
using namespace cv;
int main() 
{
	Mat src, dst;
	src = imread("c:/users/征途/desktop/vs-cpp/project3/04.jpg");
	blur(src,dst, Size(3, 3));
	imshow("src", src);
	imshow("dst", dst);
	waitKey(0);
	return 0;
}

第二,自己用c++实现均值滤波函数

#include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h>
#include <vector>
#include <opencv2/imgproc/imgproc.hpp>
#include<cmath>
using namespace std;
using namespace cv;


void myblur(const Mat& src, Mat& dst, Size ksize)
{
	//若模板不是奇数模板,则报错退出
	if (ksize.width % 2 == 0 || ksize.height % 2 == 0)
	{
		cout << "please input odd ksize" << endl;
		exit(-1);
	}

	//根据ksize大小扩充模板边界
	int awidth = (ksize.width - 1) / 2;  //公式中的a 
	int aheight = (ksize.height - 1) / 2;// 公式中的b
	Mat asrc;
	//图像边界扩充函数copyMakeBorder,void copyMakeBorder( const Mat& src, Mat& dst,int top, int bottom, int left, int right,int borderType, const Scalar& value = Scalar() );
	copyMakeBorder(src, asrc, aheight, aheight, awidth, awidth, BORDER_DEFAULT);
	//根据图像通道数遍历图像求均值
	//通道数为1

	if (src.channels() == 1)
	{
		for (int i = 0+aheight; i < src.rows + aheight; i++) // i < 扩充后图片高
		{
			for (int j = 0+awidth; j < src.cols + awidth; j++)
			{
				int sum = 0;	//sum是成绩和
				int mean = 0;   //mean是均值
				for (int k = i - aheight; k <= i + aheight; k++) 
				{
					for (int l = j - awidth; l <= j + awidth; l++)
					{
						sum += asrc.at<uchar>(k, l);  //模板系数和像素乘积的和,采用的是3x3都为1的平均滤波模板
					}
				}
				mean = sum / (ksize.width*ksize.height); // 乘积和/模板系数和
				dst.at<uchar>(i - aheight, j - awidth) = mean;
			}
		}
	}
	//通道数为3	
	if (src.channels() == 3)
	{
		for (int i = aheight; i < src.rows + aheight; i++)
		{
			for (int j = awidth; j < src.cols + awidth; j++)
			{
				int sum[3] = { 0 };
				int mean[3] = { 0 };
				for (int k = i - aheight; k <= i + aheight; k++)
				{
					for (int l = j - awidth; l <= j + awidth; l++) //依次根据通道读取每个通道上的,模板系数和像素乘积的和
					{
						sum[0] += asrc.at<Vec3b>(k, l)[0];
						sum[1] += asrc.at<Vec3b>(k, l)[1];
						sum[2] += asrc.at<Vec3b>(k, l)[2];
					}
				}
				for (int m = 0; m < 3; m++) //依次循环按照通道数将卷积后的结果赋予dst
				{
					mean[m] = sum[m] / (ksize.width*ksize.height);
					dst.at<Vec3b>(i - aheight, j - awidth)[m] = mean[m];
				}
			}
		}
	}
}

int main() 
{
	Mat src, dst1,dst2;
	src = imread("c:/users/征途/desktop/vs-cpp/project3/04.jpg");
	//opencv自带函数
	blur(src,dst1, Size(3, 3));
	imshow("src", src);
	imshow("dst1", dst1);
	//自己编写的函数
	dst2 = Mat::zeros(src.size(), src.type());
	myblur(src, dst2, Size(3, 3));
	imshow("dst2", dst2);
	waitKey(0);
	return 0;
}

结果:1为原图,2为系统自带函数结果,3为自己编写结果
在这里插入图片描述

3.5.2中值滤波

1.数学原理
先将掩膜中欲求的像素及其领域内的像素值排序,确定出中值,并将中值赋予给该像素点。
针对随机噪声,椒盐噪声效果好,可以保护图像尖锐边缘;对高斯噪声效果差。
应用:中值滤波对脉冲噪声(如椒盐噪声)的抑制十分有用。

缺点:易造成图像的不连续性
在这里插入图片描述

2.实现代码
实现的思路:用一个数组存储模板中所有的像素值,进行排序,取数组中的中间值赋值给当前像素点

1.opencv自带函数为medianBlur()
2.c++自己编写函数mymedianBlur()
代码实现:
在这里插入图片描述
在这里插入图片描述

#include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h>
#include <vector>
#include <opencv2/imgproc/imgproc.hpp>
#include<cmath>
using namespace std;
using namespace cv;
//首先进行编写冒泡排序算法
void bublle_sort(std::vector<int> &arr)
{
	bool flag = true;//默认数组排序已经排好
	for (int i = 0; i < arr.size() - 1; ++i)
	{
		while (flag = false)   //如果排序错误,则执行循环体中的语句
		{
			for (int j = 0; j < arr.size() - 1 - i; ++j)
			{
				if (arr[j] > arr[j + 1])
				{
					int temp = arr[j];
					arr[j] = arr[j + 1];
					arr[j + 1] = temp;
					flag = true;
				}
			}
		}
	}
}

//用c++实现中值滤波
void mymedianBlur(cv::Mat& src, cv::Mat& dst, cv::Size ksize)//Mat &a的意思是创建一个矩阵a的引用
{
	//图像边界扩充
	if (ksize.width % 2 == 0 || ksize.height % 2 == 0) //卷积核要取奇数
	{
		fprintf(stderr, "Please enter odd size!");
		exit(-1);
	}
	int hh = (ksize.height - 1) / 2;
	int hw = (ksize.width - 1) / 2;
	cv::Mat Newsrc;
	cv::copyMakeBorder(src, Newsrc, hh, hh, hw, hw, cv::BORDER_REFLECT_101);//图像扩充,以边缘为轴,对称
	dst = cv::Mat::zeros(src.rows, src.cols, src.type());

	//编写中值滤波,先进行滑窗遍历图像来获取像素点像素
	//首先遍历图像源
	for (int i = hh; i < src.rows + hh; i++)
	{
		uchar* ptrdst = dst.ptr(i - hh);   //滑窗内的ptrdst
		for (int j = hw; i < src.cols + hw; j++)
		{
			std::vector<int> pix; //定义一个std内存中的容器,容器名叫pix,容器内的值为int类型,与数组类似,但是容器的大小可变

		//使用滑窗算法遍历
			for (int r = i - hh; r <= i + hh; r++)   //定义滑窗的高
			{
				const uchar* ptrsrc = Newsrc.ptr(r);  //指针取原图位于滑窗内的位置r处的元素
				for (int c = j - hw; c <= j + hw; c++) // 滑窗的宽
				{
					pix.push_back(ptrsrc[c]);  //在r的前提下,利用指针获取处的元素
				}
			}
			//对读取出来的元素冒泡排序
			bublle_sort(pix);
			ptrdst[j - hw] = pix[(ksize.area() - 1) / 2];//将排序后的中值映射给输出图像

		}
	}
}
	// 主函数应用
int main()
{
	cv::Mat src = cv::imread("c:/users/征途/desktop/vs-cpp/project3/09中值.jpg");
	Mat dst1;
	Mat dst2;
	cv::Size ksize(5, 5);
	mymedianBlur(src, dst1, ksize);
	medianBlur(src, dst2, (5,5));
	imshow("my", dst1);
	imshow("cv", dst2);
	waitKey(0);
	return 0;
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
完整版PDF电子书下载 带索引书签目录高清版。642页,绝对的完整、高清,有目录,带索引书签。 数字图像处理 冈萨雷斯 第三版 中文本 在数字图像处理领域 《数字图像处理 第三版 》作为主要教材已有30多年 这一版本是作者在前两版的基础上修订而成的 是前两版的发展与延续 除保留了前两版的大部分内容外 根据读者的反馈 作者在13个方面对《数字图像处理 第三版 》进行了修订 新增了400多幅图像 200多幅图表及80多道习题 融入了近年来数字图像处理领域的重要进展 因而《数字图像处理 第三版 》特色鲜明且与时俱进 《数字图像处理 第三版 》仍分为12章 即绪论 数字图像基础 灰度变换与空间滤波 频率域滤波 图像复原与重建 彩色图像处理 小波和多分辨率处理 图像压缩 形态学图像处理 图像分割 表示与描述 目标识别   《数字图像处理 第三版 》的读者对象主要是从事信号与信息处理 通信工程 电子科学与技术 信息工程 自动化 计算机科学与技术 地球物理 生物工程 生物医学工程 物理 化学 医学 遥感等领域的大学教师和科技工作者 研究生 大学本科高年级学生及工程技术人员 ">数字图像处理 冈萨雷斯 第三版 中文本 在数字图像处理领域 《数字图像处理 第三版 》作为主要教材已有30多年 这一版本是作者在前两版的基础上修订而成的 是前两版的发展 与延续 除保留了前两版的大部分内容外 根据 [更多]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值