最后发现不是point的精度问题,float不至于产生这么大误差,是自己代码里缓存了顶点坐标,后面由手动修改了旋转矩形的角度,导致不匹配!
下文可以忽略了-_-!
发现一个天坑,通过高宽和角度构造了一个旋转矩形
RotatedRect(const Point2f& _center, const Size2f& _size, float _angle)
然后通过points返回矩形的四个顶点
void points(Point2f pts[])
发现这些顶点跟构造时的角度差距较大
如旋转矩形
center={x=1852.00000 y=560.000000 }
size={width=380.000000 height=132.000000 }
angle=39.6590843
points返回的点集
-
[0] {x=1669.15649 y=476.189209 } cv::Point_<float>
-
[1] {x=1760.48804 y=380.886719 } cv::Point_<float>
-
[2] {x=2034.84351 y=643.810791 } cv::Point_<float>
-
[3] {x=1943.51196 y=739.113281 } cv::Point_<float>
求点1和点2的角度 (matlab)
p0 = [2034.84351 643.810791];
p1 = [1760.48804 380.886719];
atan((p0(2) - p1(2)) / (p0(1) - p1(1))) / pi * 180;
ans = 43.781133464613490
差了令人瞩目的4.1220,所以要做变换矩阵的计算时慎用,会带来很大的误差!
查看points源码
sources\modules\core\src\matrix.cpp
void RotatedRect::points(Point2f pt[]) const
{
double _angle = angle*CV_PI/180.;
float b = (float)cos(_angle)*0.5f;
float a = (float)sin(_angle)*0.5f;
pt[0].x = center.x - a*size.height - b*size.width;
pt[0].y = center.y + b*size.height - a*size.width;
pt[1].x = center.x + a*size.height - b*size.width;
pt[1].y = center.y - b*size.height - a*size.width;
pt[2].x = 2*center.x - pt[0].x;
pt[2].y = 2*center.y - pt[0].y;
pt[3].x = 2*center.x - pt[1].x;
pt[3].y = 2*center.y - pt[1].y;
}
重写一个基于double运算的版本,算出来的角度就对了
void MyGetVertices(cv::Point2d pt[4], cv::RotatedRect &rect)
{
double _angle = rect.angle*CV_PI / 180.;
double b = cos(_angle)*0.5;
double a = sin(_angle)*0.5;
cv::Point2f center = rect.center;
cv::Size2f size = rect.size;
pt[0].x = center.x - a*size.height - b*size.width;
pt[0].y = center.y + b*size.height - a*size.width;
pt[1].x = center.x + a*size.height - b*size.width;
pt[1].y = center.y - b*size.height - a*size.width;
pt[2].x = 2 * center.x - pt[0].x;
pt[2].y = 2 * center.y - pt[0].y;
pt[3].x = 2 * center.x - pt[1].x;
pt[3].y = 2 * center.y - pt[1].y;
}
返回的点集如下
-
[0] {x=1663.6050505562603 y=489.54900267497470 } cv::Point_<double>
-
[1] {x=1747.8498550961431 y=387.92807516475688 } cv::Point_<double>
-
[2] {x=2040.3949494437397 y=630.45099732502536 } cv::Point_<double>
-
[3] {x=1956.1501449038569 y=732.07192483524318 } cv::Point_<double>