Анализ соседей в 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)

Другие вопросы по тегам