OpenCV-跟我学一起学数字图像处理之中值滤波

中值滤波(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的中指滤波代码段如下,

 1 //load the Original Image and get some informations
 2 Mat src = imread("010.jpg",1);
 3 namedWindow("OriginalImage");
 4 imshow("OriginalImage",src);
 5 CV_Assert(src.depth() == CV_8U);
 6 const int nr = src.rows;
 7 const int nc = src.cols;
 8 const int nchannels = src.channels();
 9
10 //OpenCV Solution
11 Mat result_opencv;
12 medianBlur(src,result_opencv,3);
13 namedWindow("median filter_opencv");
14 imshow("median filter_opencv",result_opencv);

仿真结果:

原图:

用medianBlur中值滤波的结果:

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

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

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

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

 1 //own median filter algorithm
 2 uchar* previous = NULL;
 3 uchar* current = NULL;
 4 uchar* next = NULL;
 5 uchar* current_result_own = NULL;
 6 int arr[9];   //use 3*3 mask
 7 for(int i=1;i<nr-1;i++)
 8 {
 9     previous = src.ptr<uchar>(i-1);
10     current = src.ptr<uchar>(i);
11     next = src.ptr<uchar>(i+1);
12     current_result_own = result_own.ptr<uchar>(i);
13     for(int j=nchannels;j<nchannels*(nc-1);j++)
14     {
15         for(int k=0;k<3;k++)
16         {
17             arr[k] = previous[j+(k-1)*nchannels];
18             arr[k+3] = current[j+(k-1)*nchannels];
19             arr[k+6] = next[j+(k-1)*nchannels];
20         }
21         bubble_sort(arr,9);
22         current_result_own[j] = arr[4];
23     }
24 }
25
26 //set the pixels on the borders to zeros
27 result_own.row(0).setTo(Scalar(0));
28 result_own.row(nr-1).setTo(Scalar(0));
29 result_own.col(0).setTo(Scalar(0));
30 result_own.col(nc-1).setTo(Scalar(0));
31
32 //show the result
33 namedWindow("median filter_own");
34 imshow("median filter_own",result_own);

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

 1 //************************//
 2 //bubble sort
 3 //************************//
 4 void bubble_sort(int* arr,int num)
 5 {
 6     int temp;
 7     for(int i=1;i<num-1;i++)
 8     {
 9         for(int j=0;j<num-i;j++)
10            {
11                if(arr[j]>arr[j+1])
12                {
13                    temp = arr[j];
14                    arr[j] = arr[j+1];
15                    arr[j+1] = temp;
16                }
17            }
18     }
19 }

仿真结果:

时间: 2024-10-10 01:58:55

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

数字图像处理------中值滤波

一 中值滤波概念 中值滤波算法以某像素的领域图像区域中的像素值的排序为基础,将像素领域内灰度的中值代替该像素的值[1]: 如:以3*3的领域为例求中值滤波中像素5的值 图1 1)int pixel[9]中存储像素1,像素2...像素9的值: 2)对数组pixel[9]进行排序操作: 3)像素5的值即为数组pixel[9]的中值pixel[4]. 中值滤波对处理椒盐噪声非常有效. 二 中值滤波代码实现 项目工程:https://github.com/ranjiewwen/Everyday_Prac

[数字图像处理]图像复原--逆滤波

1.逆滤波的问题点 图像的老化,可以视为以下这样的一个过程.一个是退化函数的影响(致使图片模糊,褪色等),一个可加性噪声的影响. 用算式表示为 前几篇博文,主要是介绍可加性噪声的去除.本博文,主要介绍图像的逆滤波,即退化函数的去除.然而,逆滤波在空间域内的处理是很不方便的. 简单的来考虑,加法的逆运算是减法,乘法的逆运算的除法,微分的逆运算是积分(严密一点说是不定积分).那么就可以得到一个简单的结论了,要出去卷积的话,肯定需要用到卷积的逆运算.卷积的逆运算是---------反卷积,额,好像是一

【数字图像处理】七.MFC图像增强之图像普通平滑、高斯平滑、Laplacian、Sobel、Prewitt锐化详解

本文主要讲述基于VC++6.0 MFC图像处理的应用知识,主要结合自己大三所学课程<数字图像处理>及课件进行讲解,主要通过MFC单文档视图实现显示BMP图像增强处理,包括图像普通平滑.高斯平滑.不同算子的图像锐化知识.希望该篇文章对你有所帮助,尤其是初学者和学习图像处理的学生. [数字图像处理]一.MFC详解显示BMP格式图片 [数字图像处理]二.MFC单文档分割窗口显示图片 [数字图像处理]三.MFC实现图像灰度.采样和量化功能详解 [数字图像处理]四.MFC对话框绘制灰度直方图 [数字图像

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

本文主要讲述基于VC++6.0 MFC图像处理的应用知识,主要结合自己大三所学课程<数字图像处理>及课件进行解说.主要通过MFC单文档视图实现显示BMP图片点运算处理.包含图像灰度线性变换.灰度非线性变换.图像阈值化处理.图像均衡化处理等知识,并结合前一篇论文灰度直方图进行展示 .同一时候文章比較具体基础,希望该篇文章对你有所帮助,尤其是刚開始学习的人和学习图像处理的学生. [数字图像处理]一.MFC具体解释显示BMP格式图片 [数字图像处理]二.MFC单文档切割窗体显示图片 [数字图像处理]

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

本文主要讲述基于VC++6.0 MFC图像处理的应用知识,主要结合自己大三所学课程<数字图像处理>及课件进行讲解,主要通过MFC单文档视图实现显示BMP图片空间几何变换,包括图像平移.图形旋转.图像反转倒置镜像和图像缩放的知识.同时文章比较详细基础,没有采用GDI+获取矩阵,而是通过读取BMP图片信息头和矩阵像素实现变换,希望该篇文章对你有所帮助,尤其是初学者和学习图像处理的学生. [数字图像处理]一.MFC详解显示BMP格式图片 [数字图像处理]二.MFC单文档分割窗口显示图片 [数字图像处

【数字图像处理】四.MFC对话框绘制灰度直方图

本文主要讲述基于VC++6.0 MFC图像处理的应用知识,主要结合自己大三所学课程<数字图像处理>及课件进行回忆讲解,主要通过MFC单文档视图实现点击弹出对话框绘制BMP图片的灰度直方图,再获取平均灰度.中指灰度和标准差等值.文章比较详细基础,希望该篇文章对你有所帮助~ [数字图像处理]一.MFC详解显示BMP格式图片 [数字图像处理]二.MFC单文档分割窗口显示图片 [数字图像处理]三.MFC实现图像灰度.采样和量化功能详解 免费资源下载地址: http://download.csdn.ne

【数字图像处理】三.MFC实现图像灰度、采样和量化功能详解

本文主要讲述基于VC++6.0 MFC图像处理的应用知识,主要结合自己大三所学课程<数字图像处理>及课件进行讲解,主要通过MFC单文档视图实现显示BMP格式图片,并通过Bitmap进行灰度处理.图片采样和量化功能. 个人认为对初学者VC++6.0可能还是很值得学习的工具,所以采用它来讲解,而不是VS或C#.同时文章比较详细基础,希望该篇文章对你有所帮助~ [数字图像处理]一.MFC详解显示BMP格式图片 [数字图像处理]二.MFC单文档分割窗口显示图片 免费资源下载地址: http://dow

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

从这篇博文开始,小生正式从一个毫不相干专业转投数字图像处理.废话不多说了,talk is cheap. show me the code. 直方图均衡化目的 由于一些图像灰度的分布过于集中,这样会导致图像的层次不够分明,直方图均衡化就是为了让图像的灰度分布更均匀,图像的层次感更强. 数学原理 基于连续灰度分布的结论推导 直方图均衡化属于数字图像处理中灰度变换(intensity transformation)的内容,灰度变换的目的就是找到一个合适的映射函数s=T(r).将原图像的灰度值映射到新的

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

数字图像处理作业的输入图像全部都是灰度图像,所以汇总一下自己遇到的问题答案. OCV的图像容器是Mat<typename>,可以用imread(filename)读取图像,filename是c string,char*和const char*都行.灰度图像的typename是uchar,RGB图像的typename是Vec3b. Mat容器如果直接使用操作符赋值,只会复制一份信息头而不会复制包含数据的矩阵,由此而降低内存的浪费和速度,所以这样得到的多个Mat对象都指向同一个数据矩阵,换句话说,