雷达结构化数据和深度学习检测的目标进行融合的过程中,雷达获取的目标从世界坐标系转换到像素坐标系后,如何快速判定一个雷达目标点是否在box中(融合是否成功)。
可以参考两种方法:
1、直接判断法
直接获取雷达目标在图像上的像素坐标,然后通过比较雷达目标的x坐标是否处于bbox框的【xmin, xmax】之间, y坐标是否处于bbox框的【ymin,ymax】之间,如果均为True,那就说明处于bbox框中
代码如下:
def check_in_box(box, point):
'''
box : xyxy format
point: x,y
'''
x, y = point
if (x >= box[0] & x <= box[2]) & (y >= box[1] & y <= box[3]):
return True
else:
return False
2、坐标向量法
向量的叉乘,又叫做向量积,外积等。
a与b的叉积结果为向量,记为a×b。a与b之间的夹角为θ,则它的模与方向分别为:
模:|a×b| = |a||b|sinθ
方向:垂直于a与b所构成的平面,且满足右手法则
从上述公式可以了解,向量a,b的叉乘的结果取决于sinθ,如果sinθ的值大于0,按照右手准则,说明a向量沿逆时针方向可以转到b向量方向,通俗点讲就是b向量在a向量的左边,其他情况类似,不在赘述。因此可以按照这个原理判定固定点是否在矩形框内部。
具体如下:
- 1、矩形和p点如下图所示
- 2、判定点p是否在矩形内部,主要是判定p点是否在举行内部等价于判定:1、p点在AB和CD之间,2、p点在AD和BC之间,因此只需要计算如下值即可:
(1)BA×BP>0&DC×DP>0则说明P点位于AB和CD之间
(2)AD×AP>0&CB×CP>0则说明P点位于AD和BC之间
同时满足上述两条即可验证P是否在矩形框内部。
平面直角坐标系中
向量a=(x1,y1)
向量b=(x2,y2)
则|a×b| = |x1y2-x2y1|
代码如下:
def check_in_box(box, point):
'''
box : xyxy format
point: x,y
'''
x, y = point
xmin, ymin, xmax, ymax = box
BA = (xmin - xmax, 0)
BP = (x - xmax, y - ymin)
DC = (xmax - xmin, 0)
DP = (x - xmin, y - ymax)
AD = (0, ymax - ymin)
AP = (x - xmin, y - ymin)
CB = (0, ymin - ymax)
CP = (x - xmax, y - ymax)
a = BA[0]*BP[1]-BA[1]*BP[0] # BA×BP
b = DC[0]*DP[1]-DC[1]*DP[0] # DC×DP
c = AD[0]*AP[1]-AD[1]*AP[0] # AD×AP
d = CB[0]*CP[1]-CB[1]*CP[0] # CB×CP
if (a>0&b>0)&(c>0&d>0):
return True
else:
False
3、射线法
其主要原理是在凸边形的内部或者外部存在的点,通过以它为起点,向外无限延伸,与凸边形的边的交点数量,如果为偶数,则点在凸边形的外部,如果为奇数,则在凸边形的内部。
其具体实现的c++代码如下所示:
#include"PtInPolygon.h"
bool PtInPolygon(Point2d p, vector<Point2d> &ptpolygon, int nCount)
{
int nCross = 0;
for (int i = 0; i < nCount; i++)
{
Point2d p1 = ptpolygon[i];
Point2d p2 = ptpolygon[(i + 1) % nCount];
if (p1.y == p2.y) {
continue;
}
if (p.y < min(p1.y, p2.y)) {
continue;
}
if (p.y >= max(p1.y, p2.y)) {
continue;
}
double x = (double)(p.y - p1.y) * (double)(p2.x - p1.x) / (double)(p2.y - p1.y) + p1.x;
if (x > p.x) {
nCross++; //统计在点右侧射线的交点
}
}
if ((nCross % 2) == 1) { // 在区域内部
return true;
}
else
{
return false;
}
}
以上为自己的小结,如有问题,敬请指正。