首页 > 其他分享 >数字图像处理之「中值滤波」

数字图像处理之「中值滤波」

时间:2023-04-14 09:22:37浏览次数:47  
标签:src ... 卷积 数字图像处理 滤波 value fi pixel

中值滤波原理

中值滤波就是用一个奇数点的移动窗口(要求奇数主要是为了保证整个模板有唯一中心元素),将窗口中心点的值用窗口内各点的中值代替。假设窗口内有5点,其值为80、90、200、110和120,那么此窗口内各点的中值即为110。

设有一个一维序列f1,f2,...,fnf1,f2,...,fn,取窗口长度(点数)为m(m为奇数),对其进行中值滤波,就是从输入序列中相机抽出m个数fi−v,...,fi−1,fi,fi+1,...,fi+vfi−v,...,fi−1,fi,fi+1,...,fi+v(其中fifi为窗口中心点值,v=(m−1)/2v=(m−1)/2),再将这m个点按其数值大小排序,取其序号为中心点的那个数作为滤波输出。用数学公式表示为:

 

yi=Median{fi−v,...,fi−1,fi,fi+1,...,fi+v},i∈N,v=m−12yi=Median{fi−v,...,fi−1,fi,fi+1,...,fi+v},i∈N,v=m−12

 

如:以3*3的领域为例求中值滤波中像素5的值。

image

  1. int pixel[9]中存储像素1,像素2...像素9的值;
  2. 对数组pixel进行排序操作;
  3. 像素5的值即为数组pixel的中值pixel[4]。

代码实现

void medianFilter(cv::Mat& src, cv::Mat& dst, cv::Size size) {
	/*step1:判断窗口size是否为奇数*/
	if (size.width % 2 == 0 || size.height % 2 == 0) {
		cout << "卷积核窗口大小应为奇数!\n";
		exit(-1);
	}

	/*step2:对原图进行边界扩充*/
	int h = (size.height - 1) / 2;
	int w = (size.width - 1) / 2;
	Mat src_border;
	copyMakeBorder(src, src_border, h, h, w, w, BORDER_REFLECT_101);

	/*step3:卷积操作*/
 	map<uchar, Point> mp; // 定义容器存储每个卷积窗口内各像素点的<像素值, 像素位置>
	for (int i = h; i < src.rows + h; i++) {
		for (int j = w; j < src.cols + w; j++) {
			mp.clear();
			for (int ii = i - h; ii <= i + h; ii++) {
				for (int jj = j - w; jj <= j + w; jj++) {
					Point point(jj, ii);
					uchar value;
					if (src.channels() == 1) {
						// 灰度图像,存储灰度值
						value = src_border.at<uchar>(ii, jj);
					}else {
						// 彩色图像,存储亮度值
						uchar value_b = src_border.at<cv::Vec3b>(ii, jj)[0];
						uchar value_g = src_border.at<cv::Vec3b>(ii, jj)[1];
						uchar value_r = src_border.at<cv::Vec3b>(ii, jj)[2];
						value = 0.114 * value_b + 0.587 * value_g + 0.299 * value_r;
					}
					mp[value] = point;
				}
			}
			// 将窗口中心点的值用窗口内个点的中值代替
			auto iter = mp.begin();
			int count = 0;
			Point pixel;
			int median_size = mp.size() / 2;
			while (iter != mp.end()) {
				if (count == median_size) {
					pixel = Point(iter->second.x, iter->second.y);
					break;
				}
				count++;
				iter++;
			}
			if (src.channels() == 1) {
				dst.at<uchar>(i - h, j - w) = src_border.at<uchar>(pixel.y, pixel.x);
			}
			else {
				dst.at<cv::Vec3b>(i - h, j - w)[0] = src_border.at<cv::Vec3b>(pixel.y, pixel.x)[0];
				dst.at<cv::Vec3b>(i - h, j - w)[1] = src_border.at<cv::Vec3b>(pixel.y, pixel.x)[1];
				dst.at<cv::Vec3b>(i - h, j - w)[2] = src_border.at<cv::Vec3b>(pixel.y, pixel.x)[2];
			}
		}
	}
}

代码讲解

copyMakeBorder(src,src_border,h,h,w,w,BORDER_REFLECT_101);

在模板或卷积的加权运算中的图像边界问题:当在图像上移动模板(卷积核)至图像边界时,在原图像中找不到与卷积核中的加权系数相对应的N个像素(N为卷积核元素个数),即卷积核悬挂在图像的边界上,这种现象在图像的上下左右四个边界上均会出现。例如,当模板为:

 

19⎡⎣⎢111111111⎤⎦⎥19[111111111]

 

设原图像为:

 

⎡⎣⎢⎢⎢12341234123412341234⎤⎦⎥⎥⎥[11111222223333344444]

 

经过卷积操作之后图像为:

 

⎡⎣⎢⎢⎢−−−−−23−−23−−23−−−−−⎤⎦⎥⎥⎥[−−−−−−222−−333−−−−−−]

 

"-"表示无法进行卷积操作的像素点。

解决方法有2种:①忽略图像边界数据(即不管边界,卷积操作的范围从整张图缩小为边界内缩K圈,K的值随卷积核尺寸变化)。②将原图像往外扩充像素,如在图像四周复制源图像边界的值,从而使得卷积核悬挂在原图像四周时也能进行正常的计算。

 

value=0.114*value_b+0.587*value_g+0.299*value_r;

对于彩色图像,我们取图像亮度的中间值,亮度值的计算方法为:

 

luminance=0.299R+0.587G+0.114Bluminance=0.299R+0.587G+0.114B

 

map<uchar, Point> mp;

map为C++的stl中的关联性容器,为了实现快速查找,map内部本身就是按序存储的(map底层实现是红黑二叉树)。在我们插入<key, value>键值对时,就会按照key的大小顺序进行存储,其中key的类型必须能够进行 < 运算,且唯一,默认排序是按照从小到大遍历。

因此,将亮度值或灰度值作为键,map将自动进行按键排序,无需手动书写排序代码。

实现效果

卷积核size为(5, 5)。

image

标签:src,...,卷积,数字图像处理,滤波,value,fi,pixel
From: https://www.cnblogs.com/mylinke/p/17317260.html

相关文章

  • 算法 | 数字图像处理之「中值滤波」
    中值滤波原理中值滤波就是用一个奇数点的移动窗口,将窗口中心点的值用窗口内个点的中值代替。假设窗口内有5点,其值为80、90、200、110和120,那么此窗口内各点的中值即为110。设有一个一维序列\(f_1,f_2,...,f_n\),取窗口长度(点数)为m(m为奇数),对其进行中值滤波,就是从输入序列中相机抽......
  • 28.图像滤波
    1、均值滤波代码清单5-8blur()函数原型voidcv::blur(InputArraysrc,OutputArraydst,Sizeksize,Pointanchor=Point(-1,-1),intborderType=BORDER_DEFAULT)待......
  • H.264 入门篇 - 14 (去块滤波)
    目录1、产生的原因2、去块滤波的作用3、去块滤波的执行过程3.1、概念3.2、宏块去块滤波的过程3.2.1、计算边界强度3.2.2、区分真假边界4、滤波运算4.1、BS<44.2、BS=4 H264视频编码标准中,在解码器反变换量化后会出现块效应。1、产生的原因量化过程是有损的......
  • m基于shepp-Logan模型和滤波反投影的医学图像多尺度全局重建和局部重建matlab仿真
    1.算法描述        从投影重建物体的截面图像是图像处理中非常重要的技术此技术在物体的无损伤性检测其内部缺陷的应用中能起很大作用从投影重建图像的技术早在20世纪中期就已经制成常规医疗诊断设备的商品1917年奥地利数学家J.Radon发表的论文证明了二维物体或三维物体......
  • 基于simulink的车辆坡度与质量识别模型,扩展卡尔曼滤波,估计曲线与实际误差合理
    基于simulink的车辆坡度与质量识别模型,扩展卡尔曼滤波,估计曲线与实际误差合理YID:8572645488015821......
  • 卡尔曼滤波物体轨迹预测趣味实战
       卡尔曼滤波实战最近刚好看到了一个有意思的卡尔曼滤波的视频,于是就学习了一下,现分享给大家......
  • MPU6050开发 -- 卡尔曼滤波
    上一篇文章有讲到卡尔曼滤波了,现在需要将其添加到我们之前的C52测试程序中。STM32相关工程,下载:STM32F10x卡尔曼滤波一、再看一下卡尔曼滤波程序 #include<math.h>#include"stm32f10x.h"#include"Kalman_Filter.h"//卡尔曼滤波参数与函数floatdt=0.001;//注意:d......
  • 基于matlab的CQMFB单带滤波器设计仿真
    1.算法描述QMF         在滤波器的某些附加条件下,与分析滤波器组和合成滤波器组相关联的变换是正交的。正态性意味着样品的能量在转换过程中保持不变。如果满足这些条件,滤波器具有以下显著特性:合成滤波器是分析滤波器的时间反转版本,高通滤波器是低通滤波器的调制版本,......
  • 卡尔曼滤波做分类融合
    ——做项目的时候需要用到多模态的融合,找了一些相关资料,简单学习一下卡尔曼滤波的方法吧。在多模态分类中,我们通常会使用多个传感器或模态来收集不同类型的信息,并将这些信息结合起来以做出最终的分类决策。为了实现这个目标,我们需要一个能够整合多个模态数据的方法。一种有效的......
  • 功率型锂离子电池双无迹卡尔曼滤波算法(DUKF)soc和soh联合估计,估计欧姆内阻,内阻表征SOH
    功率型锂离子电池双无迹卡尔曼滤波算法(DUKF)soc和soh联合估计,估计欧姆内阻,内阻表征SOHmatlab代码DST和US06工况多篇参考文献支持YID:32249655598283937......