校准图像以获得位于同一平面上的点的俯视图

时间:2015-12-25 09:51:57

标签: matlab opencv computer-vision camera-calibration matlab-cvst

校准:

我在Matlab中使用这个视觉工具箱校准了相机。我使用棋盘图像来做到这一点。校准后,我得到了cameraParams 其中包含:

Camera Extrinsics
RotationMatrices: [3x3x18 double]
TranslationVectors: [18x3 double]

 Camera Intrinsics
 IntrinsicMatrix: [3x3 double]
 FocalLength: [1.0446e+03 1.0428e+03]
 PrincipalPoint: [604.1474 359.7477]
 Skew: 3.5436

目的: 我使用这台相机记录了一些运动物体的轨迹。每个对象对应于帧中的单个点。现在,我想要投射点,以便我得到一个顶视图。

  1. 请注意我希望转换的所有这些点都在同一个平面上。

    ex:[xcor_i,ycor_i]

    -101.7000  -77.4040
    -102.4200  -77.4040
    
  2. KEYPOINT :此平面垂直于用于校准的棋盘图像之一。对于那张图片(下图),我知道棋盘的起点高度(193.040厘米)。投影点的平面与地面平行并垂直于此图像。
  3. Figure 1

    代码 (参考:https://stackoverflow.com/a/27260492/3646408并在下面的@Dima回答):

    function generate_homographic_matrix()
    %% Calibrate camera
    % Define images to process
    path=['.' filesep 'Images' filesep];
    list_imgs=dir([path '*.jpg']);
    list_imgs_path=strcat(path,{list_imgs.name});
    
    % Detect checkerboards in images
    [imagePoints, boardSize, imagesUsed] = detectCheckerboardPoints(list_imgs_path);
    imageFileNames = list_imgs_path(imagesUsed);
    
    % Generate world coordinates of the corners of the squares
    squareSize = 27;  % in units of 'mm'
    worldPoints = generateCheckerboardPoints(boardSize, squareSize);
    
    % Calibrate the camera
    [cameraParams, imagesUsed, estimationErrors] = estimateCameraParameters(imagePoints, worldPoints, ...
        'EstimateSkew', true, 'EstimateTangentialDistortion', true, ...
        'NumRadialDistortionCoefficients', 3, 'WorldUnits', 'mm');
    %% Compute homography for peripendicular plane to checkerboard
    % Detect the checkerboard 
    im=imread(['.' filesep 'Images' filesep 'exp_19.jpg']); %exp_19.jpg is the checkerboard orthogonal to the floor
    [imagePoints, boardSize] = detectCheckerboardPoints(im);
    
    % Compute rotation and translation of the camera.
    [Rc, Tc] = extrinsics(imagePoints, worldPoints, cameraParams);
    
    % Rc(rotation of the calibration view w.r.t the camera) = [x y z])
    %then the floor has rotation Rf = [z x -y].(Normal vector of the floor goes up.)
    Rf=[Rc(:,3),Rc(:,1),Rc(:,2)*-1];
    
    % Translate it to the floor
    H=452;%distance btw origin and floor
    Fc = Rc * [0; H; 0];
    Tc = Tc + Fc';
    
    % Combine rotation and translation into one matrix:
    Rf(3, :) = Tc;
    
    % Compute the homography between the checkerboard and the image plane:
    H = Rf * cameraParams.IntrinsicMatrix;
    
    save('homographic_matrix.mat','H')
    end
    
    %% Transform points
    function [x_transf,y_transf] =transform_points(xcor_i,ycor_i)
    % creates a projective2D object and then transforms the points forward to
    % get a top-view
    % xcor_i and ycor_i are 1d vectors comprising of the x-coordinates and
    % y-coordinates of trajectories. 
    data=load('homographic_matrix.mat');
    homo_matrix=data.H;
    tform=projective2d(inv(homo_matrix));
    [x_transf,y_transf] = transformPointsForward(tform,xcor_i,ycor_i);
    end
    

    从OReilly Learning OpenCV Pg 412引用文本: "一旦我们按照我们的意愿设置了单应矩阵和高度参数,我们就可以 然后取下棋盘并推动推车,制作鸟瞰视频 路径......" 这就是我基本上希望实现的目标。

2 个答案:

答案 0 :(得分:1)

阿布舍克巴克,

我不完全明白你想要做什么。你的分数是否在飞机上,你是否试图创造一只鸟的眼睛?

如果是这样,那么你需要知道extrinsics,R和t,描述该平面和相机之间的关系。获得R和t的一种方法是在平面上放置一个棋盘,然后使用extrinsics函数。

之后,您可以按照question you cited中的说明进行单应性检查。获得单应性后,您可以创建一个projective2D对象,并使用其transformPointsForward方法转换您的点数。

答案 1 :(得分:0)

由于你在网格上有正方形的大小,然后给出2个你知道通过大小为E的边缘连接的点(以实际单位为单位),你可以计算它们的3D位置。

拍摄相机内在矩阵K和3D位置C以及相机方向矩阵R,您可以通过执行操作计算每个点p的光线:

D = R^T * K^-1 * p

每个3D点定义为:

P = C + t*D

你有||P1-P2|| = E的约束 那就是解决t1,t2并找到两点的3D位置的问题。

为了创建俯视图,您可以拍摄3D点并使用该顶视图的相机模型投影它们以生成新图像。

如果你的所有点都在一个平面上,那么计算3点的位置就足够了,你可以推断其余的点。

如果您的点位于您知道其中一个坐标的平面上,则可以仅为每个点执行此操作。例如,如果您知道您的相机位于高度h=C.z,并且您想要找到框架中点的3D位置,假设它们在地板上(z = 0),那么您只有要做的是如上所述计算方向D,然后:

t=abs( (h-0)/D.z )

0代表飞机的高度。替换其他飞机的任何其他值。

现在您的值为t,您可以计算每个点的3D位置:P=C+t*D

然后,要创建顶视图,请创建新的摄像机位置和旋转以匹配所需的投影,并且可以将每个点投影到此摄像机的图像平面上。 如果需要完整图像,可以插入位置并填充没有特征点的空白。

有关详情,请务必阅读:http://www.robots.ox.ac.uk/~vgg/hzbook/index.html