如何找到两组点之间的径向畸变系数?

时间:2017-05-18 16:07:56

标签: matlab computer-vision

标题更改为:使用棋盘坐标的图像的特定转换/失真

我有两张棋盘图片。其中一个比另一个略扭曲。我认为它是一种"桶"失真。我试图计算径向失真参数(或生成相机参数),以便将其中一个图像扭曲成另一个图像,这样棋盘角就会排成一行。

这是二进制无失真图像,其角点用蓝色o和#和我们需要扭曲图像的角落的参考坐标绘制成红色o' s。

enter image description here

大部分失真发生在边缘和角落周围。我相信这是一种径向扭曲。如何找到代表棋盘角的两组坐标之间的径向畸变系数?

链接到图像A(未失真):http://imgur.com/rg4PNvp

链接到图像B(失真):http://imgur.com/a/BIvid

我需要从图像B转换棋盘,使其角与图像A的角对齐。

我尝试修改MATLAB Camera Calibration应用程序生成的脚本(link)。我改变了用于估计相机参数的世界点,使其等于图像A中的世界点(角点)。但是,这并不成功。我尝试的代码可以在这个pastebin中看到:https://pastebin.com/D0StCb0p我在imageFileNames中使用了相同的图像,因为estimateCameraParameters需要至少2组坐标。

代码:

% Define images to process
imageFileNames = {'C:\Users\asavelyev\Pictures\checkerB.tif',...
    'C:\Users\asavelyev\Pictures\checkerB.tif',...
    };

% Detect checkerboards in images
[imagePoints, boardSize, imagesUsed] = detectCheckerboardPoints(imageFileNames);
imageFileNames = imageFileNames(imagesUsed);

% Read the first image to obtain image size
originalImage = imread(imageFileNames{1});
[mrows, ncols, ~] = size(originalImage);

% AS: change these worldPoints to points of RGB image...
% Generate world coordinates of the corners of the squares
worldPoints = detectCheckerboardPoints('C:\Users\asavelyev\Pictures\checkerA.tif');

% Calibrate the camera
[cameraParams, imagesUsed, estimationErrors] = estimateCameraParameters(imagePoints, worldPoints, ...
    'EstimateSkew', false, 'EstimateTangentialDistortion', false, ...
    'NumRadialDistortionCoefficients', 2, 'WorldUnits', 'millimeters', ...
    'InitialIntrinsicMatrix', [], 'InitialRadialDistortion', [], ...
    'ImageSize', [mrows, ncols]);

% For example, you can use the calibration data to remove effects of lens distortion.
undistortedImage = undistortImage(originalImage, cameraParams);

1 个答案:

答案 0 :(得分:1)

使用数学StackOverflow中的这篇文章解决了这个问题:https://math.stackexchange.com/questions/302093/how-to-calculate-the-lens-distortion-coefficients-with-a-known-displacement-vect

我监督的主要问题是用于计算径向失真中使用的K系数的数据点的标准化。

这是我为寻找这些系数而编写的MATLAB脚本:

% input images should be black and white checkerboards already thresholded into a binary image
% output image are the K coefficients used in radial distortion

function K = CalculateRadialDistortion(DistortedImg, UndistortedImg)

    distortedCorners = detectCheckerboardPoints(DistortedImg);
    undistortedCorners = detectCheckerboardPoints(UndistortedImg);

    % normalize data
    X1 = distortedCorners(:,1) - size(DistortedImg, 2)/2;
    Y1 = distortedCorners(:,2) - size(DistortedImg, 1)/2;

    X1p = undistortedCorners(:,1) - size(DistortedImg, 2)/2;
    Y1p = undistortedCorners(:,2) - size(DistortedImg, 1)/2;

    % X1p = (1+k1*r^2 + k2*r^4)X1 where r^2 = X1^2 + Y1^2

    Rsq =  X1.^2 + Y1.^2;
    Rquad = Rsq.^2;

    Rsqd = cat(1, Rsq, Rsq);
    Rquadd = cat(1, Rquad, Rquad);

    R = cat(2, Rsqd, Rquadd);

    X1poX1 = X1p ./ X1;
    X1poX1 = X1poX1 - 1;

    Y1poY1 = Y1p ./ Y1;
    Y1poY1 = Y1poY1 - 1;

    X1Y1 = cat(1, X1poX1, Y1poY1);

    K = linsolve(R, X1Y1);

end