我正在尝试从单个图像进行相机校准和网球场的3D估计。首先作为预处理,我做了边缘检测,然后应用hoare变换来获取线条。从这里我清理图像,以获得球场边缘。 。由此我试图估计球场的3D姿势(可能是在相机校准后)。 opencv中的摄像机校准方法似乎适用于预先存在的模式。据我所知,法院尺寸是否有任何方法可以从单个图像中获取3D参数?或者我们可以更容易地从平行线计算相应的矩阵吗?
答案 0 :(得分:1)
这是一次尝试......
第1步:我点击"已知"您基本上已经找到的相机图像中的世界点。我在MATLAB中运行了ginput
并点击了可以从你的Hough线中导出的14个点交叉点。以下是这些点,以像素为单位(您可以将它们绘制在原始图像的上方以查看它们的位置):
x = [
161 118
193 119
382 116
412 116
181 149
288 147
393 146
134 268
287 266
440 266
36 358
98 358
473 352
535 353
]';
步骤2:我计算了相应的世界点,将球场的左上角视为原点(0,0,0)并向下和向右增加。由于球场是一架飞机,每个点的Z坐标都等于0。以下是这些点,以英尺为单位:
y = [
0 0 0
4.5 0 0
31.5 0 0
36 0 0
4.5 18 0
18 18 0
31.5 18 0
4.5 60 0
18 60 0
31.5 60 0
0 78 0
4.5 78 0
31.5 78 0
36 78 0
]';
步骤3:我们现在在摄像机点和世界点之间有一堆对应关系。我使用相机校准工具箱来获取相机的外在和内在参数。请注意,由于我们的对应关系很少,所以我跳过了失真参数和宽高比的计算(无论如何都应该非常接近1.0)。此处生成的图像显示了映射到图像的原始世界点,仅给出校准信息。我们可以看到校准是有效的,因为所有世界点都非常接近地映射到图像中的正确位置。
这是最终的代码:
clc;
clear all;
img = imread('HSY1A.jpg');
nx = size(img,2);
ny = size(img,1);
% imshow(img,[]);
x = [
161 118
193 119
382 116
412 116
181 149
288 147
393 146
134 268
287 266
440 266
36 358
98 358
473 352
535 353
]';
y = [
0 0 0
4.5 0 0
31.5 0 0
36 0 0
4.5 18 0
18 18 0
31.5 18 0
4.5 60 0
18 60 0
31.5 60 0
0 78 0
4.5 78 0
31.5 78 0
36 78 0
]';
num_pts = size(y,2);
% Required by camera calibration toolbox
x_1 = x;
X_1 = y;
% Setting up calibration parameters
n_ima = 1;
est_aspect_ratio = 0;
est_dist = zeros(5,1);
% check_cond = 0;
% Run calibration
go_calib_optim;
%% Estimate original points
est_x_1 = KK * [Rc_1 Tc_1] * [X_1; ones(1, size(X_1,2))];
est_x_1 = est_x_1 ./ repmat(est_x_1(3,:),3,1);
%% Plot results
imshow(img,[]); hold on;
plot(est_x_1(1,:),est_x_1(2,:),'gs');
以下是产生的图片: