仅针对所选像素的卷积或针对所选像素的nlfilter()

时间:2015-03-07 13:33:47

标签: performance matlab image-processing filtering convolution

是否存在仅用于进行卷积的内置函数 图像上的像素子集?

基本上,我知道这些点的坐标,我想得到将卷积核应用于这些点的结果。

我想在我的Hessian-Laplace特征检测器的实现中使用它。 我不想构建整个尺度空间立方体,我想将拉普拉斯算子仅应用于Hessian探测器找到的兴趣点。

谢谢。

修改

我正在搜索具有以下签名的函数:

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. 内核矩阵总是大小不均匀。将我们的内核矩阵旋转180度。 (通常如何通过卷积完成)。我们的代码的结果:

     h = [4 5 6;
          0 0 0;
          3 2 1];
    
  2. 我们检查内核是否适合矩阵的所有指定点。否则,我们使用一种可能的填充技术填充矩阵:'零','复制','对称'。填充过程与matlab中的padarray()函数相同。

  3. 将旋转的内核置于原始图像的每个指定点上并计算响应。对所有指定点进行相同的处理。在我们的示例[[2, 2]; [2, 3]]中。每行的第一个数字是行号,第二个是列号。在我们的例子中,它将是数字73或原始矩阵。
  4. 第一个号码的回复是4 + 5*5 + 6*2 + 3*3 + 2*3 + 9 = 65
  5. 我的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
    

    我刚用旋转的内核矩阵应用它。

1 个答案:

答案 0 :(得分: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