【问题标题】:OpenCV - Find angle to a static depth-skewed rectangleOpenCV - 找到静态深度倾斜矩形的角度
【发布时间】:2016-05-31 10:08:10
【问题描述】:

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

(图片来自here,前提相同。)

如何计算从相机到目标矩形的水平角?假设矩形目标已经在 OpenCV 中翻译成 MatOfPoints 对象。

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

Rotation: [2.662893740213683e-05;
 -0.0001007426907390123;
 0.0484638952150343]
Position: [18.43394203112024;
 48.39531890689394;
 0.1318397318617369]

给出结果垫转储:

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

【问题讨论】:

    标签: opencv computer-vision vision


    【解决方案1】:

    艰难的方法:

    i) 您会在图像中找到 CLOCKWISE 矩形二维角。

    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 使用右手坐标系。您可能需要重新考虑最终角的符号。

    【讨论】:

    • 当您在第二节中提到图像尺寸和矩形尺寸时,它们的单位是什么?另外,您是指物理矩形的大小,还是边界矩形对象的大小?
    • 我真的很抱歉...我愚蠢地引导您在 ii) 中出现关于 3D 角定义的错误。我编辑了我的答案。显然,3D 角不得与图像像素混合。您选择要使用的任何物理单位,相同的单位将用于计算相机的位置姿势。
    • 感谢您的帮助!在第 ii 节中,您声明矩形 3D 角是顺时针方向的,但在以下代码中,您按以下顺序列出角:左上、右上、左下、右下,这似乎不是顺时针。其中哪一个是正确的,或者它们都正确但我误解了?
    • 我的另一个错误。你的好看!我再次编辑我的答案以顺时针设置 3D 角。
    • 注意:正如我想你所理解的,角落是顺时针、逆时针还是其他方向并不重要。真正重要的是 2D 点顺序和 3D 点顺序都匹配。
    猜你喜欢
    • 2016-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-18
    • 2013-03-16
    • 1970-01-01
    • 2012-06-13
    相关资源
    最近更新 更多