【问题标题】:Matlab Median Filter CodeMatlab中值滤波器代码
【发布时间】:2015-02-16 14:07:16
【问题描述】:

我需要在 MATLAB 中为图像实现中值滤波。但是,我不允许在 MATLAB 中使用 medfilt2 或 ordfilt2 函数。我们最近也开始学习 MATLAB。

是否有可用的中值滤波器或高斯滤波器的代码?

【问题讨论】:

  • 你可以使用nfilter吗?
  • @CapeCode 听起来像是家庭作业,所以可能不会……一定要喜欢那些给我的 coodz 问题……但我很内疚并写下答案。哎呀。这比任何事情都更能锻炼我的编码肌肉

标签: image matlab image-processing filter median


【解决方案1】:

注意:这假设已安装图像处理工具箱。


中值滤波的基本前提是分析图像中的像素邻域,对其强度进行排序,然后选择中间强度作为结果。我可以提出的一个建议是使用 im2col 将每个像素邻域转换为单个 column 向量,并采用所有这些列向量来创建单个矩阵。每列将代表像素邻域内的像素强度。接下来,使用sort 并沿每一列的行排序,然后获取该排序矩阵的middle,它表示每个像素邻域的中间值。这将是一个单行向量,表示每个像素邻域的中值。完成后,只需将此向量重新整形为与原始图像相同的大小,即可获得中值滤波结果。您可以使用col2im 来帮助完成最后一步。

但是,使用im2col,它只抓取原始图像范围内的像素邻域。因为您需要沿图像边界对像素进行中值过滤,所以在使用im2col 处理之前,您需要填充图像边界。使用padarray 为您执行此操作。我将假设边框用零填充以使事情变得更简单。

因此,给定 灰度 图像 im,以及要分析的对称邻域 N x N,其中 N 是您邻域的宽度/高度,您的代码可能类似于这。我还将假设 N 很奇怪,以便更容易选择中位数:

im_pad = padarray(im, [floor(N/2) floor(N/2)]);
im_col = im2col(im_pad, [N N], 'sliding');
sorted_cols = sort(im_col, 1, 'ascend');
med_vector = sorted_cols(floor(N*N/2) + 1, :);
out = col2im(med_vector, [N N], size(im_pad), 'sliding');

让我们举个例子。假设我们的过滤器大小是5 x 5,我们将使用cameraman.tif,它是图像处理工具箱的一部分。如果我们执行下面的代码,然后运行上面刚刚看到的中值滤波器代码:

N = 5;
im = imread('cameraman.tif');

我们得到以下内容,包括原始图像,以及使用中值滤波过滤的最终图像。

这是我们所期望的,因为中值滤波有望(或多或少)在进行图像平滑时保持边缘良好。中值滤波对于椒盐噪声特别有用,因为在对像素邻域进行排序时,这些噪声像素很可能会出现在开头和结尾,因此选择中间值很可能会滤除这些噪声值。


奖金

您的帖子还要求从执行高斯滤波的第一原则中查找代码。几天前我为别人回答了这个问题。

在此处查看此帖子:How do I create and apply a Gaussian filter in MATLAB without using fspecial, imfilter or conv2?

【讨论】:

    【解决方案2】:

    这是我自己编写的代码。我希望它有效。

    clc;
    clear all;
    close all;
    
    A=imread('2.jpg');
    A=rgb2gray(A);
    figure;imshow(A);
    Y=imnoise(A,'salt & pepper',0.5);
    figure;imshow(Y);
    [n,m]=size(A);
    %median filter
    for i=1:n
       for j=1:m
            mat=zeros(3,3);
            if((i-1) == 0 && (j-1) ~= 0 && j~=m)
                mat(2:3,1:3)=Y(i:i+1,j-1:j+1);
                mat=sort(mat,1);
                mat=sort(mat,2);
                Y(i,j)=mat(2,2);
           elseif(i==n && (j-1)~=0 && j~=m)
                mat(1:2,:)=Y(i-1:i,j-1:j+1);
                mat=sort(mat,1);
                mat=sort(mat,2);
                Y(i,j)=mat(2,2);
           elseif((i-1)~=0 &&(j-1)~=0 && j~=m && i~=n)
                mat(:,:)=Y(i-1:i+1,j-1:j+1);
                mat=sort(mat,1);
                mat=sort(mat,2);
                Y(i,j)=mat(2,2);
            elseif((j-1)==0 && (i-1)~=0 && i~=n)
                mat(:,2:3)=Y(i-1:i+1,j:j+1);
                mat=sort(mat,1);
                mat=sort(mat,2);
                Y(i,j)=mat(2,2);
            elseif(j==m && (i-1)~=0 && i~=n)
                mat(:,1:2)=Y(i-1:i+1,j-1:j);
                mat=sort(mat,1);
                mat=sort(mat,2);
                Y(i,j)=mat(2,2);
            end
        end
    end
    
    figure;
    imshow(Y)
    

    【讨论】:

      【解决方案3】:

      我已经写了一个代码,它可能会有所帮助:

      读取图像并为其添加噪声:

      I=imread('cameraman.tif');
      if(size(I,3)~=1)
      I=rgb2gray(I);
      end
      rr=0.1;  
      h=imnoise(I,'salt & pepper',rr);
      imshow(h);
      [M,N]=size(h);
      new=h-h;
      

      询问你需要的内核大小:

      disp('***************Note:zero-padding method is used!***********');
      disp('                                                           ');
      kernel_size=input('enter the size of the kernel for the Median-ranking? 3 or 5 or 7 or 9=  ');
      k=zeros(kernel_size);  %k is the kernel used. 
      

      对图像应用中值过滤器:

      start=kernel_size-floor(kernel_size*0.5);
      for x=start:1:M-floor(kernel_size*0.5)
      for y=start:1:N-floor(kernel_size*0.5)
      
      %defining x1 & y1 as the 1st coordinates in the kernel
      x1=x-(floor(kernel_size*0.5));
      y1=y-(floor(kernel_size*0.5));
      
      %specifying image pixels to the kernel
      for p=1:1:kernel_size
      for q=1:1:kernel_size
       k(p,q)=h(x1+p-1,y1+q-1);
      end    
      end
      d=reshape(k,1,[]);  %k values into an array d 
      [r,c]=size(d);
      %*****Ordering kernel members***************
      for j=1:1:c-1
      for i=1:1:c-1
          a=d(1,i);
          b=d(1,i+1);
          if(a>b)
           d(1,i)=b;
           d(1,i+1)=a;
          end
      end  
      end
      Median=d(1,floor(kernel_size*kernel_size*0.5)+1);
        %*****************end of ordering***********
        %*******************************************
      
         new(x,y)=Median;    
      end
      end
      

      显示结果:

      figure;imshow(new,[]);
      

      【讨论】:

        【解决方案4】:

        我告诉你如何开始你的任务。你只需要建立一个sorting algorithm,然后拿起中心值。很大一部分是实现排序算法。其中一些:

        • 桶排序
        • 列表项
        • 冒泡排序
        • 插入排序
        • 选择排序
        • 堆排序
        • 合并排序

        它们并不难理解和编写你自己的。你可以很容易地找到已经写好的。输入您的搜索引擎sorting algorithms matlab。你说I'm looking for the code of the Built-in function of median filter in Matlab. Matlab 允许看到meddilt2() 和ordfilt2() 的源代码,你可以看到这些函数的代码,但是记住版权规则。

        实现排序算法后,您可以通过写mask( ( numel(mask) + 1 ) / 2 )轻松选择过滤器掩码的中心值。

        就是这样。

        如果您正在寻找从头开始为您的任务编写完整解决方案的人,您将面临艰巨的工作。

        祝你好运。


        中值滤波有两个 MATLAB 内置函数:medfilt2() 和 ordfilt2()。实际上medfilt2() 在其体内调用ordfilt2()。因为中值过滤是排序过滤的特例。

        【讨论】:

        • 我知道这些函数,但我需要中值滤波器的代码或至少是算法
        • @mehmet - 我从头开始写了一个,但我不需要做太多工作。这只是对我之前的一篇文章的修改,但额外的要求是对强度进行排序并选择中间。我可能不应该写答案,但我这样做主要是为了进行心理锻炼。
        • @rayryeng - 没问题,没关系;)
        猜你喜欢
        • 1970-01-01
        • 2011-10-02
        • 1970-01-01
        • 2015-07-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-08-05
        • 2013-02-25
        相关资源
        最近更新 更多