我有已知尺寸的在墙壁上的矩形目标和位置,并在机器人的移动相机。 由于机器人在房间里开车,我需要找到目标并计算相机和姿势的位置。 作为进一步的扭曲,相机的仰角和方位角可以用舵机改变。 我能够找到使用OpenCV的目标,但我仍然对计算摄像机的位置(实际上,我已经从敲我的头在墙上的最后一个星期得到了我的额头上出现扁平点)模糊。 下面是我在做什么:
- 阅读先前计算相机内部函数文件
- 从轮廓得到4分的目标矩形的像素坐标
- 调用solvePnP与矩形的世界坐标,像素坐标,照相机矩阵和失真矩阵
- 与旋转和平移向量呼叫projectPoints
- ???
我已阅读OpenCV的书,但我想我只是缺少关于如何使用投影点,旋转和平移向量来计算摄影机和其姿势(我不是一个数学奇才)的世界坐标的东西: - (
2013年4月2日在从“morynicz”的建议,我写了这个简单的独立程序。
#include <Windows.h>
#include "opencv\cv.h"
using namespace cv;
int main (int argc, char** argv)
{
const char *calibration_filename = argc >= 2 ? argv [1] : "M1011_camera.xml";
FileStorage camera_data (calibration_filename, FileStorage::READ);
Mat camera_intrinsics, distortion;
vector<Point3d> world_coords;
vector<Point2d> pixel_coords;
Mat rotation_vector, translation_vector, rotation_matrix, inverted_rotation_matrix, cw_translate;
Mat cw_transform = cv::Mat::eye (4, 4, CV_64FC1);
// Read camera data
camera_data ["camera_matrix"] >> camera_intrinsics;
camera_data ["distortion_coefficients"] >> distortion;
camera_data.release ();
// Target rectangle coordinates in feet
world_coords.push_back (Point3d (10.91666666666667, 10.01041666666667, 0));
world_coords.push_back (Point3d (10.91666666666667, 8.34375, 0));
world_coords.push_back (Point3d (16.08333333333334, 8.34375, 0));
world_coords.push_back (Point3d (16.08333333333334, 10.01041666666667, 0));
// Coordinates of rectangle in camera
pixel_coords.push_back (Point2d (284, 204));
pixel_coords.push_back (Point2d (286, 249));
pixel_coords.push_back (Point2d (421, 259));
pixel_coords.push_back (Point2d (416, 216));
// Get vectors for world->camera transform
solvePnP (world_coords, pixel_coords, camera_intrinsics, distortion, rotation_vector, translation_vector, false, 0);
dump_matrix (rotation_vector, String ("Rotation vector"));
dump_matrix (translation_vector, String ("Translation vector"));
// We need inverse of the world->camera transform (camera->world) to calculate
// the camera's location
Rodrigues (rotation_vector, rotation_matrix);
Rodrigues (rotation_matrix.t (), camera_rotation_vector);
Mat t = translation_vector.t ();
camera_translation_vector = -camera_rotation_vector * t;
printf ("Camera position %f, %f, %f\n", camera_translation_vector.at<double>(0), camera_translation_vector.at<double>(1), camera_translation_vector.at<double>(2));
printf ("Camera pose %f, %f, %f\n", camera_rotation_vector.at<double>(0), camera_rotation_vector.at<double>(1), camera_rotation_vector.at<double>(2));
}
像素坐标我在试验中使用的是从已取约27英尺离开目标矩形(其为62英寸宽和20英寸高)的实像,在约45度角。 输出是不是我期待的。 我究竟做错了什么?
Rotation vector
2.7005
0.0328
0.4590
Translation vector
-10.4774
8.1194
13.9423
Camera position -28.293855, 21.926176, 37.650714
Camera pose -2.700470, -0.032770, -0.459009
这将是一个问题,如果我的世界坐标系中具有不同于OpenCV的屏幕Y轴反转Y轴? (我的坐标系的原点是在地板上到目标的左侧,而OpenCV中的渊源考是在屏幕的左上角)。
什么单位的姿势?