feat: Working retinaface

This commit is contained in:
uttarayan21
2025-08-07 11:51:10 +05:30
parent f7aae32caf
commit 8d07b0846c
3 changed files with 322 additions and 93 deletions

View File

@@ -3,8 +3,37 @@ pub mod nms;
pub mod roi;
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 {}
pub trait Num:
num::Num
+ core::ops::AddAssign
+ core::ops::SubAssign
+ core::ops::MulAssign
+ core::ops::DivAssign
+ core::cmp::PartialOrd
+ core::cmp::PartialEq
+ nalgebra::SimdPartialOrd
+ nalgebra::SimdValue
+ Copy
+ core::fmt::Debug
+ 'static
{
}
impl<
T: num::Num
+ core::ops::AddAssign
+ core::ops::SubAssign
+ core::ops::MulAssign
+ core::ops::DivAssign
+ core::cmp::PartialOrd
+ core::cmp::PartialEq
+ nalgebra::SimdPartialOrd
+ nalgebra::SimdValue
+ Copy
+ core::fmt::Debug
+ 'static,
> Num for T
{
}
/// An axis aligned bounding box in `D` dimensions, defined by the minimum vertex and a size vector.
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
@@ -20,16 +49,26 @@ pub type Aabb2<T> = AxisAlignedBoundingBox<T, 2>;
pub type Aabb3<T> = AxisAlignedBoundingBox<T, 3>;
impl<T: Num, const D: usize> AxisAlignedBoundingBox<T, D> {
pub fn new(point: Point<T, D>, size: SVector<T, D>) -> Self {
// Panics if max < min
pub fn new(min_point: Point<T, D>, max_point: Point<T, D>) -> Self {
if max_point < min_point {
panic!("max_point must be greater than or equal to min_point");
}
Self::from_min_max_vertices(min_point, max_point)
}
pub fn try_new(min_point: Point<T, D>, max_point: Point<T, D>) -> Option<Self> {
if max_point < min_point {
return None;
}
Some(Self::from_min_max_vertices(min_point, max_point))
}
pub fn new_point_size(point: Point<T, D>, size: SVector<T, D>) -> Self {
Self { point, size }
}
pub fn from_min_max_vertices(point1: Point<T, D>, point2: Point<T, D>) -> Self
where
T: core::ops::SubAssign,
{
pub fn from_min_max_vertices(point1: Point<T, D>, point2: Point<T, D>) -> Self {
let size = point2 - point1;
Self::new(point1, SVector::from(size))
Self::new_point_size(point1, SVector::from(size))
}
/// Only considers the points closest and furthest from origin
@@ -151,7 +190,21 @@ impl<T: Num, const D: usize> AxisAlignedBoundingBox<T, D> {
self.intersection(other)
}
pub fn union(&self, other: &Self) -> Self
pub fn component_clamp(&self, min: T, max: T) -> Self
where
T: PartialOrd,
{
let mut this = *self;
this.point.iter_mut().for_each(|x| {
*x = nalgebra::clamp(*x, min, max);
});
this.size.iter_mut().for_each(|x| {
*x = nalgebra::clamp(*x, min, max);
});
this
}
pub fn merge(&self, other: &Self) -> Self
where
T: core::ops::AddAssign,
T: core::ops::SubAssign,
@@ -168,6 +221,21 @@ impl<T: Num, const D: usize> AxisAlignedBoundingBox<T, D> {
Self::from_min_max_vertices(min, max)
}
pub fn union(&self, other: &Self) -> T
where
T: core::ops::AddAssign,
T: core::ops::SubAssign,
T: core::ops::MulAssign,
T: PartialOrd,
T: nalgebra::SimdValue,
T: nalgebra::SimdPartialOrd,
{
self.measure() + other.measure()
- Self::intersection(self, other)
.map(|x| x.measure())
.unwrap_or(T::zero())
}
pub fn intersection(&self, other: &Self) -> Option<Self>
where
T: core::ops::AddAssign,
@@ -176,21 +244,13 @@ impl<T: Num, const D: usize> AxisAlignedBoundingBox<T, D> {
T: nalgebra::SimdPartialOrd,
T: nalgebra::SimdValue,
{
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 inter_min = self.min_vertex().inf(&other.min_vertex());
let inter_max = self.max_vertex().sup(&other.max_vertex());
if self_max < other_min || other_max < self_min {
if inter_max < inter_min {
return None; // No intersection
}
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),
))
Some(Self::new(inter_min, inter_max))
}
pub fn denormalize(&self, factor: nalgebra::SVector<T, D>) -> Self
@@ -233,7 +293,7 @@ impl<T: Num, const D: usize> AxisAlignedBoundingBox<T, D> {
self.size.product()
}
pub fn iou(&self, other: &Self) -> Option<T>
pub fn iou(&self, other: &Self) -> T
where
T: core::ops::AddAssign,
T: core::ops::SubAssign,
@@ -242,9 +302,12 @@ impl<T: Num, const D: usize> AxisAlignedBoundingBox<T, D> {
T: nalgebra::SimdValue,
T: core::ops::MulAssign,
{
let intersection = self.intersection(other)?;
let intersection = self
.intersection(other)
.map(|v| v.measure())
.unwrap_or(T::zero());
let union = self.union(other);
Some(intersection.measure() / union.measure())
intersection / union
}
}
@@ -257,13 +320,6 @@ impl<T: Num> Aabb2<T> {
let point2 = Point2::new(x2, y2);
Self::from_min_max_vertices(point1, point2)
}
pub fn new_2d(point1: Point2<T>, point2: Point2<T>) -> Self
where
T: core::ops::SubAssign,
{
let size = point2.coords - point1.coords;
Self::new(point1, SVector::from(size))
}
pub fn x1y1(&self) -> Point2<T> {
self.point
}
@@ -327,14 +383,6 @@ impl<T: Num> Aabb2<T> {
}
impl<T: Num> Aabb3<T> {
pub fn new_3d(point1: Point3<T>, point2: Point3<T>) -> Self
where
T: core::ops::SubAssign,
{
let size = point2.coords - point1.coords;
Self::new(point1, SVector::from(size))
}
pub fn volume(&self) -> T
where
T: core::ops::MulAssign,
@@ -349,7 +397,7 @@ fn test_bbox_new() {
let point1 = Point2::new(1.0, 2.0);
let point2 = Point2::new(4.0, 6.0);
let bbox = AxisAlignedBoundingBox::new_2d(point1, point2);
let bbox = AxisAlignedBoundingBox::new(point1, point2);
assert_eq!(bbox.min_vertex(), point1);
assert_eq!(bbox.size(), Vector2::new(3.0, 4.0));
@@ -414,7 +462,7 @@ fn test_bounding_box_contains_2d() {
let point1 = Point2::new(1.0, 2.0);
let point2 = Point2::new(4.0, 6.0);
let bbox = AxisAlignedBoundingBox::new_2d(point1, point2);
let bbox = AxisAlignedBoundingBox::new(point1, point2);
assert!(bbox.contains_point(&Point2::new(2.0, 3.0)));
assert!(!bbox.contains_point(&Point2::new(5.0, 7.0)));
@@ -426,13 +474,13 @@ fn test_bounding_box_union_2d() {
let point1 = Point2::new(1.0, 2.0);
let point2 = Point2::new(4.0, 6.0);
let bbox1 = AxisAlignedBoundingBox::new_2d(point1, point2);
let bbox1 = AxisAlignedBoundingBox::new(point1, point2);
let point3 = Point2::new(3.0, 5.0);
let point4 = Point2::new(7.0, 8.0);
let bbox2 = AxisAlignedBoundingBox::new_2d(point3, point4);
let bbox2 = AxisAlignedBoundingBox::new(point3, point4);
let union_bbox = bbox1.union(&bbox2);
let union_bbox = bbox1.merge(&bbox2);
assert_eq!(union_bbox.min_vertex(), Point2::new(1.0, 2.0));
assert_eq!(union_bbox.size(), Vector2::new(6.0, 6.0));
}
@@ -443,11 +491,11 @@ fn test_bounding_box_intersection_2d() {
let point1 = Point2::new(1.0, 2.0);
let point2 = Point2::new(4.0, 6.0);
let bbox1 = AxisAlignedBoundingBox::new_2d(point1, point2);
let bbox1 = AxisAlignedBoundingBox::new(point1, point2);
let point3 = Point2::new(3.0, 5.0);
let point4 = Point2::new(5.0, 7.0);
let bbox2 = AxisAlignedBoundingBox::new_2d(point3, point4);
let bbox2 = AxisAlignedBoundingBox::new(point3, point4);
let intersection_bbox = bbox1.intersection(&bbox2).unwrap();
assert_eq!(intersection_bbox.min_vertex(), Point2::new(3.0, 5.0));
@@ -460,7 +508,7 @@ fn test_bounding_box_contains_point() {
let point1 = Point2::new(2, 3);
let point2 = Point2::new(5, 4);
let bbox = AxisAlignedBoundingBox::new_2d(point1, point2);
let bbox = AxisAlignedBoundingBox::new(point1, point2);
use itertools::Itertools;
for (i, j) in (0..=10).cartesian_product(0..=10) {
if bbox.contains_point(&Point2::new(i, j)) {