2
votes

Background story:

This is an old script, I needed to compare two slightly different images of the same object to get data on the camera itself. I wrote this script in octave and tried it, later I found out matlab ran much faster with it so since than I used matlab instead of octave. I recently decided to check octave again, and I still got 1:1000 speed ratio.

Questions:

  1. How can I vectorize this algorithm?
  2. Does matlab (verses octave) have a way to Auto-vectorize this code to run 1000 times faster - 0.1s verses 100s for color images 420X420 pixels size?

script:

color_depth = 8;
number_of_colors = 3;
number_of_grey_levels = 2^color_depth;
Double_Distribution_0 =zeros(number_of_grey_levels,number_of_grey_levels,number_of_colors);
frame_A = 1+int16(imread('Path\image_A.tif'));
frame_1 = 1+int16(imread('Path\image_1.tif'));
[height,width]=size(frame_A(:,:,1));
number_of_pixels = width*height;

for k = 1:number_of_colors
    tic
    for i = 1:height
        for j = 1:width
                Double_Distribution_0(frame_1(i,j,k),frame_A(i,j,k),k) = 1 + Double_Distribution_0(frame_1(i,j,k),frame_A(i,j,k),k);
        end
    end
   toc
end
3
Have you tried any of the proposed solutions? Feel free to accept an answer if you feel your problem has been solved. - KlausCPH

3 Answers

3
votes

1) Yes, you can vectorize the code as also explained by Shai. However, be aware that his solution is missing the color index on frame_1 and frame_A. This should do the trick:

for k=1:number_of_colors
    f_1 = frame_1(:,:,k);
    f_A = frame_A(:,:,k);
    Double_Distribution_0(:,:,k) = accumarray( {f_1(:), f_A(:)}, 1,...
                                   [number_of_grey_levels, number_of_grey_levels] );

end

2) The reason Matlab is many times faster than Octave it that Matlab has used a JIT compiler to greatly speed up simple for-loops and the like since release 6.5. If you are not familiar with what a JIT is, look here. Last I checked, Octave was still working on their own JIT, but I think it will still be a while :-).

Whether or not your Octave version will benefit from the above code depends on how they wrote it in Octave. I would expect a big benefit.

1
votes

If I understand your code correctly, what it does is building a 2D histogram of the joint color distribution of the two frames.

for k=1:number_of_colors
     Double_Distribution_0(:,:,k) = accumarray( {frame_1(:), frame_A(:)}, 1,...
                               [number_of_grey_levels, number_of_grey_levels] );
end
1
votes

Thanks both of you for your quick response.

Somehow part of the syntax didn't work, but when I shortened it to:

Double_Distribution_0(:,:,k) = accumarray({frame_1(:,:,k),frame_A(:,:,k)},1);

I got what I wanted (compared the results with the old code), in this case the running time in octave is only ~2 times higher than matlab.