fix: A lot of fixes relating to bounding-boxes

This commit is contained in:
uttarayan21
2025-08-05 14:39:16 +05:30
parent 561fb2a924
commit 42ac210bba
4 changed files with 104 additions and 42 deletions

View File

@@ -2,7 +2,7 @@ pub mod draw;
pub mod nms;
pub mod roi;
use nalgebra::{Point, Point2, Point3, SVector};
use nalgebra::{Point, Point2, Point3, SVector, SimdPartialOrd, SimdValue};
pub trait Num: num::Num + Copy + core::fmt::Debug + 'static {}
impl<T: num::Num + Copy + core::fmt::Debug + 'static> Num for T {}
@@ -85,10 +85,7 @@ impl<T: Num, const D: usize> AxisAlignedBoundingBox<T, D> {
self.point += translation;
}
pub fn min_vertex(&self) -> Point<T, D>
where
T: core::ops::SubAssign,
{
pub fn min_vertex(&self) -> Point<T, D> {
self.point
}
@@ -140,16 +137,18 @@ impl<T: Num, const D: usize> AxisAlignedBoundingBox<T, D> {
other_min >= self_min && other_max <= self_max
}
pub fn clamp(&self, other: &Self) -> Self
pub fn clamp(&self, other: &Self) -> Option<Self>
where
T: core::ops::AddAssign,
T: core::ops::SubAssign,
T: PartialOrd,
T: nalgebra::SimdPartialOrd,
T: nalgebra::SimdValue,
{
if self.contains_bbox(other) {
return *other;
if other.contains_bbox(self) {
return Some(*self);
}
todo!()
self.intersection(other)
}
pub fn union(&self, other: &Self) -> Self
@@ -157,18 +156,16 @@ impl<T: Num, const D: usize> AxisAlignedBoundingBox<T, D> {
T: core::ops::AddAssign,
T: core::ops::SubAssign,
T: PartialOrd,
T: nalgebra::SimdValue,
T: nalgebra::SimdPartialOrd,
{
let self_min = self.min_vertex();
let self_max = self.max_vertex();
let other_min = other.min_vertex();
let other_max = other.max_vertex();
let max_of_min = (self_min.coords < other_min.coords)
.then_some(self_min.coords)
.unwrap_or(other_min.coords);
let min_of_max = (self_max.coords > other_max.coords)
.then_some(self_max.coords)
.unwrap_or(other_max.coords);
Self::from_min_max_vertices(Point::from(max_of_min), Point::from(min_of_max))
let min = self_min.inf(&other_min);
let max = self_max.sup(&other_max);
Self::from_min_max_vertices(min, max)
}
pub fn intersection(&self, other: &Self) -> Option<Self>
@@ -176,6 +173,8 @@ impl<T: Num, const D: usize> AxisAlignedBoundingBox<T, D> {
T: core::ops::AddAssign,
T: core::ops::SubAssign,
T: PartialOrd,
T: nalgebra::SimdPartialOrd,
T: nalgebra::SimdValue,
{
let self_min = self.min_vertex();
let self_max = self.max_vertex();
@@ -186,12 +185,8 @@ impl<T: Num, const D: usize> AxisAlignedBoundingBox<T, D> {
return None; // No intersection
}
let min = (self_min.coords > other_min.coords)
.then_some(self_min.coords)
.unwrap_or(other_min.coords);
let max = (self_max.coords < other_max.coords)
.then_some(self_max.coords)
.unwrap_or(other_max.coords);
let min = self_min.sup(&other_min);
let max = self_max.inf(&other_max);
Some(Self::from_min_max_vertices(
Point::from(min),
Point::from(max),
@@ -211,7 +206,7 @@ impl<T: Num, const D: usize> AxisAlignedBoundingBox<T, D> {
}
}
pub fn cast<T2>(&self) -> Option<Aabb<T2, D>>
pub fn try_cast<T2>(&self) -> Option<Aabb<T2, D>>
where
// T: num::NumCast,
T2: Num + simba::scalar::SubsetOf<T>,
@@ -231,6 +226,26 @@ impl<T: Num, const D: usize> AxisAlignedBoundingBox<T, D> {
// size: self.size.as_(),
// })
// }
pub fn measure(&self) -> T
where
T: core::ops::MulAssign,
{
self.size.product()
}
pub fn iou(&self, other: &Self) -> Option<T>
where
T: core::ops::AddAssign,
T: core::ops::SubAssign,
T: PartialOrd,
T: nalgebra::SimdPartialOrd,
T: nalgebra::SimdValue,
T: core::ops::MulAssign,
{
let intersection = self.intersection(other)?;
let union = self.union(other);
Some(intersection.measure() / union.measure())
}
}
impl<T: Num> Aabb2<T> {
@@ -305,20 +320,9 @@ impl<T: Num> Aabb2<T> {
pub fn area(&self) -> T
where
T: core::ops::Mul<Output = T>,
T: core::ops::MulAssign,
{
self.size.x * self.size.y
}
pub fn iou(&self, other: &Self) -> Option<T>
where
T: core::ops::AddAssign,
T: core::ops::SubAssign,
T: PartialOrd,
{
let intersection = self.intersection(other)?;
let union = self.union(other);
Some(intersection.area() / union.area())
self.measure()
}
}
@@ -333,9 +337,9 @@ impl<T: Num> Aabb3<T> {
pub fn volume(&self) -> T
where
T: core::ops::Mul<Output = T>,
T: core::ops::MulAssign,
{
self.size.x * self.size.y * self.size.z
self.measure()
}
}
@@ -476,3 +480,19 @@ fn test_bounding_box_contains_point() {
}
}
}
#[test]
fn test_bounding_box_clamp_box_2d() {
let bbox1 = Aabb2::from_x1y1x2y2(1, 1, 4, 4);
let bbox2 = Aabb2::from_x1y1x2y2(2, 2, 3, 3);
let clamped = bbox2.clamp(&bbox1).unwrap();
assert_eq!(bbox2, clamped);
let clamped = bbox1.clamp(&bbox2).unwrap();
assert_eq!(bbox2, clamped);
let bbox1 = Aabb2::from_x1y1x2y2(4, 5, 7, 8);
let bbox2 = Aabb2::from_x1y1x2y2(5, 4, 8, 7);
let clamped = bbox1.clamp(&bbox2).unwrap();
let expected = Aabb2::from_x1y1x2y2(5, 5, 7, 7);
assert_eq!(clamped, expected)
}

View File

@@ -18,7 +18,14 @@ pub fn nms<T>(
nms_threshold: T,
) -> Vec<Aabb2<T>>
where
T: Num + num::Float + core::iter::Product<T> + core::ops::AddAssign + core::ops::SubAssign,
T: Num
+ num::Float
+ core::iter::Product<T>
+ core::ops::AddAssign
+ core::ops::SubAssign
+ core::ops::MulAssign
+ nalgebra::SimdValue
+ nalgebra::SimdPartialOrd,
{
use itertools::Itertools;
let bboxes: Vec<_> = boxes