校准:
我已经在Matlab中使用此视觉工具箱对相机进行了校准。我使用了棋盘图像。校准后我得到了相机参数
其中包含:
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
目标:
我已经用这台摄像机记录了一些运动物体的轨迹。每个对象对应于框架中的单个点。现在,我要对这些点进行投影,以便获得顶视图。
请注意,我希望变换的所有这些点都在同一平面上。
例如:[xcor_i,ycor_i]
-101.7000 -77.4040
-102.4200 -77.4040
要点:此平面垂直于用于校准的棋盘图像之一。对于该图像(下图),我知道棋盘格离地面的高度(193.040厘米)。投影点的平面平行于地面并垂直于该图像。
码
(参考: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中的文本:
"一旦我们有了单应性矩阵和高度参数集,就可以
然后移开棋盘并开着手推车,制作鸟瞰视频
的道路..."
这是我本质上希望实现的。
如果您没有有关这些点的任何深度信息,或有关该对象或场景的其他3D信息,则相机校准不足以将图像中的2D点转换为精确的3D。您只能将它们放在3D射线上。
@Photon我不想将它们转换为3D。我仍然只希望从顶部观察2D点。
两者在数学上是等效的。
@photon stackoverflow.com/questions/15768651/我的问题比较容易,因为我只需要生成像素坐标而不是图像的鸟瞰图
在该链接中,额外信息是网格对象上正方形的大小。就像我之前说的,如果您有关于尺寸的信息,则可以解决它,但不能解决图像中的一般情况。
我确实有关于正方形大小的信息。我采用的校准与vision.caltech.edu/bouguetj/calib_doc/htmls/example.html中提到的完全相同。
@Photon您能在这里说明您所指场景的其他3D信息吗?
一个示例是有关对象大小的知识,该知识限制了点之间的3D距离。另一个示例是,如果您知道这些点位于约束一个坐标的某个平面(例如地板)上。
阿比舍克
我不完全了解您要做什么。您的观点是否在飞机上,并且您正在尝试创建该飞机的鸟瞰图?
如果是这样,则您需要了解描述该平面与相机之间关系的外部特性R和t。获取R和t的一种方法是将棋盘格放在飞机上,然后使用extrinsics函数。
之后,您可以按照所引问题中的说明获得单应性。一旦有了单应性,就可以创建一个projective2D对象,并使用其transformPointsForward方法转换点。
感谢您的回答。我现在在问题中添加了更多信息。请检查问题中的New info。
好的,这意味着您知道从摄像机坐标到棋盘格坐标的转换:R1,t1。您还应该能够找出棋盘格和垂直平面之间的变换:R2,t2。您需要在该平面上选择一个点作为原点。现在,您可以结合这两个变换来获得R3,t3,即从摄像机到感兴趣平面的变换。
您能否提供有关每个步骤的信息。一些代码/伪代码是极大的赞赏。对不起,我是新手。请更新您的答案。
感谢您的评论。你能告诉我如何计算R2,t2。
在问题中使用变量进行转换的更多详细信息将非常有用。请尽可能这样做。
如果可能,请检查编辑2。谢谢。请详细说明"您还应该能够确定棋盘格和垂直平面之间的转换:R2,t2。您需要在该平面上选择一个点作为原点。现在,您可以将两个转换结合起来得到"。
能否请您回复。
抱歉,计算出准确的数学需要时间,这是我目前没有的。您当前的坐标系将棋盘格作为其X-Y平面。您的新坐标系X-Y平面垂直于当前坐标系。您需要绕Y轴旋转90度,然后沿Z轴平移。检查Wikipedia上的"旋转矩阵"。
请检查一次Edit 1中的Code,以确认是否存在任何问题。谢谢!
糟糕...。是的,大约是x。
由于您在网格上具有正方形的大小,因此给定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
t在这里是什么?
它沿着射线到点的距离。
您能告诉我如何在上述工具中获得上述参数。校准后,我得到以下信息:focal Length: fc = [ 1017.46736 1014.02509 ] +- [ 21.95105 22.41464 ] Principal point: cc = [ 639.50000 359.50000 ] +- [ 0.00000 0.00000 ] Skew: alpha_c = [ 0.00000 ] +- [ 0.00000 ] => angle of pixel axes = 90.00000 +- 0.00000 degrees Distortion: kc = [ 0.07903 -0.04146 -0.00481 -0.01371 0.00000 ] +- [ 0.02762 0.03850 0.00213 0.00562 0.00000 ] Pixel error: err = [ 0.06366 0.07012 ]
那里的值仅指定摄像机固有校准(K),即[fc(1)0 cc(1); 0 fc(2)cc(2); 0 0 1]。您还需要获取/计算相机的位置和方向
感谢您的持续帮助!您是指相机在现实世界中的位置以及它在不同轴上的角度。尊重,我应该衡量这些吗?
如果要计算点在世界上的3D位置,则需要这些,这对于计算顶视图是必需的。
我的相机位置为C(x,y,z)。您能告诉我们如何定义相机的方向吗?
试试这个链接:en.wikipedia.org/wiki/Camera_resectioning#Extrinsic_parameters如果您搜索的话,还有更多在线资源。
我对问题做了一些修改,使其更加清楚。请看一看。
感谢您的回答。我现在在问题中添加了更多信息。请检查问题中的新信息。
请尽可能检查更新后的问题。如果可能,请更新您的答案。
添加了处理水平面的示例
请检查Edit 1。
能否请您回复。
我添加了处理水平面的描述。我不会在这里写代码。