MATLAB Answers

How to vectorize the following for...loop?

2 views (last 30 days)
Baraka Maiseli
Baraka Maiseli on 9 Apr 2016
Commented: Kuifeng on 10 Apr 2016
Dear colleagues,
I have written the following MATLAB code, with two for...loops, which compute the distance map of an image. However, the code is relatively slower, and I want to speed it up using vectorization techniques. I am still a newbie in code optimization; still learning. Any idea on how to vectorize the code, please share:
function [ res ] = computeDT( v, d1, d2 )
%%COMPUTEDT -- Compute the distance field of an input image, img
% v -- Input image
% res -- Output image
%%%%%%%Initialize the input image
v = v([1,1:end,end],[1,1:end,end]);
v(v~=0) = inf;
% Weights [0 +d1 +d2]
%%Forward pass
M1 = size(v,2); % Number of columns
M2 = size(v,1); % Number of lines (rows)
for k1=2:M1-1
for k2=2:M2-1
v(k1,k2) = min([v(k1 - 1, k2 - 1) + d2, v(k1 - 1, k2) + d1,...
v(k1 - 1, k2 + 1) + d2, v(k1, k2 - 1) + d1, v(k1, k2)]);
end
end
%%Backward pass
for k1=M1-1:-1:2
for k2=M2-1:-1:2
v(k1,k2) = min([v(k1, k2), v(k1, k2 + 1) + d1, v(k1 + 1, k2 - 1) + d2,...
v(k1 + 1, k2) + d1, v(k1 + 1, k2 + 1) + d2]);
end
end
res = v(2:end-1,2:end-1);
% save res.mat
% subimage(mat2gray(res))
end

  1 Comment

Kuifeng
Kuifeng on 10 Apr 2016
can you give an example value/matrix of v, d1, d2?

Sign in to comment.

Answers (1)

Kuifeng
Kuifeng on 9 Apr 2016
% maybe make some changes to the following code could help,
[rows cols] = size(ans);
v1 = v(1:rows-1, 1:cols-1);
v2 = v(2:rows, 1:cols-1);
v3 = v(1:rows-1, 2:cols);
v4 = v(2:rows, 2:cols);
result = min[v1+d1, v2+d2, v3, v4, v5]; %for example only, revise accordingly

  3 Comments

Baraka Maiseli
Baraka Maiseli on 9 Apr 2016
Thank you Kuifeng for the response. I am trying to make the code snippet above working. I have embedded it in the original code, and did a little modifications to suit my needs, but still the results are not the ones I expect. Considering just the "Forward pass" (please see comments in the original code), I have adopted your recommendation as follows:
result = min([v1(1:rows - 2, 1:cols - 2) + d2, v1(1:rows - 2, 2:cols - 1) + d1, v1(1:rows - 2, 3:cols) + d2, v1(2:rows - 1, 1:cols - 2) + d1, v1(2:rows - 1, 2:cols - 1)]);
But, this provides a wrong answer. I still don't understand where the mistakes are.
Kuifeng
Kuifeng on 9 Apr 2016
%for example in the 'forward pass',
[rows cols] = size(v);
v1 = v(1:rows-2, 1:cols-2);
v2 = v(1:rows-2, 2:cols-1);
v3 = v(1:rows-2, 3:cols);
v4 = v(2:rows-1, 1:cols-2);
v5 = v(2:rows-1, 2:cols-1);
result = min(min(min(min(v1 + d2, ...
v2 + d1), ...
v3 + d2), ...
v4 + d1), ...
v5);
Baraka Maiseli
Baraka Maiseli on 9 Apr 2016
Testing the code snippet (for the forward pass), as it is, I get:
Inf Inf Inf Inf Inf Inf Inf
Inf Inf Inf Inf Inf Inf Inf
Inf Inf Inf Inf Inf Inf Inf
Inf Inf Inf 0 1 Inf Inf
Inf Inf Inf 1 Inf Inf Inf
Inf Inf Inf Inf Inf Inf Inf
Inf Inf Inf Inf Inf Inf Inf
But the old code, which I use as reference, gives:
Inf Inf Inf Inf Inf Inf Inf Inf Inf
Inf Inf Inf Inf Inf Inf Inf Inf Inf
Inf Inf Inf Inf Inf Inf Inf Inf Inf
Inf Inf Inf Inf Inf Inf Inf Inf Inf
Inf Inf Inf Inf 0 1 2 3 Inf
Inf Inf Inf Inf 1 2 3 4 Inf
Inf Inf Inf Inf 2 3 4 5 Inf
Inf Inf Inf Inf 3 4 5 6 Inf
Inf Inf Inf Inf Inf Inf Inf Inf Inf
The two implementations produce different results.

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!