Анализ соседей в MATLAB
У меня есть матрица m-by-n с именем A, со значениями 1s и 0s. Я хочу преобразовать все значения 0 в 1, если хотя бы 5 из 8 соседних пикселей равны 1. Я пытался использовать nlfilter
функция, но я не понимаю, как аргумент fun
следует использовать, и мне нужна помощь. Я создал функцию в качестве ручки для nlfilter
следующим образом:
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
Затем я попытался сделать это:
B= nlfilter(A,[3 3],@gap_fill)
Но это дало эту ошибку:
??? Subscripted assignment dimension mismatch.
Error in ==> nlfilter at 75
b(i,j) = feval(fun,x,params{:});
Любое предложение? Основная проблема в том, что я не привык обращаться с функциями.
= ОБНОВЛЕНИЕ =
Я наконец-то придумал хороший результат. Я изменил свою функцию, чтобы вывести скаляр и когда я использую его как fun
спорить nlfilter
это работает так, как я хочу. Это мой код, спасибо за помощь, и я надеюсь, что он может быть полезен для всех:
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
В MATLAB:
b= nlfilter (A,[3 3],'gap_fill')
4 ответа
Вы можете сделать это в одну строку с blockproc
:
B = blockproc(A,[1 1],@(x)sum(x.data(:)),'BorderSize',[1 1],'TrimBorder',0)-A>=5;
Например,
A =
1 0 1 1 0
0 0 0 1 1
1 1 1 1 1
0 1 0 1 1
дает результат
B =
0 0 0 0 0
0 1 1 1 0
0 0 1 1 1
0 0 1 0 0
Обратите внимание, что граничные пиксели изображения обрабатываются правильно, благодаря использованию 'BorderSize'
вариант blockproc
,
Чтобы сохранить оригинальные в A
, применить заключительную операцию "или":
B = B|A;
Я думаю, что это потому, что документация для nlfilter
говорит, что пользовательская функция должна возвращать скаляр, а вы пытаетесь вернуть матрицу.
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.
Для решения, которое немного быстрее, чем blockproc
Вы можете использовать 2D свертку:
mask = ones(3);
mask(5) = 0;
B = conv2(A,mask,'same') >= 5;
Чтобы сделать это еще быстрее (вы заметите это, только если массивы станут больше), вы можете использовать тот факт, что средний фильтр отделим:
B = conv2(conv2(A,ones(1,3),'same'),ones(3,1),'same') - A >= 5;
Функция fun должна возвращать скаляр в вашем случае, она возвращает матрицу. из Matlab
B = nlfilter (A, [mn], fun) применяет функцию fun к каждому скользящему блоку m-by-n изображения в градациях серого A. fun - это функция, которая принимает матрицу m-by-n в качестве входных данных и возвращает скаляр результат.
c = fun(x)
поэтому ваш код должен быть. Есть лучшие способы его кодирования, особенно с помощью amtrix, но по вашему примеру:
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
Извините за ошибку, я изменяю b = 0 на b= A(5)