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

OpenCV - Find angle to a static depth-skewed rectangle

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

(图片来自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]

困难的方法:

i) 您在图像中顺时针找到矩形 2D 角。

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

我想你已经有了这些点,因为你已经画了矩形。

ii) 只要矩形以其光轴为中心站在相机上,您就可以按物理单位顺时针定义矩形 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 使用右手坐标系。您可能需要重新考虑最终角度的符号。