校准:
我在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
目的: 我使用这台相机记录了一些运动物体的轨迹。每个对象对应于帧中的单个点。现在,我想要投射点,以便我得到一个顶视图。
请注意我希望转换的所有这些点都在同一个平面上。
ex:[xcor_i,ycor_i]
-101.7000 -77.4040
-102.4200 -77.4040
代码 (参考: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引用文本: "一旦我们按照我们的意愿设置了单应矩阵和高度参数,我们就可以 然后取下棋盘并推动推车,制作鸟瞰视频 路径......" 这就是我基本上希望实现的目标。
答案 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