undistortFisheyePoints function How does it work?

3 views (last 30 days)
How does this function work? According to the documentation, I understand the general process, but I don't know how to convert the distortion points to undistort points step by step, that is, what is the corresponding mapping step? I appreciate your answer.
% documentation EXAMPLE
images = imageDatastore(fullfile(toolboxdir('vision'),'visiondata',...
'calibration','gopro'));
imageFileNames = images.Files;
[imagePoints,boardSize] = detectCheckerboardPoints(imageFileNames);
squareSize = 29; % millimeters
worldPoints = generateCheckerboardPoints(boardSize,squareSize);
I = readimage(images,10);
imageSize = [size(I,1) size(I,2)];
params = estimateFisheyeParameters(imagePoints,worldPoints,imageSize);
points = detectCheckerboardPoints(I);
[undistortedPoints,intrinsics1] = undistortFisheyePoints(points,params.Intrinsics)
undistortedPoints = 54×2
1.0e+03 * 0.9825 0.3005 0.9502 0.4199 0.9150 0.5489 0.8760 0.6901 0.8329 0.8463 0.7843 1.0205 1.1032 0.3635 1.0778 0.4781 1.0500 0.6021 1.0202 0.7366
intrinsics1 =
cameraIntrinsics with properties: FocalLength: [750 750] PrincipalPoint: [1.0005e+03 750.5000] ImageSize: [1500 2000] RadialDistortion: [0 0] TangentialDistortion: [0 0] Skew: 0 IntrinsicMatrix: [3×3 double]
Then i use my undistort Fisheye points mapping step:
uv = params.Intrinsics.StretchMatrix\(points-params.Intrinsics.DistortionCenter)';% Fisheye Camera Model, camera model proposed by Scaramuzza
rho = vecnorm(uv,2,1);
D = params.Intrinsics.MappingCoefficients;
Zc = 1*(D(1)+D(2)*rho.^2+D(3)*rho.^3+D(4)*rho.^4);% lambda = 1 ?
Xc = 1*uv(1,:);Yc = 1*uv(2,:);
myUndistortPts = [Xc./Zc;Yc./Zc]+params.Intrinsics.DistortionCenter'
myUndistortPts = 2×54
1.0e+03 * 1.0058 1.0057 1.0057 1.0057 1.0056 1.0055 1.0060 1.0059 1.0059 1.0058 1.0058 1.0057 1.0061 1.0061 1.0060 1.0060 1.0060 1.0059 1.0062 1.0062 1.0062 1.0062 1.0061 1.0061 1.0063 1.0063 1.0063 1.0063 1.0063 1.0063 0.7424 0.7426 0.7428 0.7430 0.7432 0.7434 0.7425 0.7427 0.7428 0.7430 0.7432 0.7434 0.7426 0.7427 0.7429 0.7431 0.7433 0.7435 0.7427 0.7428 0.7430 0.7431 0.7433 0.7435 0.7427 0.7429 0.7430 0.7432 0.7433 0.7435
undistortedPoints is different from myUndistortPts?

Accepted Answer

cui,xingxing
cui,xingxing on 3 Aug 2022
after i look at undistortFisheyPoints internal implementation and expermient, it turns out the following implementation.
function [undistortedPoints,camIntrinsics] = undistortFisheyePointsFcn(points,...
fisheyeIntrinsicsP,scaleFactor)
% Brief: Removal of image distortion points from the principle by Scaramuzza fisheye camera model
% Details:
% None
%
% Syntax:
% [undistortedPoints,camIntrinsics] = undistortFisheyePointsFcn(points,fisheyeIntrinsicsP,scaleFactor)
%
% Inputs:
% points - [m,n] size,[double] type,Description
% fisheyeIntrinsicsP - [m,n] size,[double] type,Description
% scaleFactor - [m,n] size,[double] type,Description
%
% Outputs:
% undistortedPoints - [m,n] size,[double] type,Description
% camIntrinsics - [m,n] size,[double] type,Description
%
% Example:
% None
%
% See also: None
% Author: cuixingxing
% Email: cuixingxing150@gmail.com
% Created: 03-Aug-2022 08:41:36
% Version history revision notes:
% None
% Implementation In Matlab R2022a
%
arguments
points (:,2) % distort fisheye image points
fisheyeIntrinsicsP (1,1) fisheyeIntrinsics
scaleFactor (1,2) double = [1,1]
end
% Scaramuzza fisheye model
uv = fisheyeIntrinsicsP.StretchMatrix\(points-fisheyeIntrinsicsP.DistortionCenter)';% Fisheye Camera Model, camera model proposed by Scaramuzza
rho = vecnorm(uv,2,1);
D = fisheyeIntrinsicsP.MappingCoefficients;
Zc = D(1)+D(2)*rho.^2+D(3)*rho.^3+D(4)*rho.^4;
Xc = uv(1,:);Yc = uv(2,:);
worldPoints = [Xc;Yc;Zc];
nw = vecnorm(worldPoints,2,1); % lambda
nw(nw == 0) = eps;
uvz = worldPoints ./ [nw;nw;nw];
uvNormal = uvz./uvz(3,:);
% Default to the middle of the original image, which is the same as for
% undistortFisheyeImage. That way, they'll match at least for the 'same'
% output view. It's a more intuitive result.
imageSize = fisheyeIntrinsicsP.ImageSize;
principalPoint = imageSize([2 1]) / 2 + 0.5 ;
f = min(imageSize) / 2;
focalLength = f .* scaleFactor(:)';
camIntrinsics = cameraIntrinsics(focalLength, principalPoint, imageSize);
% camera coordinates to image pixel coordinates
undistortedPoints = camIntrinsics.IntrinsicMatrix'*uvNormal;
undistortedPoints = undistortedPoints(1:2,:)';
end

More Answers (0)

Products


Release

R2022a

Community Treasure Hunt

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

Start Hunting!