2

Есть ли встроенная функция для свертки только для подмножества пикселей на изображении?Свертка только для выбранных пикселей или nlfilter() для выбранных пикселей

В принципе, я знаю координаты этих точек, и хочу получить результаты применения сверточного ядра, центрированного в этих точках.

Я хочу использовать его в своей реализации детектора функции Hessian-Laplace. Я не хочу строить весь куб пространства масштаба, я хочу применить лапласиан только к интересующим точкам, найденным детектором Гессиана.

Спасибо.

Edit:

Я ищу функцию, которая будет иметь следующий вид:

function [ results ] = selected_conv(input_matrix, ... 
coords, kernel, border_treatment_mode) 

Пример использования:

% define the kernel and the input image 
h = [1 2 3; 
    0 0 0; 
    6 5 4]; 
I = [1 5 2 3; 
    8 7 3 6; 
    3 3 9 1] 

% Points coordinates in original image to convolve. 
points_coords_to_convolve = [[2, 2]; [2, 3]]; 
% The third parameter is a parameter like for padarray(): 'zeros', 'replicate', 'symmetric'. 
result = selected_conv(I, h, 'zeros') 

Выход:

[65, 76] 

ломка кода выше:

  1. Kernel матрица всегда неравномерного размера. Поверните нашу матрицу ядра на 180 градусов. (Как это обычно делается с сверткой). Результат для нашего кода:

    h = [4 5 6; 
         0 0 0; 
         3 2 1]; 
    
  2. Мы проверяем, если для всех указанных точек ядро ​​помещается в матрицу. В противном случае мы накладываем нашу матрицу на один из возможных методов заполнения: «нули», «репликация», «симметричность». Процесс заполнения идентичен функции padarray() в Matlab.

  3. Центрируйте повернутое ядро ​​на каждой из указанных точек исходного изображения и вычисляйте ответ. Выполните то же самое для всех указанных точек. В нашем примере [[2, 2]; [2, 3]]. Первое число каждой строки - это номер строки, а второй номер столбца. В нашем случае это будут номера 7 и 3 или оригинальная матрица.
  4. Ответ на первый номер: 4 + 5*5 + 6*2 + 3*3 + 2*3 + 9 = 65.

Мой код nlfileter():

function [ results ] = selected_nlfilter(input_matrix, coords, ... 
func_handler, sliding_window_size, border_treatment_mode) 

    Kernel_x = sliding_window_size(1); 
    Kernel_y = sliding_window_size(2); 

    pad_row = floor(Kernel_x/2); 
    pad_col = floor(Kernel_y/2); 

    padded_matrix = pad_matrix(input_matrix, pad_row, pad_col, border_treatment_mode); 

    results = zeros(size(coords, 1), 1, 'double'); 

    amount_of_coords = size(coords, 1); 

    for coord_count = 1:amount_of_coords 

     row = coords(coord_count, 1); 
     col = coords(coord_count, 2); 

     frame = padded_matrix(row:row+(2*pad_row),col:col+(2*pad_col)); 

     sliding_window_size; 
     results(coord_count) = func_handler(frame); 

    end 
    end 

Я просто применил его с уже повернуты матрицу ядра.

+0

Покажите свой код о том, как вы будете использовать на нескольких p oints? – Divakar

+0

@ Дивакар, вам нужна подпись или конкретный прецедент? – warmspringwinds

+0

Используйте некоторые примеры минимальных данных входного изображения, массив точек, образец ядра и покажите желаемый результат. Объясните, как это должно вести себя вокруг границ. Было бы неплохо увидеть, что они затронуты в вопросе. – Divakar

ответ

1

Это функциональный код, который делает zero-padding для точек вокруг границ и достигает "selective convolution" -

function out = selected_conv(I,pts,h) 

%// Parameters 
hsz = size(h); 
bxr = (hsz-1)/2; 
Isz = size(I); 

%// Get padding lengths across all 4 sides 
low_padlens = max(bsxfun(@minus,bxr+1,pts),[],1); 
low_padlens = (low_padlens + abs(low_padlens))./2; 
high_padlens = bxr - min(bsxfun(@minus,Isz,pts),[],1); 
high_padlens = (high_padlens + abs(high_padlens))./2; 

%// Get zeros padded array 
Ip = zeros(Isz + high_padlens + low_padlens); 
Ip(low_padlens(1)+1:Isz(1)+low_padlens(1),... 
    low_padlens(2)+1:Isz(2)+low_padlens(2)) = I; 

pts = bsxfun(@plus,pts,low_padlens); %// modified points based on padding 

lin_idx = sub2ind(size(Ip),pts(:,1),pts(:,2)); %//'#linear indices of points 

%// Calculate neighborhood offsets and then the actual neighboring elements 
off1 = bsxfun(@plus,[-bxr(1):bxr(1)]',[-bxr(2):bxr(2)]*size(Ip,1)); %//' 
all_idx = bsxfun(@plus,off1(:),lin_idx(:).'); %//'# all neighbouring indices 
vals = Ip(all_idx); %// all neighbouring elements 
out = h(:).'*vals; %//'# Finally get the weighted output 

return; 

Пример Использование

h = [4 5 6; 
    0 0 0; 
    3 2 1]; 
I = [1 5 2 3; 
    8 7 3 6; 
    3 3 9 1] 

pts = [[2, 2]; [2, 3]] 

out = selected_conv(I,pts,h) 

Выходной -

out = 
    65 76 
Смежные вопросы