我使用棋盘格使用 MATLAB 的相机校准器应用程序校准了单色相机。 由此,我得到了保存在calibrationSession
中的所有相机参数。
我用同一台相机拍了一个物体(sceneImage
)的照片。 我还有一张普通图片,仅显示没有任何旋转的对象(objImage
)。 我知道物体的真实宽度和高度。
使用SURF特征检测器,我提取了其中的特征并匹配了它们。
现在我想猜测/计算物体的 6-D 位置,我知道它的特征,在我用校准相机拍摄的照片中。
到目前为止,还有我的 MATLAB 代码:
% IMPORTS
model = imread('model.png');
scene = imread('scene.png');
load('calibrationSession');
% IMG PREP
cameraParams = calibrationSession.CameraParameters;
objImage = rgb2gray(model);
[sceneImage, newOrigin] = undistortImage(rgb2gray(scene),cameraParams);
I1 = sceneImage;
I2 = objImage;
% DETECTION
points1 = detectSURFFeatures(I1);
[features1, valid_points1] = extractFeatures(I1, points1);
points2 = detectSURFFeatures(I2);
[features2, valid_points2] = extractFeatures(I2, points2);
[indexPairs,matchmetric] = matchFeatures(features1,features2);
matchedPoints1 = valid_points1(indexPairs(:,1),:);
matchedPoints2 = valid_points2(indexPairs(:,2),:);
% LOCATION
objwidth = 126;
objheight = size(I2,2)*objwidth/size(I2,1);
您的问题没有准确描述相机/物体运动的类型,所以我只是假设相机的移动足以让我们有一个基线(估计深度)。然后,我们首先假设对象是静态的。在这种情况下,我建议您首先尝试更经典的方法:首先计算拍摄图像的两个瞬间之间的相对运动,即两个相机之间的相对运动。如果你的特征正确匹配,这可以通过计算基本矩阵轻松完成(请参阅此 matlab 指南。我个人更喜欢本文的方法,但实施需要时间)。一旦你有了基本矩阵,你就可以很容易地以旋转和平移(即[R|T]
)矩阵的形式提取相对运动。现在,您可以对特征点进行三角测量并获得稀疏的 3D 地图。但是,您的T
只会在比例下知道,因此,您对对象大小和位置的估计也是如此。
这就是您想要开始利用您对对象宽度和高度的了解的地方。如果物体很简单(即立方体),并且运动不太剧烈(例如没有颠倒等),那么您可以从中推断出比例。例如,在立方体的情况下,假设您的第一个图像只是一个面部视图,即图像看起来像
A ----- B
| |
| |
C-------D
现在,您已经对特征点进行了三角测量,您有四个点{P_A,P_B,P_C,P_D}
对应于立方体上点的放大3D 位置。
既然你知道宽度/高度,你必须有
scale_factor*(P_A-P_C)==height
scale_factor*(P_B-P_A)=width
因此,这为您提供了一种估计对象位置/方向变化的方法。但它可能不会是一个强大的解决方案,并且只能在非常简单的情况下工作。
如果对象不是静态的,则其特征将是相对于您计算的基本值的异常值,因此它们不会被三角测量。这个问题要困难得多,但我怀疑可能有一个解决方案,例如基于光流,尽管我认为两种观点是不够的。
我希望这有所帮助。