我正在尝试从单个图像进行相机校准和网球场的3D估计。首先,作为预处理,我进行Canny边缘检测,然后应用hoare变换来获取线条。由此我清理图像以获得球场边缘。 。据此,我试图估计球场的3D姿势(可能是在摄像机校准之后)。 opencv中用于相机校准的方法似乎适用于现有模式。据我所知,法院规模是否有任何方法可以从单个图像中获取3D参数?还是可以更轻松地根据平行线计算相应的矩阵?

最佳答案

这是一个尝试...

第1步:我点击了您基本上已经发现的摄像机图像中的“已知”世界点。我在MATLAB中运行ginput,并单击了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');

这是结果图像:

关于java - 使用opencv对网球场进行3D估计,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22921865/

10-12 22:22