Skip to content

Commit

Permalink
fix: feature selection error for zero area features
Browse files Browse the repository at this point in the history
  • Loading branch information
edparris committed Sep 19, 2024
1 parent 7963917 commit 4d6ee82
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 0 deletions.
16 changes: 16 additions & 0 deletions src/aws/osml/model_runner/inference/feature_selection.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,22 @@ def _get_lists_from_features(self, feature_list: List[Feature]) -> Tuple[List, L
for feature in feature_list:
# [min_x, min_y, max_x, max_y]
bounds_imcoords = get_feature_image_bounds(feature)

# This is a workaround for assumptions made by the NMS library and normalization code in this class.
# All of that code assumes that features have bounding boxes with a non-zero area. That assumption
# does not hold for features reported as a single point geometry or others that might simply be
# erroneously reported with a zero width or height bbox. No matter the cause, we would like those
# features to pass through our feature selection processing without triggering errors. Here we
# add 0.1 of a pixel to the width or height of any bbox if it is currently zero. This does not change
# the actual reported geometry of the feature in any way it just ensures the assumption of a non-zero
# area is true.
bounds_imcoords = (
bounds_imcoords[0],
bounds_imcoords[1],
bounds_imcoords[2] + 0.1 if bounds_imcoords[0] == bounds_imcoords[2] else bounds_imcoords[2],
bounds_imcoords[3] + 0.1 if bounds_imcoords[1] == bounds_imcoords[3] else bounds_imcoords[3],
)

category, score = self._get_category_and_score_from_feature(feature)
boxes.append(bounds_imcoords)
categories.append(category)
Expand Down
20 changes: 20 additions & 0 deletions test/aws/osml/model_runner/inference/test_feature_selection.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,26 @@ def test_feature_selection_nms_overlaps_multiple_categories(self):
processed_features = feature_selector.select_features(original_features)
assert len(processed_features) == 3

def test_feature_selection_nms_point_feature(self):
from aws.osml.model_runner.common import FeatureDistillationNMS
from aws.osml.model_runner.inference import FeatureSelector

feature_selection_option = FeatureDistillationNMS()
feature_selector = FeatureSelector(options=feature_selection_option)

test_feature = [
Feature(
geometry=Point((85.000111, 32.983222, 0.0)),
id="point-feature",
properties={
"bounds_imcoords": [409.6, 409.6, 409.6, 409.6],
"featureClasses": [{"iri": "boat", "score": 0.85}],
},
)
]
processed_features = feature_selector.select_features(test_feature)
assert len(processed_features) == 1

def test_feature_selection_soft_nms_overlaps(self):
from aws.osml.model_runner.common import FeatureDistillationSoftNMS
from aws.osml.model_runner.inference import FeatureSelector
Expand Down

0 comments on commit 4d6ee82

Please sign in to comment.