平均过滤器Matlab

时间:2015-06-24 11:37:05

标签: matlab image-processing

我写了3x3平均滤镜。它工作正常但它显示相同的输出图像三次而不是一次。如何解决问题?

代码是

function [filtr_image] = avgFilter(noisy_image)

    [x,y] = size(noisy_image);
    filtr_image = zeros(x,y);
    for i = 2:x-1
        for j =2:y-1
            sum = 0;
            for k = i-1:i+1
                for l = j-1:j+1
                    sum = sum+noisy_image(k,l);
                end
            end
            filtr_image(i,j) = sum/9.0;
           filtr_image = uint8(filtr_image);

        end
    end

end

提前致谢

2 个答案:

答案 0 :(得分:3)

最有可能发生的事情是,当代码专门用于灰度时,您提供颜色图像。你之所以看到"三"是因为当你这样做分配你的输出过滤图像时:

[x,y] = size(noisy_image)

如果您有3D矩阵,size报告的列数将为y = size(noisy_image,2)*size(noisy_image,3);。因此,当您迭代图像中的每个像素时,按列主要顺序,每个平面将彼此并排放置。您应该做的是将图像从RGB转换为灰度或单独过滤每个平面。

此外,您在循环中执行了不必要的转换。只需在循环外执行一次。

选项#1 - 每个平面过滤

function [filtr_image] = avgFilter(noisy_image)
[x,y,z] = size(noisy_image);
filtr_image = zeros(x,y,z,'uint8');
for a = 1 : z
    for i = 2:x-1
        for j =2:y-1
            sum = 0;
            for k = i-1:i+1
                for l = j-1:j+1
                    sum = sum+noisy_image(k,l,a);
                end
            end
            filtr_image(i,j,a) = sum/9.0;
        end
    end
 end
end

然后你通过以下方式调用它:

filtr_image = avgFilter(noisy_image);

选项#2 - 转换为灰度

filtr_image = avgFilter(rgb2gray(noisy_image));

次要注意事项

您正在使用sum作为变量。 sum是MATLAB中的一个实际函数,你可能会用你的变量掩盖这个函数。如果您有其他功能在以后依赖sum,这将产生意想不到的后果。

答案 1 :(得分:1)

我无法理解为什么你的代码会重复图像(除非它是由整数溢出导致的模式:/)但是这里有一些建议:

如果你想使用循环,至少放弃内部循环:

public void Main()
{
    DefinedInstancesTest dit = new DefinedInstancesTest();
    dit.StaticReadOnlyInstancesAreEnumerated();
}

public abstract class DefinedInstancesBase<T>
{
    public static IList<T> All
    {
        get
        {
            //if (_All == null)
            //    FillAll();
            return _All;
        }
    }

    // correctly named static ctor
    static DefinedInstancesBase() { FillAll(); }

    private static void FillAll()
    {
        Console.WriteLine("FillAll() called...");
        var typeOfT = typeof(T);
        var fields = typeOfT.GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static);
        var fieldsOfTypeT = fields.Where(f => f.FieldType == typeOfT);
        _All = new List<T>();
        foreach (var fieldOfTypeT in fieldsOfTypeT)
        {
            _All.Add((T)fieldOfTypeT.GetValue(null));
        }
    }

    private static List<T> _All = null;
}

//[TestClass]
public class DefinedInstancesTest
{
    //[TestMethod]
    public void StaticReadOnlyInstancesAreEnumerated()
    {
        //Given
        var expectedClasses = new List<TestClass>
        {
            TestClass.First,
            TestClass.Second,
            TestClass.Third,
        };

        //When
        var actualClasses = TestClass.All;

        //Then
        for (var i=0; i<expectedClasses.Count; i++)
        {
            //Assert.AreEqual(expectedClasses[i].Id, actualClasses[i].Id);
            if (expectedClasses[i].Id != actualClasses[i].Id)
              Console.WriteLine("not equal!");
        }
    }

    private class TestClass : DefinedInstancesBase<TestClass>
    {
        public static readonly TestClass First;
        public static readonly TestClass Second;
        public static readonly TestClass Third;

        public int Id { get; private set; }

      static TestClass()
      {
        Console.WriteLine("TestClass() static ctor called...");
        First = new TestClass(1);
        Second = new TestClass(2);
        Third = new TestClass(3);
      }

        private TestClass(int pId)
        {
          Console.WriteLine("TestClass({0}) instance ctor called...", pId);
          Id = pId;
        }
    }
}

TestClass() static ctor called...
// the line "First = new TestClass(1);" now triggers the base class static ctor to be called,
// but the fields First, Second, and Third are all still equal to null at this point!
FillAll() called...
TestClass(1) instance ctor called...
TestClass(2) instance ctor called...
TestClass(3) instance ctor called...
// this null reference exception to be expected because the field value actually was null when FindAll() added it to the list
Unhandled Expecption: 
System.NullReferenceException: Object reference not set to an instance of an object.

但是你知道卷积吗? Matlab具有内置功能:

[x,y] = size(noisy_image);
filtr_image = zeros(x,y);
for i = 2:x-1
    for j =2:y-1
        % // you could do this in 1 line if you use mean2(...) instead
        sub = noisy_image(i-1:i+1, j-1:j+1);
        filtr_image = uint8(mean(sub(:))); 
    end
end