Reputation: 3568
I have an m-by-n matrix named A, with values 1s and 0s. I want to convert all 0s values to 1s if at least 5 out of 8 neighbor pixels are 1s. What I tried is to use the nlfilter
function, but I'm not getting how the arg fun
should be used, and I would need a help.
I created a function as handle for nlfilter
as following:
function b = gap_fill(A)
b=A;
index= A([1 2 3 4 6 7 8 9]);
if sum(index)>=5
b(5)= 1
end
end
Then I tried to do this:
B= nlfilter(A,[3 3],@gap_fill)
But it gave this error:
??? Subscripted assignment dimension mismatch.
Error in ==> nlfilter at 75
b(i,j) = feval(fun,x,params{:});
Any suggestion? The main problem is I'm not used to handle functions.
= UPDATING =
I finally came up with a good result. I changed my function to output a scalar and when I use it as fun
arg in nlfilter
it work the way I want. This is my code, thanks for helping and I hope it could be useful for anybody:
function b = gap_fill(A)
index= A([1 2 3 4 6 7 8 9]);
if sum(index)>=5
A(5)= 1;
end
b=A(5);
end
In MATLAB:
b= nlfilter (A,[3 3],'gap_fill')
Upvotes: 2
Views: 286
Reputation: 112659
You can do it in one line with blockproc
:
B = blockproc(A,[1 1],@(x)sum(x.data(:)),'BorderSize',[1 1],'TrimBorder',0)-A>=5;
For example,
A =
1 0 1 1 0
0 0 0 1 1
1 1 1 1 1
0 1 0 1 1
gives the result
B =
0 0 0 0 0
0 1 1 1 0
0 0 1 1 1
0 0 1 0 0
Note that border pixels of the image are handled correctly, thanks to using the 'BorderSize'
option of blockproc
.
To keep the original ones in A
, apply a final "or" operation:
B = B|A;
Upvotes: 3
Reputation: 11522
The fun function must return an scalar in your case it returns a matrix. from matlab
B = nlfilter(A, [m n], fun) applies the function fun to each m-by-n sliding block of the grayscale image A. fun is a function that accepts an m-by-n matrix as input and returns a scalar result.
c = fun(x)
so your code shoud be There are better ways to code it,specially with amtrix but following your sample:
function b = gap_fill(A)
index= A([1 2 3 4 6 7 8 9]);
if A(5)sum(index)>=5
b = 1;
else
b = A(5);
end
end
Sorry for the error I change b = 0 to b= A(5)
Upvotes: 0
Reputation: 74930
For a solution that's slightly faster than blockproc
, you can use a 2D convolution:
mask = ones(3);
mask(5) = 0;
B = conv2(A,mask,'same') >= 5;
To make this even faster (you'll only notice this if the arrays become larger), you can make use of the fact that an average filter is separable:
B = conv2(conv2(A,ones(1,3),'same'),ones(3,1),'same') - A >= 5;
Upvotes: 1
Reputation: 2204
I think it is because the documentation for nlfilter
says that the user function must return a scalar and you are trying to return a matrix.
B = nlfilter(A, [m n], fun) applies the function fun to each m-by-n sliding block
of the grayscale image A. fun is a function that accepts an m-by-n matrix as input
and returns a scalar (!!!) result.
Upvotes: 2