图像处理:中值滤波&均值滤波

图像处理:中值滤波&均值滤波转自 openCV 之中值滤波 amp 均值滤波 及代码实现 https blog csdn net weixin article details nbsp 在开始我们今天的博客之前 我们需要先了解一下什么是滤波 openCV 之中值滤波 amp 均值滤波 及代码实现 首先我们看一下图像滤波的概念 图像滤波 即在尽量保留图像细节特征的条件下对目标图像的噪声进行抑

转自:openCV之中值滤波&均值滤波(及代码实现):https://blog.csdn.net/weixin_/article/details/

 在开始我们今天的博客之前,我们需要先了解一下什么是滤波:

openCV之中值滤波&均值滤波(及代码实现)首先我们看一下图像滤波的概念。图像滤波,即在尽量保留图像细节特征的条件下对目标图像的噪声进行抑制,是图像预处理中不可缺少的操作,其处理效果的好坏将直接影响到后续图像处理和分析的有效性和可靠性。

下图左边是原图右边是噪声图:

图像处理:中值滤波&均值滤波图像处理:中值滤波&均值滤波

 

举一个滤波在我们生活中的应用:美颜的磨皮功能。如果将我们脸上坑坑洼洼比作是噪声的话,那么滤波算法就是来取出这些噪声,使我们自拍的皮肤看起来很光滑。

这篇博文会介绍中值滤波以及均值滤波两种算法

 

一.均值滤波

          图片中一个方块区域(一般为3*3)内,中心点的像素为全部点像素值的平均值。均值滤波就是对于整张图片进行以上操作。

我们可以看下图的矩阵进行理解

                                                                      图像处理:中值滤波&均值滤波

                         图像处理:中值滤波&均值滤波

缺陷:均值滤波本身存在着固有的缺陷,即它不能很好地保护图像细节,在图像去噪的同时也破坏了图像的细节部分,从而使图像变得模糊,不能很好地去除噪声点。特别是椒盐噪声

实现代码:

#include "opencv2/imgproc.hpp" #include "opencv2/highgui.hpp" #include 
  
    using namespace cv; using namespace std; //均值滤波 void AverFiltering(const Mat &src,Mat &dst) { if (!src.data) return; //at访问像素点 for (int i = 1; i 
   
     = 0) && (j - 1) >= 0 && (i + 1) 
    
      (i, j)[0] = (src.at 
     
       (i, j)[0] + src.at 
      
        (i - 1, j - 1)[0] + src.at 
       
         (i - 1, j)[0] + src.at 
        
          (i, j - 1)[0] + src.at 
         
           (i - 1, j + 1)[0] + src.at 
          
            (i + 1, j - 1)[0] + src.at 
           
             (i + 1, j + 1)[0] + src.at 
            
              (i, j + 1)[0] + src.at 
             
               (i + 1, j)[0]) / 9; dst.at 
              
                (i, j)[1] = (src.at 
               
                 (i, j)[1] + src.at 
                
                  (i - 1, j - 1)[1] + src.at 
                 
                   (i - 1, j)[1] + src.at 
                  
                    (i, j - 1)[1] + src.at 
                   
                     (i - 1, j + 1)[1] + src.at 
                    
                      (i + 1, j - 1)[1] + src.at 
                     
                       (i + 1, j + 1)[1] + src.at 
                      
                        (i, j + 1)[1] + src.at 
                       
                         (i + 1, j)[1]) / 9; dst.at 
                        
                          (i, j)[2] = (src.at 
                         
                           (i, j)[2] + src.at 
                          
                            (i - 1, j - 1)[2] + src.at 
                           
                             (i - 1, j)[2] + src.at 
                            
                              (i, j - 1)[2] + src.at 
                             
                               (i - 1, j + 1)[2] + src.at 
                              
                                (i + 1, j - 1)[2] + src.at 
                               
                                 (i + 1, j + 1)[2] + src.at 
                                
                                  (i, j + 1)[2] + src.at 
                                 
                                   (i + 1, j)[2]) / 9; } else {//边缘赋值 dst.at 
                                  
                                    (i, j)[0] = src.at 
                                   
                                     (i, j)[0]; dst.at 
                                    
                                      (i, j)[1] = src.at 
                                     
                                       (i, j)[1]; dst.at 
                                      
                                        (i, j)[2] = src.at 
                                       
                                         (i, j)[2]; } } } //图像椒盐化 void salt(Mat &image, int num) { if (!image.data) return;//防止传入空图 int i, j; srand(time(NULL)); for (int x = 0; x < num; ++x) { i = rand() % image.rows; j = rand() % image.cols; image.at 
                                        
                                          (i, j)[0] = 255; image.at 
                                         
                                           (i, j)[1] = 255; image.at 
                                          
                                            (i, j)[2] = 255; } } void main() { Mat image = imread("路飞.jpg"); Mat Salt_Image; image.copyTo(Salt_Image); salt(Salt_Image, 3000); Mat image1(image.size(), image.type()); Mat image2; AverFiltering(Salt_Image, image1); blur(Salt_Image, image2, Size(3, 3));//openCV库自带的均值滤波函数 imshow("原图", image); imshow("自定义均值滤波", image1); imshow("openCV自带的均值滤波", image2); waitKey(); } 
                                           
                                          
                                         
                                        
                                       
                                      
                                     
                                    
                                   
                                  
                                 
                                
                               
                              
                             
                            
                           
                          
                         
                        
                       
                      
                     
                    
                   
                  
                 
                
               
              
             
            
           
          
         
        
       
      
     
    
  

 

图像处理:中值滤波&均值滤波图像处理:中值滤波&均值滤波

可以看到图片变模糊而且噪声并没有很有效的去除,该算法只是模糊化了图片而已。

二.中值滤波

       首先,我们复习中值。在一连串数字{1,4,6,8,9}中,数字6就是这串数字的中值。由此我们可以应用到图像处理中。依然我们在图像中去3*3的矩阵,里面有9个像素点,我们将9个像素进行排序,最后将这个矩阵的中心点赋值为这九个像素的中值。

图像处理:中值滤波&均值滤波

                                     图像处理:中值滤波&均值滤波

代码:

//求九个数的中值 uchar Median(uchar n1, uchar n2, uchar n3, uchar n4, uchar n5, uchar n6, uchar n7, uchar n8, uchar n9) { uchar arr[9]; arr[0] = n1; arr[1] = n2; arr[2] = n3; arr[3] = n4; arr[4] = n5; arr[5] = n6; arr[6] = n7; arr[7] = n8; arr[8] = n9; for (int gap = 9 / 2; gap > 0; gap /= 2)//希尔排序 for (int i = gap; i < 9; ++i) for (int j = i - gap; j >= 0 && arr[j] > arr[j + gap]; j -= gap) swap(arr[j], arr[j + gap]); return arr[4];//返回中值 } //图像椒盐化 void salt(Mat &image, int num) { if (!image.data) return;//防止传入空图 int i, j; srand(time(NULL)); for (int x = 0; x < num; ++x) { i = rand() % image.rows; j = rand() % image.cols; image.at 
  
    (i, j)[0] = 255; image.at 
   
     (i, j)[1] = 255; image.at 
    
      (i, j)[2] = 255; } } //中值滤波函数 void MedianFlitering(const Mat &src, Mat &dst) { if (!src.data)return; Mat _dst(src.size(), src.type()); for(int i=0;i 
     
       0 && (i + 1) < src.rows && (j - 1) > 0 && (j + 1) < src.cols) { _dst.at 
      
        (i, j)[0] = Median(src.at 
       
         (i, j)[0], src.at 
        
          (i + 1, j + 1)[0], src.at 
         
           (i + 1, j)[0], src.at 
          
            (i, j + 1)[0], src.at 
           
             (i + 1, j - 1)[0], src.at 
            
              (i - 1, j + 1)[0], src.at 
             
               (i - 1, j)[0], src.at 
              
                (i, j - 1)[0], src.at 
               
                 (i - 1, j - 1)[0]); _dst.at 
                
                  (i, j)[1] = Median(src.at 
                 
                   (i, j)[1], src.at 
                  
                    (i + 1, j + 1)[1], src.at 
                   
                     (i + 1, j)[1], src.at 
                    
                      (i, j + 1)[1], src.at 
                     
                       (i + 1, j - 1)[1], src.at 
                      
                        (i - 1, j + 1)[1], src.at 
                       
                         (i - 1, j)[1], src.at 
                        
                          (i, j - 1)[1], src.at 
                         
                           (i - 1, j - 1)[1]); _dst.at 
                          
                            (i, j)[2] = Median(src.at 
                           
                             (i, j)[2], src.at 
                            
                              (i + 1, j + 1)[2], src.at 
                             
                               (i + 1, j)[2], src.at 
                              
                                (i, j + 1)[2], src.at 
                               
                                 (i + 1, j - 1)[2], src.at 
                                
                                  (i - 1, j + 1)[2], src.at 
                                 
                                   (i - 1, j)[2], src.at 
                                  
                                    (i, j - 1)[2], src.at 
                                   
                                     (i - 1, j - 1)[2]); } else _dst.at 
                                    
                                      (i, j) = src.at 
                                     
                                       (i, j); } _dst.copyTo(dst);//拷贝 } void main() { Mat image = imread("路飞.jpg"); Mat Salt_Image; image.copyTo(Salt_Image); salt(Salt_Image, 3000); Mat image3, image4; MedianFlitering(Salt_Image, image3); medianBlur(Salt_Image, image4, 3); imshow("自定义中值滤波处理后", image3); imshow("openCV自带的中值滤波", image4); waitKey(); } 
                                      
                                     
                                    
                                   
                                  
                                 
                                
                               
                              
                             
                            
                           
                          
                         
                        
                       
                      
                     
                    
                   
                  
                 
                
               
              
             
            
           
          
         
        
       
      
     
    
  

 

效果图:

图像处理:中值滤波&均值滤波图像处理:中值滤波&均值滤波

可以看到,椒盐噪声很好的被平滑了,而且也没均值那样模糊化太过于严重。

三 填充问题

在对图像应用滤波器进行过滤时,边界问题是一个需要处理的问题。一般来说,有3种处理的方法。

1. 不做边界处理

不对图像的边界作任何处理,在对图像进行滤波时,滤波器没有作用到图像的四周,因此图像的四周没有发生改变。

 

2. 填充0

对图像的边界做扩展,在扩展边界中填充0,对于边长为2k+1的方形滤波器,扩展的边界大小为k,若原来的图像为[m, n],则扩展后图像变为[m+2k, n+2k]。进行滤波之后,图像会出现一条黑色的边框。

 

3. 填充最近像素值

扩展与 填充0 的扩展类似,只不过填充0的扩展是在扩展部分填充0,而这个方法是填充距离最近的像素的值。

图像处理:中值滤波&均值滤波图像处理:中值滤波&均值滤波

图像处理:中值滤波&均值滤波

四 总结:

均值滤波和和中值滤波都可以起到平滑图像,虑去噪声的功能。

均值滤波采用线性的方法,平均整个窗口范围内的像素值,均值滤波本身存在着固有的缺陷,即它不能很好地保护图像细节,在图像去噪的同时也破坏了图像的细节部分,从而使图像变得模糊,不能很好地去除噪声点。均值滤波对高斯噪声表现较好,对椒盐噪声表现较差。

中值滤波采用非线性的方法,它在平滑脉冲噪声方面非常有效,同时它可以保护图像尖锐的边缘,选择适当的点来替代污染点的值,所以处理效果好,对椒盐噪声表现较好,对高斯噪声表现较差。

图像处理:中值滤波&均值滤波

参考:

1.均值滤波和中值滤波

https://blog.csdn.net/cjsh_/article/details/

2.

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/201794.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月20日 上午8:36
下一篇 2026年3月20日 上午8:36


相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号