Skip to content

Commit 6dfa326

Browse files
nikhilaravifacebook-github-bot
authored andcommitted
IOU box3d epsilon fix
Summary: The epsilon value is important for determining whether vertices are inside/outside a plane. Reviewed By: gkioxari Differential Revision: D31485247 fbshipit-source-id: 5517575de7c02f1afa277d00e0190a81f44f5761
1 parent b26f4bc commit 6dfa326

File tree

4 files changed

+28
-9
lines changed

4 files changed

+28
-9
lines changed

pytorch3d/csrc/iou_box3d/iou_utils.cuh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
#include <thrust/device_vector.h>
1212
#include <cstdio>
1313
#include "utils/float_math.cuh"
14-
#include "utils/geometry_utils.cuh"
14+
15+
const auto kEpsilon = 1e-4;
1516

1617
/*
1718
_PLANES and _TRIS define the 4- and 3-connectivity

pytorch3d/csrc/iou_box3d/iou_utils.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@
1616
#include <queue>
1717
#include <tuple>
1818
#include <type_traits>
19-
#include "utils/geometry_utils.h"
2019
#include "utils/vec3.h"
2120

21+
const auto kEpsilon = 1e-4;
2222
/*
2323
_PLANES and _TRIS define the 4- and 3-connectivity
2424
of the 8 box corners.

tests/data/real_boxes.pkl

1.39 KB
Binary file not shown.

tests/test_iou_box3d.py

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
# This source code is licensed under the BSD-style license found in the
55
# LICENSE file in the root directory of this source tree.
66

7+
import pickle
78
import random
89
import unittest
910
from typing import List, Tuple, Union
@@ -15,7 +16,6 @@
1516
from pytorch3d.ops.iou_box3d import _box_planes, _box_triangles, box3d_overlap
1617
from pytorch3d.transforms.rotation_conversions import random_rotation
1718

18-
1919
OBJECTRON_TO_PYTORCH3D_FACE_IDX = [0, 4, 6, 2, 1, 5, 7, 3]
2020
DATA_DIR = get_tests_dir() / "data"
2121
DEBUG = False
@@ -167,6 +167,7 @@ def _test_iou(self, overlap_fn, device):
167167
device=vol.device,
168168
dtype=vol.dtype,
169169
),
170+
atol=1e-7,
170171
)
171172

172173
# 7th test: hand coded example and test with meshlab output
@@ -283,20 +284,36 @@ def _test_iou(self, overlap_fn, device):
283284
self.assertClose(vols, torch.tensor([[vol_inters]], device=device), atol=1e-1)
284285
self.assertClose(ious, torch.tensor([[iou]], device=device), atol=1e-1)
285286

287+
def _test_real_boxes(self, overlap_fn, device):
288+
data_filename = "./real_boxes.pkl"
289+
with open(DATA_DIR / data_filename, "rb") as f:
290+
example = pickle.load(f)
291+
292+
verts1 = torch.FloatTensor(example["verts1"])
293+
verts2 = torch.FloatTensor(example["verts2"])
294+
boxes = torch.stack((verts1, verts2)).to(device)
295+
296+
iou_expected = torch.eye(2).to(device)
297+
vol, iou = overlap_fn(boxes, boxes)
298+
self.assertClose(iou, iou_expected)
299+
286300
def test_iou_naive(self):
287301
device = get_random_cuda_device()
288302
self._test_iou(self._box3d_overlap_naive_batched, device)
289303
self._test_compare_objectron(self._box3d_overlap_naive_batched, device)
304+
self._test_real_boxes(self._box3d_overlap_naive_batched, device)
290305

291306
def test_iou_cpu(self):
292307
device = torch.device("cpu")
293308
self._test_iou(box3d_overlap, device)
294309
self._test_compare_objectron(box3d_overlap, device)
310+
self._test_real_boxes(box3d_overlap, device)
295311

296312
def test_iou_cuda(self):
297313
device = torch.device("cuda:0")
298314
self._test_iou(box3d_overlap, device)
299315
self._test_compare_objectron(box3d_overlap, device)
316+
self._test_real_boxes(box3d_overlap, device)
300317

301318
def _test_compare_objectron(self, overlap_fn, device):
302319
# Load saved objectron data
@@ -656,7 +673,7 @@ def is_inside(
656673
n: torch.Tensor,
657674
points: torch.Tensor,
658675
return_proj: bool = True,
659-
eps: float = 1e-6,
676+
eps: float = 1e-4,
660677
):
661678
"""
662679
Computes whether point is "inside" the plane.
@@ -778,17 +795,17 @@ def clip_tri_by_plane_oneout(
778795
vout is "outside" the plane and vin1, vin2 are "inside"
779796
Returns:
780797
verts: tensor of shape (4, 3) containing the new vertices formed after clipping the
781-
original intersectiong triangle (vout, vin1, vin2)
798+
original intersecting triangle (vout, vin1, vin2)
782799
faces: tensor of shape (2, 3) defining the vertex indices forming the two new triangles
783800
which are "inside" the plane formed after clipping
784801
"""
785802
device = plane.device
786803
# point of intersection between plane and (vin1, vout)
787804
pint1, a1 = plane_edge_point_of_intersection(plane, n, vin1, vout)
788-
assert a1 >= eps and a1 <= 1.0, a1
805+
assert a1 >= -eps and a1 <= 1.0 + eps, a1
789806
# point of intersection between plane and (vin2, vout)
790807
pint2, a2 = plane_edge_point_of_intersection(plane, n, vin2, vout)
791-
assert a2 >= 0.0 and a2 <= 1.0, a2
808+
assert a2 >= -eps and a2 <= 1.0 + eps, a2
792809

793810
verts = torch.stack((vin1, pint1, pint2, vin2), dim=0) # 4x3
794811
faces = torch.tensor(
@@ -823,10 +840,10 @@ def clip_tri_by_plane_twoout(
823840
device = plane.device
824841
# point of intersection between plane and (vin, vout1)
825842
pint1, a1 = plane_edge_point_of_intersection(plane, n, vin, vout1)
826-
assert a1 >= eps and a1 <= 1.0, a1
843+
assert a1 >= -eps and a1 <= 1.0 + eps, a1
827844
# point of intersection between plane and (vin, vout2)
828845
pint2, a2 = plane_edge_point_of_intersection(plane, n, vin, vout2)
829-
assert a2 >= eps and a2 <= 1.0, a2
846+
assert a2 >= -eps and a2 <= 1.0 + eps, a2
830847

831848
verts = torch.stack((vin, pint1, pint2), dim=0) # 3x3
832849
faces = torch.tensor(
@@ -917,6 +934,7 @@ def box3d_overlap_naive(box1: torch.Tensor, box2: torch.Tensor):
917934
`iou = vol / (vol1 + vol2 - vol)`
918935
"""
919936
device = box1.device
937+
920938
# For boxes1 we compute the unit directions n1 corresponding to quad_faces
921939
n1 = box_planar_dir(box1) # (6, 3)
922940
# For boxes2 we compute the unit directions n2 corresponding to quad_faces

0 commit comments

Comments
 (0)