Postprocessing
Functions for cleaning up raw detections: non-maximum suppression across and within tiles, polygon
hole suppression, tile boundary suppression, masking, and filtering by canopy height. Most of these
operate on the standardized RegionDetections and RegionDetectionsSet types.
postprocessing
¶
Attributes¶
Classes¶
Functions:¶
NMS_on_points(detections, threshold_distance)
¶
Run non-max suppression on point data, suppressing points within a thereshold distance of higher-score points
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
detections
|
Union[RegionDetections, RegionDetectionsSet]
|
The input data to run NMS on. Can either be a RegionDetections or RegionDetectionsSet object. |
required |
threshold_distance
|
float
|
Detections within this distance of each other are suppressed |
required |
Returns:
| Name | Type | Description |
|---|---|---|
RegionDetections |
RegionDetections
|
The NMS-suppressed detections with all the original attributes |
Source code in tree_detection_framework/postprocessing/postprocessing.py
filter_by_chm(outputs, chm_path, min_height=10.0)
¶
Filter tree detections by canopy height model (CHM) values.
A detection is kept if
- max CHM value within geometry >= min_height, OR
- the detection does not fully overlap the CHM
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
outputs
|
Union[RegionDetections, RegionDetectionsSet]
|
The detections to filter |
required |
chm_path
|
str
|
Path to the canopy height model raster file |
required |
min_height
|
float
|
Minimum height threshold for filtering detections |
10.0
|
Returns:
| Name | Type | Description |
|---|---|---|
RegionDetections |
RegionDetections
|
Filtered detections that meet the height criteria |
Source code in tree_detection_framework/postprocessing/postprocessing.py
734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 | |
merge_and_postprocess_detections(detections, tolerance=0.2, min_area_threshold=20.0)
¶
Apply postprocessing techniques that include:
1. Get a union of polygons that have been split across tiles
2. Simplify the edges of polygons by tolerance value
3. Remove holes within the polygons that are smaller than min_area_threshold value
Merges regions into a single RegionDetections.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
detections
|
RegionDetectionsSet
|
Detections from multiple regions to postprocess. |
required |
tolerance
|
Optional[float]
|
A value that controls the simplification of the detection polygons. The higher this value, the smaller the number of vertices in the resulting geometry. |
0.2
|
min_area_threshold
|
Optional[float]
|
Holes within polygons having an area lesser than this value get removed. |
20.0
|
Returns:
| Name | Type | Description |
|---|---|---|
RegionDetections |
RegionDetections
|
Postprocessed set of detections, merged together for the set of regions. |
Source code in tree_detection_framework/postprocessing/postprocessing.py
multi_region_NMS(detections, run_per_region_NMS=True, threshold=0.5, confidence_column='score', min_confidence=0.3, intersection_method='IOU')
¶
Run non-max suppression on predictions from multiple regions.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
detections
|
RegionDetectionsSet
|
Detections from multiple regions to run NMS on. |
required |
run_per_region_NMS
|
bool
|
Should nonmax-suppression be run on each region before the regions are merged. This may lead to a speedup if there is a large amount of within-region overlap. Defaults to True. |
True
|
threshold
|
float
|
The threshold for the NMS(intersection) method. Defaults to 0.5. |
0.5
|
confidence_column
|
str
|
Which column in the dataframe to use as a confidence for NMS. Defaults to "score" |
'score'
|
min_confidence
|
float
|
Prediction score threshold for detections to be included. |
0.3
|
intersection_method
|
str
|
The method to compute intersections, one of ("IOU", "IOS", "Dice", "IOT"). Defaults to "IOU". |
'IOU'
|
Returns: RegionDetections: NMS-suppressed set of detections, merged together for the set of regions.
Source code in tree_detection_framework/postprocessing/postprocessing.py
multi_region_hole_suppression(detections, min_area_threshold=20.0)
¶
Suppress polygon holes in a RegionDetectionsSet object.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
detections
|
RegionDetectionsSet
|
Set of detections from a multiple regions that need suppression of polygon holes. |
required |
min_area_threshold
|
float
|
Remove holes within the polygons that have area smaller than this value. |
20.0
|
Returns:
| Name | Type | Description |
|---|---|---|
RegionDetectionsSet |
Set of detections after suppressing polygon holes. |
Source code in tree_detection_framework/postprocessing/postprocessing.py
polygon_hole_suppression(polygon, min_area_threshold=20.0)
¶
To remove holes within a polygon
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
polygon
|
Polygon
|
A shapely polygon object |
required |
min_area_threshold
|
float
|
Remove holes within the polygons that have area smaller than this value |
20.0
|
Returns:
| Type | Description |
|---|---|
|
shapely.Polygon: The equivalent polygon created after suppressing the holes |
Source code in tree_detection_framework/postprocessing/postprocessing.py
remove_detections_from_tile_overlap(detections, retain_method='within')
¶
Remove detections in overlapping regions of tiles by defining a central "core" area of each tile which is farthest from the boundary and keeping detections within that region.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
detections
|
RegionDetectionsSet
|
The detections to suppress |
required |
retain_method
|
str
|
How to deal with edge detections. "within" keeps detections that are fully within the interior region, "intersects" keeps any that touch the interior region, and "clip" clips detections on the boundary so only the portion within the interior is retained. Defaults to "within". |
'within'
|
Returns:
| Name | Type | Description |
|---|---|---|
RegionDetectionsSet |
RegionDetectionsSet
|
Updated detections |
Source code in tree_detection_framework/postprocessing/postprocessing.py
remove_masked_detections(region_detection_sets, mask_iterator, threshold=0.4)
¶
Filters out detections that marked as invalid in the given masks.
Returns:
| Type | Description |
|---|---|
List[RegionDetectionsSet]
|
List of RegiondetectionSet objects with masked predictions filtered out (one per |
List[RegionDetectionsSet]
|
image) OR list of geospatial dataframes (one per image). This is based on the |
List[RegionDetectionsSet]
|
input type of region_detection_sets |
Source code in tree_detection_framework/postprocessing/postprocessing.py
630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 | |
remove_maskfile_detections(region_detection_sets, image_root, image_paths, valid_classes, mask_root, mask_extension='.png', threshold=0.4)
¶
Filters out detections that marked as invalid in the given mask images. One example use case is that mask images could be rastered where the certain pixels are marked as "ground" vs. "above ground". Then detections that mostly overlap with the "ground" mask could be removed.
Returns:
| Type | Description |
|---|---|
Union[List[RegionDetectionsSet], List[GeoDataFrame]]
|
List of RegiondetectionSet objects with masked predictions filtered out (one per |
Union[List[RegionDetectionsSet], List[GeoDataFrame]]
|
image) OR list of geospatial dataframes (one per image). This is based on the |
Union[List[RegionDetectionsSet], List[GeoDataFrame]]
|
input type of region_detection_sets |
Source code in tree_detection_framework/postprocessing/postprocessing.py
550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 | |
remove_out_of_bounds_detections(region_detection_sets, image_bounds)
¶
Filters out detections that are outside the bounds of a defined region.
Used as a post-processing step after predict_raw_drone_images().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
region_detection_sets
|
List[RegionDetectionSet]
|
Each elemet is a RegionDetectionsSet derived from a specific drone image. Length is the number of raw drone images given to the dataloader. |
required |
image_bounds
|
List[bounding_box]
|
Each element is a |
required |
Returns:
| Type | Description |
|---|---|
List[RegionDetectionsSet]
|
List of RegiondetectionSet objects with out-of-bounds predictions filtered out. |
Source code in tree_detection_framework/postprocessing/postprocessing.py
single_region_NMS(detections, threshold=0.5, confidence_column='score', min_confidence=0.3, intersection_method='IOU')
¶
Run non-max suppression on predictions from a single region.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
detections
|
RegionDetections
|
Detections from a single region to run NMS on. |
required |
threshold
|
float
|
The threshold for the NMS(intersection) method. Defaults to 0.5. |
0.5
|
confidence_column
|
str
|
Which column in the dataframe to use as a confidence for NMS. Defaults to "score" |
'score'
|
min_confidence
|
float
|
Prediction score threshold for detections to be included. |
0.3
|
intersection_method
|
str
|
The method to compute intersections, one of ("IOU", "IOS", "Dice", "IOT"). Defaults to "IOU". |
'IOU'
|
Returns:
| Name | Type | Description |
|---|---|---|
RegionDetections |
RegionDetections
|
NMS-suppressed set of detections |
Source code in tree_detection_framework/postprocessing/postprocessing.py
single_region_hole_suppression(detections, min_area_threshold=20.0)
¶
Suppress polygon holes in a RegionDetections object.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
detections
|
RegionDetections
|
Detections from a single region that needs suppression of polygon holes. |
required |
min_area_threshold
|
float
|
Remove holes within the polygons that have area smaller than this value. |
20.0
|
Returns:
| Name | Type | Description |
|---|---|---|
RegionDetections |
Detections after suppressing polygon holes. |
Source code in tree_detection_framework/postprocessing/postprocessing.py
suppress_tile_boundary_with_NMS(predictions, iou_threshold=0.5, ios_threshold=0.5, min_confidence=0.3)
¶
Used as a post-processing step with the GeometricDetector class to suppress detections that are split across tiles.
This is done by applying NMS twice, first using IOU and then using IOS.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
predictions
|
RegionDetectionsSet
|
Detections from multiple regions. |
required |
iou_threshold
|
float
|
The threshold for the NMS method that uses IoU metric. Defaults to 0.5. |
0.5
|
ios_threshold
|
float
|
The threshold for the NMS method that uses IoS metric. Defaults to 0.5. |
0.5
|
min_confidence
|
float
|
Prediction score threshold for detections to be included. |
0.3
|
Returns:
| Name | Type | Description |
|---|---|---|
RegionDetections |
RegionDetections
|
NMS postprocessed set of detections, merged together. |
Source code in tree_detection_framework/postprocessing/postprocessing.py
update_gdf_to_centroid(gdf)
¶
Return the geodataframe with the geometry updated to be the centroid Point
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
gdf
|
GeoDataFrame
|
A dataframe to convert |
required |
Returns:
| Name | Type | Description |
|---|---|---|
GeoDataFrame |
GeoDataFrame
|
the input geodataframe with the geometry updated to be the centroid Point |