2014-01-27 3 views
2

У меня есть матрица m-by-n с именем A со значениями 1 и 0. Я хочу преобразовать все значения 0s в 1s, если по крайней мере 5 из 8 соседних пикселей равны 1 с. Я попытался использовать функцию nlfilter, но я не понимаю, как использовать arg fun, и мне нужна помощь. Я создал функцию, как ручки для nlfilter следующим образом:Анализ соседства в MATLAB

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 arg в 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') 

ответ

2

Я думаю, что это происходит потому, что документация 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. 
3

Вы можете сделать это в одной строке с 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; 
+0

мне нужно, чтобы избежать превращения 1s в 0s, как в B вашего примера – umbe1987

+0

@ umbe1987 Применить окончательную «или» операцию: «B = B | A;» (см. обновленный ответ) –

0

Функция весело должна возвращать скаляр в вашем случае она возвращает матрицу. от 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 

Извините за ошибки меняю Ь = 0 до Ь = А (5)

+0

К сожалению, этот код также преобразует некоторые 1s в 0s, и я должен его избегать. – umbe1987

+0

Да, это правда, я забыл проверить, был ли он уже один, я отредактирую его – anquegi

1

За решение, которое немного быстрее, чем 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; 
Смежные вопросы