中值滤波(median filter)在数字图像处理中属于空域平滑滤波的内容(spatial filtering)。对消除椒盐噪声具有很好的效果。

  • 数学原理

为了讲述的便捷,我们以灰度图为例。RGB三通道的彩色图可以通过每一个通道各自的中值滤波联合得到。

数字图像是以矩阵的方式存储的,具体存储方式可以参见OpenCV手册。中值滤波是通过所谓的mask operation操作进行的。以3x3的mask为例。设图像的矩阵形式如下:

0,0 0,1 0,2 0,3 0,4 0,5
1,0 1,1 1,2 1,3 1,4 1,5
2,0 2,1 2,2 2,3 2,4 2,5
3,0 3,1 3,2 3,3 3,4 3,5
4,0 4,1 4,2 4,3 4,4 4,5
5,0 5,1 5,2 5,3 5,4 5,5

图中每个方框代表一个像素,每个方框里的数字对代表该像素在图中的位置。中值滤波从位置(1,1)开始,建立一个3x3的mask

i-1,j-1 i-1,j i-1,j+1
i,j-1 i,j i,j+1
i+1,j-1 i+1,j i+1,j+1

让(1,1)与(i,j)对其,取出模板所覆盖的范围内像素值,取这九个值得中值然后赋给(1,1),作为(1,1)位置的新像素值。然后移动模板的中心(i,j)至(1,2),重复上面的操作,直至遍历整幅图片。这里面应该注意的是,我们在做中值滤波时,模板里的中值是赋给一个新建的全新图像,被滤波的图像像素值不会改变。这样就保证了每一次模板覆盖的区域都是原图像的像素。

注:

  1. mask并不一定要用3x3的矩阵来做,模板的大小不是一定的。
  2. 从上面的操作过程可以看到,在图像的最后一行和第一行,最后一列和第一列的像素都没有被遍历到,我们一般有两种方案解决这个问题。
    1. 可以将该位置的所有像素赋值为零。
    2. 可以在原图像的上下左右都加上相应的全零向量,然后再进行上述的中值滤波操作,这样所有原图的像素都可以被遍历到。
  • 基于OpenCV中值滤波程序

OpenCV中也用现成的中值滤波函数medianblur,具体用法为

medianBlur(InputArray src,OutputArray dst,int ksize);

其中InputArray src为Mat类的被滤波图片,OutputArray是Mat类的滤波后输出结果,ksize是mask的大小,如,如果用3x3的模板,ksize就传值3;

基于OpenCV的中指滤波代码段如下,

 //load the Original Image and get some informations
Mat src = imread("010.jpg",);
namedWindow("OriginalImage");
imshow("OriginalImage",src);
CV_Assert(src.depth() == CV_8U);
const int nr = src.rows;
const int nc = src.cols;
const int nchannels = src.channels(); //OpenCV Solution
Mat result_opencv;
medianBlur(src,result_opencv,);
namedWindow("median filter_opencv");
imshow("median filter_opencv",result_opencv);

仿真结果:

原图:

用medianBlur中值滤波的结果:

  • 基于中值滤波原理编写的中值滤波函数仿真

这次我们进行的不再是灰度图的仿真,所以有必要简单介绍一下彩色图在Mat类里保存的方式,见下图(来源:opencv.org)。

从图中我们可以看到,彩色图片中像素的三通道是保存在同一行中的,顺序是BGR。假如指针p[i]定位到的是(0,1)的蓝色通道,那么p[i+Mat.channels]定位到的就是下一列的蓝色通道。

基于中值滤波原理编写的中值滤波函数代码段如下

 //own median filter algorithm
uchar* previous = NULL;
uchar* current = NULL;
uchar* next = NULL;
uchar* current_result_own = NULL;
int arr[]; //use 3*3 mask
for(int i=;i<nr-;i++)
{
previous = src.ptr<uchar>(i-);
current = src.ptr<uchar>(i);
next = src.ptr<uchar>(i+);
current_result_own = result_own.ptr<uchar>(i);
for(int j=nchannels;j<nchannels*(nc-);j++)
{
for(int k=;k<;k++)
{
arr[k] = previous[j+(k-)*nchannels];
arr[k+] = current[j+(k-)*nchannels];
arr[k+] = next[j+(k-)*nchannels];
}
bubble_sort(arr,);
current_result_own[j] = arr[];
}
} //set the pixels on the borders to zeros
result_own.row().setTo(Scalar());
result_own.row(nr-).setTo(Scalar());
result_own.col().setTo(Scalar());
result_own.col(nc-).setTo(Scalar()); //show the result
namedWindow("median filter_own");
imshow("median filter_own",result_own);

其中bubble_sort是我用冒泡排序法写的排序函数,代码段如下,

 //************************//
//bubble sort
//************************//
void bubble_sort(int* arr,int num)
{
int temp;
for(int i=;i<num-;i++)
{
for(int j=;j<num-i;j++)
{
if(arr[j]>arr[j+])
{
temp = arr[j];
arr[j] = arr[j+];
arr[j+] = temp;
}
}
}
}

仿真结果:

OpenCV-跟我学一起学数字图像处理之中值滤波的更多相关文章

  1. 图像处理之中值滤波介绍及C实现

    1 中值滤波概述 中值滤波是基于排序统计理论的一种能有效抑制噪声的非线性信号平滑处理技术,它将每一像素点的灰度值设置为该点某邻域窗口内的所有像素点灰度值的中值. 中值滤波的基本原理是把数字图像或数字序 ...

  2. opencv3.2.0图像处理之中值滤波medianBlur API函数

    /*中值滤波:medianBlur函数是非线性滤波 函数原型:void medianBlur(inputArray src,OutputArray dst,int ksize) 参数详解: input ...

  3. Matlab图像处理——中值滤波medfilt2问题解决

    本文链接:https://blog.csdn.net/Pxzly1117/article/details/79201772程序: I=imread('13.jpg');%读入图像imshow(I);h ...

  4. 数字图像处理:基于MATLAB的车牌识别项目 标签: 图像处理matlab算法 2017-06-24 09:17 98人阅读 评论(0)

    学过了数字图像处理,就进行一个综合性强的小项目来巩固一下知识吧.前阵子编写调试了一套基于MATLAB的车牌识别的项目的代码.今天又重新改进了一下代码,识别的效果好一点了,也精简了一些代码.这里没有使用 ...

  5. 【数字图像处理】六.MFC空间几何变换之图像平移、镜像、旋转、缩放具体解释

    本文主要讲述基于VC++6.0 MFC图像处理的应用知识,主要结合自己大三所学课程<数字图像处理>及课件进行解说,主要通过MFC单文档视图实现显示BMP图片空间几何变换.包含图像平移.图形 ...

  6. 【数字图像处理】五.MFC图像点运算之灰度线性变化、灰度非线性变化、阈值化和均衡化处理具体解释

    本文主要讲述基于VC++6.0 MFC图像处理的应用知识,主要结合自己大三所学课程<数字图像处理>及课件进行解说.主要通过MFC单文档视图实现显示BMP图片点运算处理.包含图像灰度线性变换 ...

  7. OpenCV-跟我一起学数字图像处理之直方图均衡化

    从这篇博文开始,小生正式从一个毫不相干专业转投数字图像处理.废话不多说了,talk is cheap. show me the code. 直方图均衡化目的 由于一些图像灰度的分布过于集中,这样会导致 ...

  8. 数字图像处理作业使用OpenCV - 使用笔记

    数字图像处理作业的输入图像全部都是灰度图像,所以汇总一下自己遇到的问题答案. OCV的图像容器是Mat<typename>,可以用imread(filename)读取图像,filename ...

  9. 数字图像处理笔记与体会(一)——matlab编程基础

    最近开始学习数字图像处理,使用matlab实现,下面我就来记录笔记和体会,一方面是给大家提供参考,另一方面是防止我忘记了. 复习一下: 1.数字图像是用一个数字矩阵来表示的,数字阵列中的每个数字,表示 ...

随机推荐

  1. js多条件if语句简写发生Uncaught SyntaxError: Unexpected token }

    改写原生js 多条件if判断语句时,采用三元方法,发生Uncaught SyntaxError: Unexpected token } function compareImgSize() { var ...

  2. mkswap命令详解

    基础命令学习目录首页 原文链接:http://blog.51cto.com/arlen99/1743841 mkswap命令用于在一个文件或者设备上建立交换分区.在建立完之后要使用sawpon命令开始 ...

  3. Python之并发编程-多线程

    目录 一.threading模块介绍二.使用说明三.进一步介绍(守护线程,锁(互斥锁.递归锁),信号量,队列,event,condition,定时器) 1.守护线程 2.锁(互斥锁.递归锁) 3.信号 ...

  4. java第四次实验报告

    课程:Java程序与设计     班级:1352 姓 名:池彬宁  小组成员: 20135212池彬宁 20135208贺邦 学号:20135212 成绩:             指导教师:娄嘉鹏  ...

  5. Linux 目录结构及文件基本操作

    Linux 目录结构及文件基本操作 实验介绍 1.Linux 的文件组织目录结构. 2.相对路径和绝对路径. 3.对文件的移动.复制.重命名.编辑等操作. 一.Linux 目录结构 在讲 Linux ...

  6. 团队计划backlog---DayTwo

    任务索引卡(Two): 1.  季方:实现界面跳转,数据库相关数据的显示 的测试: 2.  司宇航:添加部分团队博客,并测试: 3.  王金萱.马佳慧:学习爬虫的相关内容,为将来统计博客部分做准备: ...

  7. Task 6.2冲刺会议九 /2015-5-22

    今天把之前的跳转问题加以改正并加以优化.遇到的主要问题是跳转的时后时间有点长,以为没有成功.之后查资料说是端口没有及时释放,导致了程序的滞缓.明天要继续把程序的界面进行优化.

  8. 结对作业-四则运算GUI

    目录: 一.项目地址二.PSP三.接口设计四.计算模块接口的设计与实现过程五.计算模块接口部分的性能改进六.计算模块部分单元测试展示七.计算模块部分异常处理说明八.界面模块的详细设计过程九.界面模块与 ...

  9. Gradle入门(3):构建第一个Java项目

    Gradle插件通过引入特定领域的约定和任务来构建你的项目.Java插件是Gradle自身装载的一个插件.Java插件提供的基本功能远比源代码编译和打包多.它为你的项目建立了一个标准的项目布局,并确保 ...

  10. 3、第一个Python程序

    现在,了解了如何启动和退出Python的交互式环境,我们就可以正式开始编写Python代码了. 在写代码之前,请千万不要用“复制”-“粘贴”把代码从页面粘贴到你自己的电脑上.写程序也讲究一个感觉,你需 ...