如何判断一个点是否在一个box框中间

雷达结构化数据和深度学习检测的目标进行融合的过程中,雷达获取的目标从世界坐标系转换到像素坐标系后,如何快速判定一个雷达目标点是否在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;
	}
}

以上为自己的小结,如有问题,敬请指正。

猜你喜欢

转载自blog.csdn.net/caobin_cumt/article/details/129831820
今日推荐