两个矩形重叠多少?
我有两个矩形 a 和 b,它们的边平行于坐标系的轴。我的坐标为 x1,y1,x2,y2。
我试图确定,它们不仅重叠,而且重叠了多少?我试图弄清楚它们是否真的是相同的矩形,是否有一点回旋余地。那么它们的面积是95%一样吗?
对计算重叠百分比有帮助吗?
I have two rectangles a and b with their sides parallel to the axes of the coordinate system. I have their co-ordinates as x1,y1,x2,y2.
I'm trying to determine, not only do they overlap, but HOW MUCH do they overlap? I'm trying to figure out if they're really the same rectangle give or take a bit of wiggle room. So is their area 95% the same?
Any help in calculating the % of overlap?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
计算交集的面积,它也是一个矩形:
从那里您可以计算并集的面积:
您可以考虑比率
(在完美重叠的情况下为 100%,低至 0%)。
Compute the area of the intersection, which is a rectangle too:
From there you compute the area of the union:
And you can consider the ratio
(100% in case of a perfect overlap, down to 0%).
虽然 接受的答案是正确的,但我认为值得以一种能够完全阐明答案的基本原理的方式探索这个答案明显的。这是一种太常见的算法,不可能有不完整的(或更糟糕的是,有争议的)答案。此外,如果只浏览一下给定的公式,您可能会错过算法的优美性和可扩展性,以及正在做出的隐式决策。
我们将构建使这些公式直观的方法:
首先,考虑定义二维框的一种方法是:
这可能看起来像:
我用三角形表示左上角,用圆圈表示右下角。这是为了避免像本例中的
x1, x2
这样的不透明语法。两个重叠的矩形可能如下所示:
请注意,要找到重叠,您要寻找橙色和蓝色碰撞的位置:
一旦你认识到这一点,很明显重叠是以下结果的结果找到并乘以这两条深色线:
每条线的长度是两个圆点的最小值减去两个三角形点的最大值。
在这里,我使用双色调三角形(和圆形)来显示橙色点和蓝色点的相互比较。双色三角形后面的小写字母“y”表示沿 y 轴比较三角形,小写“x”表示沿 x 轴比较。
例如,要查找深蓝色线的长度,您可以看到比较三角形以查找两者之间的最大值。比较的属性是 x 属性。三角形之间的最大 x 值为 210。
同样的事情的另一种说法是:
通过从直线最远侧的最近点减去直线最近侧的最远点来找到适合橙色线和蓝色线的新线的长度。
找到这些线可以提供有关重叠区域的完整信息。
一旦你有了这个,找到重叠的百分比就很简单了:
但是等等,如果橙色矩形不与蓝色矩形重叠,那么您将有问题:
在这个示例中,我们的重叠区域的值为 -850,这是不对的。更糟糕的是,如果检测不与任一维度重叠(x 轴或 y 轴均不重叠),那么您仍然会得到正数,因为两个维度均为负数。这就是为什么您将
Max(0, ...) * Max(0, ...)
视为解决方案的一部分;它确保如果任何重叠为负数,您将从函数中得到 0。与我们的符号系统保持一致的最终公式:
值得注意的是,可能不需要使用
max(0, ...)
函数。您可能想知道某物是否沿其某个维度而不是所有维度重叠;如果您使用 max 那么您将删除该信息。因此,请考虑如何处理不重叠的边界框。通常,max 函数很好用,但值得了解它在做什么。最后,请注意,由于此比较仅涉及线性测量,因此可以缩放到任意尺寸或任意重叠的四边形。
总结一下:
While the accepted answer is correct, I think it's worth exploring this answer in a way that will make the rationale for the answer completely obvious. This is too common an algorithm to have an incomplete (or worse, controversial) answer. Furthermore, with only a passing glance at the given formula, you may miss the beauty and extensibility of the algorithm, and the implicit decisions that are being made.
We're going to build our way up to making these formulas intuitive:
First, consider one way to define a two dimensional box is with:
This might look like:
I indicate the top left with a triangle and the bottom right with a circle. This is to avoid opaque syntax like
x1, x2
for this example.Two overlapping rectangles might look like this:
Notice that to find the overlap you're looking for the place where the orange and the blue collide:
Once you recognize this, it becomes obvious that overlap is the result of finding and multiplying these two darkened lines:
The length of each line is the minimum value of the two circle points, minus the maximum value of the two triangle points.
Here, I'm using a two-toned triangle (and circle) to show that the orange and the blue points are compared with each other. The small letter 'y' after the two-toned triangle indicates that the triangles are compared along the y axis, the small 'x' means they are compared along the x axis.
For example, to find the length of the darkened blue line you can see the triangles are compared to look for the maximum value between the two. The attribute that is compared is the x attribute. The maximum x value between the triangles is 210.
Another way to say the same thing is:
The length of the new line that fits onto both the orange and blue lines is found by subtracting the furthest point on the closest side of the line from the closest point on the furthest side of the line.
Finding those lines gives complete information about the overlapping areas.
Once you have this, finding the percentage of overlap is trivial:
But wait, if the orange rectangle does not overlap with the blue one then you're going to have a problem:
With this example, you get a -850 for our overlapping area, that can't be right. Even worse, if a detection doesn't overlap with either dimension (neither on the x or y axis) then you will still get a positive number because both dimensions are negative. This is why you see the
Max(0, ...) * Max(0, ...)
as part of the solution; it ensures that if any of the overlaps are negative you'll get a 0 back from your function.The final formula in keeping with our symbology:
It's worth noting that using the
max(0, ...)
function may not be necessary. You may want to know if something overlaps along one of its dimensions rather than all of them; if you use max then you will obliterate that information. For that reason, consider how you want to deal with non-overlapping bounding boxes. Normally, the max function is fine to use, but it's worth being aware what it's doing.Finally, notice that since this comparison is only concerned with linear measurements it can be scaled to arbitrary dimensions or arbitrary overlapping quadrilaterals.
To summarize:
我最近也遇到了这个问题并应用了 Yves 的答案,但不知何故导致了错误的区域大小,所以我重写了它。
假设有两个矩形 A 和 B,找出它们重叠的程度,如果重叠,则返回面积大小:
I recently ran into this problem as well and applied Yves' answer, but somehow that led to the wrong area size, so I rewrote it.
Assuming two rectangles A and B, find out how much they overlap and if so, return the area size:
只需修复之前的答案,使比率介于 0 和 1 之间(使用 Python):
输出将是:
Just fixing previous answers so that the ratio is between 0 and 1 (using Python):
The output will be:
假设矩形必须平行于 x 和 y 轴,因为这似乎是前面的评论和答案的情况。
我还不能发表评论,但我想指出,前面的两个答案似乎都忽略了一侧矩形完全位于另一个矩形一侧的情况。如果我错了,请纠正我。
考虑这种情况
在这种情况下,我们看到对于交集,高度必须为
bTop - bBottom
因为b
的垂直部分完全包含在a
中代码>.我们只需要添加更多情况,如下所示:(如果将顶部和底部视为与右侧和左侧相同,则可以缩短代码,这样您就不需要将条件块复制两次,但这应该可以。)
Assuming that the rectangle must be parallel to
x
andy
axis as that seems to be the situation from the previous comments and answers.I cannot post comment yet, but I would like to point out that both previous answers seem to ignore the case when one side rectangle is totally within the side of the other rectangle. Please correct me if I am wrong.
Consider the case
In this case, we see that for the intersection, height must be
bTop - bBottom
because the vertical part ofb
is wholly contained ina
.We just need to add more cases as follows: (The code can be shorted if you treat top and bottom as the same thing as right and left, so that you do not need to duplicate the conditional chunk twice, but this should do.)
这是 C# 中的一个工作函数:
Here is a working Function in C#:
@User3025064 是正确的,并且是最简单的解决方案,但是,必须首先检查不相交的矩形的排他性,例如矩形 A 和 A 。 B(在 Visual Basic 中):
@User3025064 is correct and is the simplest solution, though, exclusivity must be checked first for rectangles that do not intersect e.g., for rectangles A & B (in Visual Basic):
@user3025064 的答案是正确答案。接受的答案无意中翻转了内部 MAX 和 MIN 调用。
如果我们使用给出的公式 MAX(0,x) 而不是 ABS(x),我们也不需要首先检查它们是否相交。如果它们不相交,MAX(0,x) 返回零,这使得相交区域为 0(即不相交)。
我建议 @Yves Daoust 修正他的答案,因为它是任何搜索该问题的人都会弹出的公认答案。再次,这是正确的交集公式:
SI = Max(0, Min(XA2, XB2) - Max(XA1, XB1)) * Max(0, Min(YA2, YB2) - Max(YA1, YB1))
其余如常。并集:
SU = SA + SB - SI
和比率:
SI/SU
The answer of @user3025064 is the right answer. The accepted answer inadvertently flips the inner MAX and MIN calls.
We also don't need to check first if they intersect or not if we use the presented formula, MAX(0,x) as opposed to ABS(x). If they do not intersect, MAX(0,x) returns zero which makes the intersection area 0 (i.e. disjoint).
I suggest that @Yves Daoust fixes his answer because it is the accepted one that pops up to anyone who searches for that problem. Once again, here is the right formula for intersection:
SI = Max(0, Min(XA2, XB2) - Max(XA1, XB1)) * Max(0, Min(YA2, YB2) - Max(YA1, YB1))
The rest as usual. Union:
SU = SA + SB - SI
and ratio:
SI/SU