OpenCV - 查找静态深度偏斜矩形的角度

时间:2016-02-19 00:18:27

标签: opencv computer-vision vision

给定固定位置的矩形和未知位置的摄像机,如何找到摄像机和矩形之间的水平角度?矩形将始终垂直于地面并且是固定大小。相机的高度始终低于矩形。

Rectangle head on

Rectangle from an angle

(图片来自here,这是同一个前提。)

如何计算从相机到目标矩形的水平角度?假设矩形目标已经被转换为OpenCV中的MatOfPoints对象。

更新:使用SolvePNP和以下图像,生成的旋转和位置垫为不同的图片提供了一些意外的数字。检测到的角点已用圆圈着色,并绘制了BoundingRectangle。 Head on 给出了mat dump:

Rotation: [-0.0001071012175770757;
 -4.285121336676997e-05;
 0.01258020218302199]
Position: [35.87669469188199;
 45.47657018572935;
 0.1244586014980523]

Slightly to the left 给出了mat dump:

    --------------------------------------------------------------
    - employee_id - level - study_environment - work_environment -                     
    --------------------------------------------------------------
    --                         values...                        --
    --------------------------------------------------------------

1 个答案:

答案 0 :(得分:2)

艰难的方法:

i)你发现CLOCKWISE图像中的矩形2D角。

std::vector<cv::Point2f> rect_corners_2d; // TODO find clockwise rectangle 2D corners in image

我猜你有这些点,因为你绘制了矩形。

ii)你可以定义CLOCKWISE物理单位中的矩形3D角,只要该矩形位于相机的中心位于其面向它的光轴上。

float width; // TODO set rectangle's physical width
float height; // TODO set rectangle's physical height
std::vector<cv::Point3f> rect_corners_3d =
{
    cv::Point3f(-width/2, -height/2, 0.0), // top-left
    cv::Point3f(width/2, -height/2, 0.0), // top-right
    cv::Point3f(width/2, height/2, 0.0), // bottom-right
    cv::Point3f(-width/2, height/2, 0.0) // bottom-left
};

iii)旋转图像点,使每个2D角对应于3D对应点。

// rectangle's top-left corner must be the first in 2D image points since it is the first in 3D defined ones
int index; // TODO set index of top-left corner in 2D image points
std::rotate(rect_corners_2d.begin(), rect_corners_2d.begin() + index, rect_corners_2d.end());

iv)了解相机内部参数和镜头失真系数。

cv::Mat_<double> intrinsic_parameters; // TODO set camera matrix
cv::Mat_<double> distortion_coefficients; // TODO set lens distortion coefficients

我希望你有相机的校准。

v)相对于看到的矩形提取相机的姿势:http://docs.opencv.org/2.4/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html#solvepnp

cv::Vec3d rotation;
cv::Vec3d position;
cv::solvePnP(rect_corners_3d, rect_corners_2d, intrinsic_parameters, distortion_coefficients, rotation, position);

此处的位置与您在ii)中用于定义3D角的单位相同。

vi)读取你的水平角度。

double hangle = rotation[1]; // Y axis <--> horizontal angle

结论:计算出的姿势是相机相对于所见矩形的姿势,而不是您预期的相反方式。位置和旋转需要反转。另请注意,相机的Y轴向下,OpenCV使用右手坐标系。您可能想重新考虑最终角度的符号。