# Index information for conv2(.,.)

3 views (last 30 days)
820408 on 26 Oct 2016
Edited: Andrei Bobrov on 27 Oct 2016
I have an image X (dimension N1xN2) and a filter Y(dimension 3x5). I can use matlab command conv2(X,Y) to get the filtered image Z. Now I want to get another matrix Z_Index of dimension (N1N2 x 15). The kth row of Z_index(k,:) should contain linear index information of those x's that contributed in kth element of Z. How can I get such a matrix?

Guillaume on 26 Oct 2016
One possible way:
indices = reshape(1:numel(X), size(X));
usedindices = nlfilter(indices, size(Y), @(idx) {idx(:)});
Z = [usedindices{:}]'
You get 0 for those k indices near the edges due to the zero padding.
##### 2 CommentsShowHide 1 older comment
Guillaume on 27 Oct 2016
nlfilter works exactly the same as conv2 (with the 'full' option|) except that you specify the function that is to operate on the sliding block. In fact you could replicate conv2 with the function @(block) sum(sum(block .* Y)).
In this case, instead of filtering the original image, I filter the indices of the image pixel. nlfilter slides blocks of size size(Y) over the image and pass these pixels (in this case whose value is their indices) as a matrix to the filtering function I specify. That function is very simple, simply reshape that matrix of indices into a single column and pack it up into a scalar cell array. It needs to be put into a scalar cell array because nlfilter expect a scalar value back from the filtering function.
nlfilter combines all these scalar into a matrix but since I returned scalar cell arrays that combined matrix is actually a cell array containing column vectors. The next line simply concatenate all these column vectors into one matrix and transpose to get the orientation you wanted.
You could do the same with a loop which may be faster as nlfilter is not particularly fast. nlfilter just abstracts away the complexity of the loop.

Andrei Bobrov on 27 Oct 2016
Edited: Andrei Bobrov on 27 Oct 2016
Without Image Processing ...
m = 3;
n = 5;
A = reshape(1:numel(X),size(X));
[k,l] = size(A);
s = floor([m,n]/2)
B = zeros(size(A)+s*2);
B(s(1)+1:end-s(1),s(2)+1:end-s(2)) = A;
C = reshape(1:numel(B),size(B))
D = C(1:end-m+1,1:end-n+1);
[x,y] = size(C);
M = bsxfun(@plus,(0:m-1)',(0:n-1)*x);
out = B(bsxfun(@plus,D(:),M(:)'));
with Image Processing