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 使用右手坐标系。您可能需要重新考虑最终角度的符号。
给定一个固定位置的矩形和一个未知位置的相机,我如何找到相机和矩形之间的水平角度?矩形将始终垂直于地面并且大小固定。相机将始终处于比矩形低的高度。
(图片来自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 使用右手坐标系。您可能需要重新考虑最终角度的符号。