Присвоение одинакового значения соседям

Я пытаюсь присвоить значение, которое чаще повторяется в районе 8x8, как значение всех пикселей в этом районе.

Я сделал вызов следующей функции:

   function ret = spatial_val(x)
       [m,n]=size(x);
       [a,b]=hist(x(:),unique(x));
       most_frequent_value=mode(x(:));
       for i=1:m
           for j=1:n
               x(i,j)=most_frequent_value;
               ret(i,j)=x(i,j);
           end
       end
   end

С использованием:

new_img = nlfilter(img, [8,8], @spatial_val);  

Но я получаю следующую ошибку:

Subscripted assignment dimension mismatch.

Error in nlfilter (line 75)
        b(i,j) = feval(fun,x,params{:});

Error in Fuzzy_CMeans_ali (line 186)
    new_img = nlfilter(img, [8,8], @spatial_val);

Как я могу решить эту проблему?


person Simplicity    schedule 15.05.2013    source источник


Ответы (4)


вам нужна ваша функция для предоставления одного значения, а не матрицы. Также неясно, что является значением по умолчанию, если у вас есть два или более числа, которые чаще всего появляются одинаковое количество раз. Игнорируя пока этот случай, вы можете упростить свою функцию следующим образом:

function ret = spatial_val(x)    
   [a,b]=hist(x(:),unique(x));
   [c ret]=max(a)

переменная ret теперь будет содержать значение, которое является наиболее повторяющимся элементом в блоке nxm, выбранном фильтром.

person Community    schedule 15.05.2013

Я думаю, что вы пытались сделать:

function ret = spatial_val(x)
    ret = ones(size(x))*mode(x(:));
end

РЕДАКТИРОВАТЬ - 1

Все, что вам может понадобиться, может быть на самом деле:

function ret = spatial_val(x)
    ret = uint8(mode(double(x(:))));
end

А потом:

B = nlfilter(lena,[8 8],@spatial_val);
imshow(B);

РЕДАКТИРОВАТЬ - 2

Приведенный ниже код сделает именно то, что вам нужно.

spatial_val.m

function ret = spatial_val(x)
    ret = uint8(ones(size(x))*mode(double(x(:))));
end

main.m

clear;
close;
clc;

lena = imread('lena.jpg');

[m, n] = size(lena);
result = uint8(zeros([m, n]));

window_size = [8, 8];

for ii=1:window_size(1):m
    for jj=1:window_size(2):n
        result(ii:min(ii+window_size(1),m),jj:min(jj+window_size(2),n)) = spatial_val(lena(ii:min(ii+window_size(1),m),jj:min(jj+window_size(2),n)));
    end
end

subplot(1,2,1);
imshow(lena);
subplot(1,2,2);
imshow(result);

Это дает:

введите здесь описание изображения

person Roney Michael    schedule 15.05.2013
comment
Я думаю, вы имеете в виду ret = ones(size(x)) * mode(x(:)); - person anandr; 15.05.2013
comment
@ Рони Майкл. Спасибо за ваш ответ. Итак, дает ли ret = uint8(mode(double(x(:))));) значение mode для всех соседних пикселей? - person Simplicity; 15.05.2013
comment
К сожалению, это не так. Он выполняет ту же операцию для каждого пикселя и его окрестности. Я думаю, что это самое близкое, что вы можете получить с помощью встроенной функции, хотя должно быть достаточно легко написать ее самостоятельно. - person Roney Michael; 15.05.2013

Из документации MatLab (R2011b):

B = nlfilter(A, [m n], fun) применяет функцию fun к каждому скользящему блоку размером m на n изображения в градациях серого A. fun – это функция, которая принимает на вход матрицу размером m на n и возвращает скалярный (!!!) результат.

Ваша функция возвращает матрицу 8x8, а не скаляр.

person anandr    schedule 15.05.2013
comment
Но я думаю, что значение будет применено к center пикселю, но учитывает neighbourhood пиксель. Итак, результат является скаляром? - person Simplicity; 15.05.2013
comment
Да, возвращаемое значение вычисляется из окрестности mxn и будет помещено в центральный пиксель результирующего изображения (центральный пиксель только для нечетных m и n). Решение Roney должно выполнять свою работу. - person anandr; 15.05.2013

Как насчет этого:

im = imread('cameraman.tif');
imp = blockproc(im,[8 8],@(bs) mode(bs.data(:))*ones(size(bs.data),'like',bs.data));
imshow(imp)
person Ashish Uthama    schedule 16.05.2013