undistortFisheyePoints function How does it work?

조회 수: 18(최근 30일)
cui
cui 2022년 6월 29일
답변: cui 2022년 8월 3일
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?

채택된 답변

cui
cui 2022년 8월 3일
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

추가 답변(0개)

Community Treasure Hunt

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

Start Hunting!

Translated by