我写了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
提前致谢
答案 0 :(得分:3)
最有可能发生的事情是,当代码专门用于灰度时,您提供颜色图像。你之所以看到"三"是因为当你这样做分配你的输出过滤图像时:
[x,y] = size(noisy_image)
如果您有3D矩阵,size
报告的列数将为y = size(noisy_image,2)*size(noisy_image,3);
。因此,当您迭代图像中的每个像素时,按列主要顺序,每个平面将彼此并排放置。您应该做的是将图像从RGB转换为灰度或单独过滤每个平面。
此外,您在循环中执行了不必要的转换。只需在循环外执行一次。
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);
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