oriented-det 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- export/__init__.py +9 -0
- export/ort_runtime.py +67 -0
- export/postprocess.py +151 -0
- export/scripts/__init__.py +6 -0
- export/scripts/build_faster_rcnn_savedmodel.py +104 -0
- export/scripts/export_onnx.py +210 -0
- export/scripts/onnx_to_savedmodel.py +35 -0
- export/scripts/predict_savedmodel.py +94 -0
- export/scripts/save_predictions_tf.py +447 -0
- export/scripts/to_tflite.py +32 -0
- export/tests/test_export_onnx_optional.py +82 -0
- export/tests/test_export_wrappers.py +105 -0
- export/tests/test_faster_rcnn_export_parity.py +201 -0
- export/tests/test_ort_runtime.py +41 -0
- export/tf_serving_model.py +96 -0
- export/val_dataset.py +116 -0
- export/wrappers.py +161 -0
- oriented_det/__init__.py +77 -0
- oriented_det/cli/__init__.py +92 -0
- oriented_det/cli/train.py +18 -0
- oriented_det/configs/_base_/augmentation.json +21 -0
- oriented_det/configs/_base_/datasets/dota_le90.json +21 -0
- oriented_det/configs/_base_/fp16.json +5 -0
- oriented_det/configs/_base_/models/oriented_rcnn_r50.json +26 -0
- oriented_det/configs/_base_/models/rotated_faster_rcnn_r50.json +53 -0
- oriented_det/configs/_base_/models/rotated_retinanet_r50.json +30 -0
- oriented_det/configs/_base_/preprocessing.json +8 -0
- oriented_det/configs/_base_/schedules/1x.json +33 -0
- oriented_det/configs/config.schema.json +404 -0
- oriented_det/configs/oriented_rcnn/dota_le90_1x.json +121 -0
- oriented_det/configs/oriented_rcnn/dota_le90_3x.json +11 -0
- oriented_det/configs/rotated_faster_rcnn/dota_le90_1x.json +119 -0
- oriented_det/configs/rotated_faster_rcnn/dota_le90_3x.json +9 -0
- oriented_det/configs/rotated_retinanet/dota_le90_1x.json +107 -0
- oriented_det/configs/rotated_retinanet/dota_le90_3x.json +30 -0
- oriented_det/data/__init__.py +89 -0
- oriented_det/data/airbus_playground.py +611 -0
- oriented_det/data/dota.py +741 -0
- oriented_det/data/dota_classes.py +26 -0
- oriented_det/data/evaluation.py +648 -0
- oriented_det/data/flips.py +115 -0
- oriented_det/data/preprocessing.py +335 -0
- oriented_det/data/tiling.py +399 -0
- oriented_det/data/transforms.py +377 -0
- oriented_det/geometry/__init__.py +8 -0
- oriented_det/geometry/poly.py +127 -0
- oriented_det/geometry/qbox.py +63 -0
- oriented_det/geometry/rbox.py +250 -0
- oriented_det/geometry/transforms.py +266 -0
- oriented_det/models/__init__.py +36 -0
- oriented_det/models/backbones/__init__.py +11 -0
- oriented_det/models/backbones/resnet_fpn.py +79 -0
- oriented_det/models/backbones/utils.py +81 -0
- oriented_det/models/bbox_coder.py +355 -0
- oriented_det/models/faster_rcnn_inference.py +494 -0
- oriented_det/models/horizontal_roi_coder.py +155 -0
- oriented_det/models/oriented_rcnn.py +1256 -0
- oriented_det/models/oriented_roi.py +1664 -0
- oriented_det/models/oriented_rpn.py +2104 -0
- oriented_det/models/rotated_retinanet.py +1030 -0
- oriented_det/models/utils.py +590 -0
- oriented_det/ops/__init__.py +58 -0
- oriented_det/ops/gpu_ops.py +1109 -0
- oriented_det/ops/iou.py +172 -0
- oriented_det/ops/kfiou.py +275 -0
- oriented_det/ops/nms.py +202 -0
- oriented_det/ops/probiou.py +165 -0
- oriented_det/ops/rotated_ops.py +122 -0
- oriented_det/ops/utils.py +257 -0
- oriented_det/pretrained/__init__.py +23 -0
- oriented_det/pretrained/hub.py +249 -0
- oriented_det/pretrained/manifest.json +46 -0
- oriented_det/runtime/__init__.py +29 -0
- oriented_det/runtime/checkpoint.py +274 -0
- oriented_det/runtime/collate.py +348 -0
- oriented_det/runtime/inference.py +1286 -0
- oriented_det/train/__init__.py +102 -0
- oriented_det/train/config.py +872 -0
- oriented_det/train/engine.py +2933 -0
- oriented_det/train/grouped_ce.py +139 -0
- oriented_det/train/piecewise_schedule.py +33 -0
- oriented_det/train/profiler.py +287 -0
- oriented_det/train/utils.py +999 -0
- oriented_det/utils/__init__.py +31 -0
- oriented_det/utils/config.py +376 -0
- oriented_det/utils/device.py +35 -0
- oriented_det/utils/logging.py +163 -0
- oriented_det/utils/progress.py +62 -0
- oriented_det/utils/viz.py +181 -0
- oriented_det-0.1.0.dist-info/METADATA +313 -0
- oriented_det-0.1.0.dist-info/RECORD +115 -0
- oriented_det-0.1.0.dist-info/WHEEL +5 -0
- oriented_det-0.1.0.dist-info/entry_points.txt +2 -0
- oriented_det-0.1.0.dist-info/licenses/LICENSE +202 -0
- oriented_det-0.1.0.dist-info/top_level.txt +3 -0
- tools/__init__.py +1 -0
- tools/app.py +1284 -0
- tools/dataset_stats.py +389 -0
- tools/dota_labels_to_comma.py +132 -0
- tools/free_gpu.py +142 -0
- tools/generate_airbus_playground_csv.py +154 -0
- tools/image_demo.py +200 -0
- tools/lr_finder.py +771 -0
- tools/measure_sampled_riou_error.py +483 -0
- tools/playground_to_dota.py +290 -0
- tools/pretrained_download.py +49 -0
- tools/preview_augmentation.py +510 -0
- tools/publish_checkpoint.py +96 -0
- tools/save_predictions.py +2350 -0
- tools/sync_vendored_configs.py +94 -0
- tools/tile_dota.py +447 -0
- tools/train.py +2324 -0
- tools/train_example.py +244 -0
- tools/train_multi_gpu.py +367 -0
- tools/visualize_boxes.py +183 -0
tools/visualize_boxes.py
ADDED
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
"""Example: Visualizing oriented bounding boxes.
|
|
2
|
+
|
|
3
|
+
This script demonstrates how to:
|
|
4
|
+
1. Create and manipulate oriented boxes
|
|
5
|
+
2. Convert between different representations
|
|
6
|
+
3. Visualize boxes on images
|
|
7
|
+
4. Apply transformations
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import argparse
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
import sys
|
|
13
|
+
import math
|
|
14
|
+
|
|
15
|
+
try:
|
|
16
|
+
from PIL import Image
|
|
17
|
+
import numpy as np
|
|
18
|
+
except ImportError as e:
|
|
19
|
+
print(f"Required dependencies not installed: {e}")
|
|
20
|
+
print("Please install: pip install Pillow numpy")
|
|
21
|
+
sys.exit(1)
|
|
22
|
+
|
|
23
|
+
from oriented_det import Polygon, QBox, RBox, transforms
|
|
24
|
+
from oriented_det.utils import viz
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def create_example_boxes():
|
|
28
|
+
"""Create example oriented boxes for visualization."""
|
|
29
|
+
boxes = [
|
|
30
|
+
# Axis-aligned box
|
|
31
|
+
RBox(cx=100, cy=100, width=80, height=40, angle=0),
|
|
32
|
+
|
|
33
|
+
# Rotated box
|
|
34
|
+
RBox(cx=200, cy=150, width=60, height=30, angle=math.radians(45)),
|
|
35
|
+
|
|
36
|
+
# Another rotated box
|
|
37
|
+
RBox(cx=300, cy=200, width=100, height=50, angle=math.radians(-30)),
|
|
38
|
+
|
|
39
|
+
# Box from quadrilateral
|
|
40
|
+
QBox([(400, 100), (500, 120), (480, 200), (380, 180)]),
|
|
41
|
+
|
|
42
|
+
# Box from polygon
|
|
43
|
+
Polygon([(100, 250), (150, 240), (160, 290), (110, 300)]),
|
|
44
|
+
]
|
|
45
|
+
return boxes
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def demonstrate_conversions():
|
|
49
|
+
"""Demonstrate conversions between different box representations."""
|
|
50
|
+
print("Demonstrating box conversions:")
|
|
51
|
+
print("-" * 50)
|
|
52
|
+
|
|
53
|
+
# Start with an RBox
|
|
54
|
+
rbox = RBox(cx=256, cy=256, width=100, height=50, angle=math.radians(30))
|
|
55
|
+
print(f"Original RBox: cx={rbox.cx:.1f}, cy={rbox.cy:.1f}, "
|
|
56
|
+
f"w={rbox.width:.1f}, h={rbox.height:.1f}, angle={math.degrees(rbox.angle):.1f}°")
|
|
57
|
+
|
|
58
|
+
# Convert to QBox
|
|
59
|
+
qbox = transforms.rbox_to_qbox(rbox)
|
|
60
|
+
print(f"\nConverted to QBox:")
|
|
61
|
+
for i, point in enumerate(qbox.points):
|
|
62
|
+
print(f" Point {i+1}: ({point[0]:.1f}, {point[1]:.1f})")
|
|
63
|
+
|
|
64
|
+
# Convert to Polygon
|
|
65
|
+
poly = transforms.rbox_to_polygon(rbox)
|
|
66
|
+
print(f"\nConverted to Polygon:")
|
|
67
|
+
print(f" Area: {poly.area:.1f}")
|
|
68
|
+
print(f" Centroid: ({poly.centroid[0]:.1f}, {poly.centroid[1]:.1f})")
|
|
69
|
+
print(f" Bounds: {poly.bounds}")
|
|
70
|
+
|
|
71
|
+
# Round trip: RBox -> QBox -> RBox
|
|
72
|
+
recovered = transforms.qbox_to_rbox(qbox)
|
|
73
|
+
print(f"\nRound trip (RBox -> QBox -> RBox):")
|
|
74
|
+
print(f" Original angle: {math.degrees(rbox.angle):.1f}°")
|
|
75
|
+
print(f" Recovered angle: {math.degrees(recovered.angle):.1f}°")
|
|
76
|
+
print(f" Difference: {abs(rbox.angle - recovered.angle):.6f} rad")
|
|
77
|
+
print()
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def visualize_on_image(image_path: Path = None, output_path: Path = None):
|
|
81
|
+
"""Visualize boxes on an image.
|
|
82
|
+
|
|
83
|
+
Args:
|
|
84
|
+
image_path: Path to input image (creates blank if None)
|
|
85
|
+
output_path: Path to save visualization
|
|
86
|
+
"""
|
|
87
|
+
# Create or load image
|
|
88
|
+
if image_path and image_path.exists():
|
|
89
|
+
image = Image.open(image_path).convert("RGB")
|
|
90
|
+
print(f"Loaded image: {image.size}")
|
|
91
|
+
else:
|
|
92
|
+
# Create a blank image for demonstration
|
|
93
|
+
image = Image.new("RGB", (600, 400), color="white")
|
|
94
|
+
print("Created blank image for demonstration")
|
|
95
|
+
|
|
96
|
+
# Create example boxes
|
|
97
|
+
boxes = create_example_boxes()
|
|
98
|
+
print(f"\nVisualizing {len(boxes)} boxes:")
|
|
99
|
+
|
|
100
|
+
# Convert all to polygons for visualization
|
|
101
|
+
polygons = []
|
|
102
|
+
for i, box in enumerate(boxes):
|
|
103
|
+
if isinstance(box, RBox):
|
|
104
|
+
poly = box.to_polygon()
|
|
105
|
+
label = f"RBox {i+1}: {math.degrees(box.angle):.0f}°"
|
|
106
|
+
elif isinstance(box, QBox):
|
|
107
|
+
poly = box.to_polygon()
|
|
108
|
+
label = f"QBox {i+1}"
|
|
109
|
+
elif isinstance(box, Polygon):
|
|
110
|
+
poly = box
|
|
111
|
+
label = f"Polygon {i+1}"
|
|
112
|
+
else:
|
|
113
|
+
continue
|
|
114
|
+
|
|
115
|
+
polygons.append(poly.points)
|
|
116
|
+
print(f" Box {i+1}: {type(box).__name__}, area={poly.area:.1f}")
|
|
117
|
+
|
|
118
|
+
# Draw boxes
|
|
119
|
+
result = viz.draw_polygons(
|
|
120
|
+
image,
|
|
121
|
+
polygons,
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
# Save or show
|
|
125
|
+
if output_path:
|
|
126
|
+
result.save(output_path)
|
|
127
|
+
print(f"\nSaved visualization to: {output_path}")
|
|
128
|
+
else:
|
|
129
|
+
print("\nVisualization created (use --output to save)")
|
|
130
|
+
|
|
131
|
+
return result
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def demonstrate_transforms():
|
|
135
|
+
"""Demonstrate geometric transformations."""
|
|
136
|
+
print("\nDemonstrating transformations:")
|
|
137
|
+
print("-" * 50)
|
|
138
|
+
|
|
139
|
+
from oriented_det.data import HorizontalFlip, Rotate
|
|
140
|
+
|
|
141
|
+
rbox = RBox(cx=200, cy=150, width=80, height=40, angle=math.radians(30))
|
|
142
|
+
print(f"Original: cx={rbox.cx:.1f}, cy={rbox.cy:.1f}, angle={math.degrees(rbox.angle):.1f}°")
|
|
143
|
+
|
|
144
|
+
# Horizontal flip
|
|
145
|
+
flip = HorizontalFlip(p=1.0)
|
|
146
|
+
flipped = flip.apply_to_rbox(rbox, image_width=400, image_height=300)
|
|
147
|
+
print(f"Flipped: cx={flipped.cx:.1f}, cy={flipped.cy:.1f}, angle={math.degrees(flipped.angle):.1f}°")
|
|
148
|
+
|
|
149
|
+
# Rotation
|
|
150
|
+
rotate = Rotate(degrees=90, p=1.0)
|
|
151
|
+
rotated = rotate.apply_to_rbox(rbox, image_width=400, image_height=300)
|
|
152
|
+
print(f"Rotated: cx={rotated.cx:.1f}, cy={rotated.cy:.1f}, angle={math.degrees(rotated.angle):.1f}°")
|
|
153
|
+
print()
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
def main():
|
|
157
|
+
parser = argparse.ArgumentParser(description="Visualize oriented bounding boxes")
|
|
158
|
+
parser.add_argument("--image", type=Path, help="Input image path (creates blank if not provided)")
|
|
159
|
+
parser.add_argument("--output", type=Path, default=Path("visualization.png"),
|
|
160
|
+
help="Output image path")
|
|
161
|
+
parser.add_argument("--demo-conversions", action="store_true",
|
|
162
|
+
help="Demonstrate box conversions")
|
|
163
|
+
parser.add_argument("--demo-transforms", action="store_true",
|
|
164
|
+
help="Demonstrate transformations")
|
|
165
|
+
parser.add_argument("--all", action="store_true",
|
|
166
|
+
help="Run all demonstrations")
|
|
167
|
+
|
|
168
|
+
args = parser.parse_args()
|
|
169
|
+
|
|
170
|
+
if args.all or args.demo_conversions:
|
|
171
|
+
demonstrate_conversions()
|
|
172
|
+
|
|
173
|
+
if args.all or args.demo_transforms:
|
|
174
|
+
demonstrate_transforms()
|
|
175
|
+
|
|
176
|
+
# Always visualize
|
|
177
|
+
visualize_on_image(args.image, args.output)
|
|
178
|
+
|
|
179
|
+
print("\nDone!")
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
if __name__ == "__main__":
|
|
183
|
+
main()
|