Labfans是一个针对大学生、工程师和科研工作者的技术社区。 | 论坛首页 | 联系我们(Contact Us) |
![]() |
![]() |
#1 |
高级会员
注册日期: 2019-11-21
帖子: 3,006
声望力: 66 ![]() |
![]()
假设我们有两个大小相同的数组A和B
现在,我们需要一个过滤器,对于给定的蒙版大小,该过滤器从A选择元素,但删除蒙版的中心元素,然后从B插入对应的元素。 因此3x3的“伪蒙版”将类似于以下内容: AAA ABA AAA 进行平均滤波器这样的事情非常简单。我们可以计算A中没有中心元素的元素的平均值,然后将其与B中元素的适当比例结合起来: h = ones(3,3); h(2,2) =0; h = h/sum(h(:)); A_ave = filter2(h, A); C = (8/9) * A_ave + (1/9) * B; 但如何做中值滤波器(类似的东西medfilt2甚至更好的为ordfilt2 ) 回答: 解决此问题的方法是找到一种方法来组合来自A和B的信息,以便过滤本身变得容易。 我想到的第一件事是沿第三个维度对A和B进行分类,并通过滤镜蒙版,该滤镜蒙版将使用来自“ A切片”的8个元素和来自“ B切片”的中心元素。不幸的是,Matlab不支持此功能。 尽管nlfilter仅适用于2D图像,但它确实允许您指定任何过滤功能。因此,您可以创建一个可以某种方式查找A和B正确值的函数。因此,我想到了第一个解决方案。 创建一个新的数组C,该数组在每个元素处都包含元素索引,即第一个元素为1,第二个元素为2,依此类推。然后,运行nlfilter,它使用3x3滑动窗口并传递C的值在窗口内过滤功能,ffn。 ffn是一个匿名函数,它调用crazyFilter,并且已经初始化,以便A和B在每次调用时都可以通过。 CrazyFunction从C的滑动窗口中获取值,这些值仅是A和B的索引,并从它们中收集A和B的值。 第二种解决方案完全相同,除了创建一个新数组而不是移动滑动窗口,该数组在每一列中的每个可能位置都具有滑动窗口的内容。如果窗口重叠,则列数组将比原始数组大。同样,您只需要使用列数组C的值(它们是A和B的索引),就可以在相关位置查找A和B的值。 编辑如果您有足够的内存,im2col和col2im可以大大加快该过程 %# define A,B A = randn(100); B = rand(100); %# pad A, B - you may want to think about how you want to pad Ap = padarray(A,[1,1]); Bp = padarray(B,[1,1]); #% EITHER -- the more more flexible way %# create a pseudo image that has indices instead of values C = zeros(size(Ap)); C(:) = 1:numel(Ap); %# convert to 'column image', where each column represents a block C = im2col(C,[3,3]); %# read values from A data = Ap(C); %# replace centers with values from B data(5,:) = Bp(C(5,:)); %# OR -- the more efficient way %# reshape A directly into windows and fill in B data = im2col(Ap,[3,3]); data(5,:) = B(:); % median and reshape out = reshape(median(data,1),size(A)); 旧版本(使用较少的内存,可能需要填充) %# define A,B A = randn(100); B = rand(100); %# define the filter function ffun = @(x)crazyFilter(x,A,B); %# create a pseudo image that has indices instead of values C = zeros(size(A)); C(:) = 1:numel(A); %# filter filteredImage = nlfilter(C,[3,3],ffun); %# filter function function out = crazyFilter(input,A,B) %#CRAZYFILTER takes the median of a 3x3 mask defined by input, taking 8 elements from A and 1 from B %# read data from A data = A(input(:)); %# replace center element with value from B data(5) = B(input(5)); %# return the median out = median(data); 更多&回答... |
![]() |
![]() |