仅对选定像素进行卷积或对选定像素进行 nlfilter()
Convolution only for selected pixels or nlfilter() for selected pixels
是否有内置函数只对
图像上的像素子集?
基本上,我知道这些点的坐标,我想得到以这些点为中心的卷积核的应用结果。
我想在 Hessian-Laplace 特征检测器的实现中使用它。
我不想构建整个规模 space 立方体,我只想将拉普拉斯算子应用于 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]
以上代码分解:
内核矩阵总是大小不均。将我们的内核矩阵旋转 180 度。 (通常如何用卷积完成)。我们代码的结果:
h = [4 5 6;
0 0 0;
3 2 1];
我们检查内核是否适合矩阵中的所有指定点。否则,我们使用一种可能的填充技术填充我们的矩阵:'zeros'、'replicate'、'symmetric'。填充的过程与matlab中的padarray()
函数完全相同。
- 将旋转内核置于原始图像的每个指定点的中心并计算响应。对所有指定的点以相同的方式进行。在我们的示例中
[[2, 2]; [2, 3]]
。每行的第一个数字是行号,第二个是列号。在我们的例子中,它将是数字 7
和 3
或原始矩阵。
- 第一个数字的响应是
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
我刚刚将它应用于已经旋转的核矩阵。
这是一个函数代码,它对边界周围的点进行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
是否有内置函数只对 图像上的像素子集?
基本上,我知道这些点的坐标,我想得到以这些点为中心的卷积核的应用结果。
我想在 Hessian-Laplace 特征检测器的实现中使用它。 我不想构建整个规模 space 立方体,我只想将拉普拉斯算子应用于 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]
以上代码分解:
内核矩阵总是大小不均。将我们的内核矩阵旋转 180 度。 (通常如何用卷积完成)。我们代码的结果:
h = [4 5 6; 0 0 0; 3 2 1];
我们检查内核是否适合矩阵中的所有指定点。否则,我们使用一种可能的填充技术填充我们的矩阵:'zeros'、'replicate'、'symmetric'。填充的过程与matlab中的
padarray()
函数完全相同。- 将旋转内核置于原始图像的每个指定点的中心并计算响应。对所有指定的点以相同的方式进行。在我们的示例中
[[2, 2]; [2, 3]]
。每行的第一个数字是行号,第二个是列号。在我们的例子中,它将是数字7
和3
或原始矩阵。 - 第一个数字的响应是
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
我刚刚将它应用于已经旋转的核矩阵。
这是一个函数代码,它对边界周围的点进行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