2

My brain is hardwired with C++ mindset. Need help vectorizing the following loop.

This code is trying to generate a C++ header that contains an array that maps every pixel location of an distorted image to the undistorted coordinates.

FYI cameraParams and imgIntrinsics are already previously generated by the estimateFisheyeParameters function and undistortFisheyeImage image previously.

fileID = fopen('undistorted.h', 'w');

fprintf(fileID, '#ifndef UNDISTORTED_H\n#define UNDISTORTED_H\n\n');
fprintf(fileID, 'const float distortionFix[%d][%d][2] = {', mrows, ncols);
for y = 1:mrows
    fprintf(fileID, '{');
    for x = 1:ncols
        undistortedPoint = undistortFisheyePoints([x y], cameraParams.Intrinsics);
        undistortedPoint = undistortedPoint - imgIntrinsics.PrincipalPoint;
        fprintf(fileID, '{%f, %f}', undistortedPoint);
        if x < ncols
            fprintf(fileID, ', ');
        end
    end
    if (y < mrows)
        fprintf(fileID, '},\n');
    end
end
fprintf(fileID, '}};\n\n#endif');
tearfur
  • 57
  • 5
  • 2
    Why do you need vectorization here? Does this code take much longer to execute than compiling the resulting header file? – Cris Luengo Aug 08 '19 at 18:29
  • @CrisLuengo It's just a good excercise to get into the matlab mindset, plus I just hate waiting. The task itself is indeed not time-sensitive – tearfur Aug 08 '19 at 21:26

1 Answers1

4

The best place to start would be to recognize that undistortFisheyePoints can accept a matrix of coordinate points, so calling it once with a matrix input will likely be more efficient than calling it repeatedly in a loop. You would just have to create the point matrix (which can be done using repmat and repelem), get your matrix of undistorted points, then subtract imgIntrinsics.PrincipalPoint from each row (either by using implicit expansion, bsxfun, or explicitly replicating it). This can all be done outside the loop, and then you only need one loop to print it all out:

fileID = fopen('undistorted.h', 'w');

fprintf(fileID, '#ifndef UNDISTORTED_H\n#define UNDISTORTED_H\n\n');
fprintf(fileID, 'const float distortionFix[%d][%d][2] = {', mrows, ncols);

points = [repmat((1:ncols).', mrows, 1) repelem((1:mrows).', ncols, 1)];
undistortedPoints = undistortFisheyePoints(points, cameraParams.Intrinsics);
undistortedPoints = bsxfun(@minus, undistortedPoints, imgIntrinsics.PrincipalPoint);

for y = 1:mrows
    fprintf(fileID, '{');
    index = ((y-1)*ncols+1):(y*ncols-1);
    fprintf(fileID, '{%f, %f},', undistortedPoints(index, :).');
    fprintf(fileID, '{%f, %f}', undistortedPoints(y*ncols, :));
    if (y < mrows)
        fprintf(fileID, '},\n');
    end
end
fprintf(fileID, '}};\n\n#endif');
gnovice
  • 125,304
  • 15
  • 256
  • 359