mblt-vision-python 0.0.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.
- mblt_vision/__init__.py +86 -0
- mblt_vision/_api.py +53 -0
- mblt_vision/_compat.py +227 -0
- mblt_vision/_model_paths.py +137 -0
- mblt_vision/_tasks.py +30 -0
- mblt_vision/benchmark/__init__.py +1 -0
- mblt_vision/benchmark/argparse_utils.py +106 -0
- mblt_vision/benchmark/chart_utils.py +146 -0
- mblt_vision/benchmark/io_utils.py +64 -0
- mblt_vision/benchmark/summary_utils.py +770 -0
- mblt_vision/cli/__init__.py +5 -0
- mblt_vision/cli/__main__.py +5 -0
- mblt_vision/cli/_vision.py +337 -0
- mblt_vision/cli/compile.py +117 -0
- mblt_vision/cli/main.py +35 -0
- mblt_vision/cli/predict.py +64 -0
- mblt_vision/cli/val.py +562 -0
- mblt_vision/compile/__init__.py +21 -0
- mblt_vision/compile/vision.py +1120 -0
- mblt_vision/datasets/__init__.py +15 -0
- mblt_vision/datasets/ade20k.yaml +164 -0
- mblt_vision/datasets/cityscapes.yaml +54 -0
- mblt_vision/datasets/coco.yaml +178 -0
- mblt_vision/datasets/dotav1.yaml +28 -0
- mblt_vision/datasets/imagenet.yaml +1019 -0
- mblt_vision/datasets/imagenet_synsets.txt +1000 -0
- mblt_vision/datasets/nyu-depth.yaml +7 -0
- mblt_vision/datasets/registry.py +158 -0
- mblt_vision/datasets/widerface.yaml +9 -0
- mblt_vision/depth_estimation/__init__.py +19 -0
- mblt_vision/face_detection/__init__.py +43 -0
- mblt_vision/image_classification/__init__.py +311 -0
- mblt_vision/instance_segmentation/__init__.py +65 -0
- mblt_vision/models/AlexNet.yaml +23 -0
- mblt_vision/models/CAFormer_B36.yaml +22 -0
- mblt_vision/models/CAFormer_M36.yaml +22 -0
- mblt_vision/models/CAFormer_S18.yaml +22 -0
- mblt_vision/models/CAFormer_S36.yaml +22 -0
- mblt_vision/models/CoAtNet_0_RW_224.yaml +22 -0
- mblt_vision/models/CoAtNet_1_RW_224.yaml +22 -0
- mblt_vision/models/CoAtNet_2_RW_224.yaml +22 -0
- mblt_vision/models/ConvFormer_B36.yaml +22 -0
- mblt_vision/models/ConvFormer_M36.yaml +22 -0
- mblt_vision/models/ConvFormer_S18.yaml +22 -0
- mblt_vision/models/ConvFormer_S36.yaml +22 -0
- mblt_vision/models/ConvNext_Base.yaml +23 -0
- mblt_vision/models/ConvNext_Large.yaml +23 -0
- mblt_vision/models/ConvNext_Small.yaml +23 -0
- mblt_vision/models/ConvNext_Tiny.yaml +23 -0
- mblt_vision/models/DeiT3_Base_Patch16_224.yaml +22 -0
- mblt_vision/models/DeiT3_Base_Patch16_384.yaml +22 -0
- mblt_vision/models/DeiT3_Large_Patch16_224.yaml +22 -0
- mblt_vision/models/DeiT3_Large_Patch16_384.yaml +22 -0
- mblt_vision/models/DeiT3_Medium_Patch16_224.yaml +22 -0
- mblt_vision/models/DeiT3_Small_Patch16_224.yaml +22 -0
- mblt_vision/models/DeiT3_Small_Patch16_384.yaml +22 -0
- mblt_vision/models/DeiT_Base_Patch16_224.yaml +22 -0
- mblt_vision/models/DeiT_Base_Patch16_384.yaml +22 -0
- mblt_vision/models/DeiT_Small_Patch16_224.yaml +22 -0
- mblt_vision/models/DeiT_Tiny_Patch16_224.yaml +22 -0
- mblt_vision/models/DenseNet121.yaml +23 -0
- mblt_vision/models/DenseNet161.yaml +23 -0
- mblt_vision/models/DenseNet169.yaml +23 -0
- mblt_vision/models/DenseNet201.yaml +23 -0
- mblt_vision/models/EfficientFormer_L1.yaml +22 -0
- mblt_vision/models/EfficientFormer_L3.yaml +22 -0
- mblt_vision/models/EfficientFormer_L7.yaml +22 -0
- mblt_vision/models/EfficientNet_B0.yaml +23 -0
- mblt_vision/models/EfficientNet_B1.yaml +32 -0
- mblt_vision/models/EfficientNet_B2.yaml +23 -0
- mblt_vision/models/EfficientNet_B3.yaml +23 -0
- mblt_vision/models/EfficientNet_B4.yaml +23 -0
- mblt_vision/models/EfficientNet_B5.yaml +23 -0
- mblt_vision/models/EfficientNet_B6.yaml +23 -0
- mblt_vision/models/EfficientNet_B7.yaml +23 -0
- mblt_vision/models/EfficientNet_V2_L.yaml +23 -0
- mblt_vision/models/EfficientNet_V2_M.yaml +23 -0
- mblt_vision/models/EfficientNet_V2_S.yaml +23 -0
- mblt_vision/models/FlexiVit_Base.yaml +22 -0
- mblt_vision/models/FlexiVit_Large.yaml +22 -0
- mblt_vision/models/FlexiVit_Small.yaml +22 -0
- mblt_vision/models/GELANc-seg.yaml +29 -0
- mblt_vision/models/GELANc.yaml +28 -0
- mblt_vision/models/GELANe.yaml +28 -0
- mblt_vision/models/GELANm.yaml +28 -0
- mblt_vision/models/GELANs.yaml +28 -0
- mblt_vision/models/GoogLeNet.yaml +23 -0
- mblt_vision/models/Inception_V3.yaml +23 -0
- mblt_vision/models/LeViT_Conv_128.yaml +22 -0
- mblt_vision/models/LeViT_Conv_128S.yaml +22 -0
- mblt_vision/models/LeViT_Conv_192.yaml +22 -0
- mblt_vision/models/LeViT_Conv_256.yaml +22 -0
- mblt_vision/models/LeViT_Conv_384.yaml +22 -0
- mblt_vision/models/MNASNet0_5.yaml +23 -0
- mblt_vision/models/MNASNet0_75.yaml +23 -0
- mblt_vision/models/MNASNet1_0.yaml +23 -0
- mblt_vision/models/MNASNet1_3.yaml +23 -0
- mblt_vision/models/MobileNet_V2.yaml +32 -0
- mblt_vision/models/MobileNet_V3_Large.yaml +32 -0
- mblt_vision/models/MobileNet_V3_Small.yaml +23 -0
- mblt_vision/models/RegNet_X_16GF.yaml +32 -0
- mblt_vision/models/RegNet_X_1_6GF.yaml +32 -0
- mblt_vision/models/RegNet_X_32GF.yaml +32 -0
- mblt_vision/models/RegNet_X_3_2GF.yaml +32 -0
- mblt_vision/models/RegNet_X_400MF.yaml +32 -0
- mblt_vision/models/RegNet_X_800MF.yaml +32 -0
- mblt_vision/models/RegNet_X_8GF.yaml +32 -0
- mblt_vision/models/RegNet_Y_16GF.yaml +76 -0
- mblt_vision/models/RegNet_Y_1_6GF.yaml +32 -0
- mblt_vision/models/RegNet_Y_32GF.yaml +76 -0
- mblt_vision/models/RegNet_Y_3_2GF.yaml +32 -0
- mblt_vision/models/RegNet_Y_400MF.yaml +32 -0
- mblt_vision/models/RegNet_Y_800MF.yaml +32 -0
- mblt_vision/models/RegNet_Y_8GF.yaml +32 -0
- mblt_vision/models/RepViT_M0_9.yaml +22 -0
- mblt_vision/models/RepViT_M1.yaml +22 -0
- mblt_vision/models/RepViT_M1_0.yaml +22 -0
- mblt_vision/models/RepViT_M1_1.yaml +22 -0
- mblt_vision/models/RepViT_M1_5.yaml +22 -0
- mblt_vision/models/RepViT_M2.yaml +22 -0
- mblt_vision/models/RepViT_M2_3.yaml +22 -0
- mblt_vision/models/RepViT_M3.yaml +22 -0
- mblt_vision/models/ResNeXt101_32X8D.yaml +32 -0
- mblt_vision/models/ResNeXt101_64X4D.yaml +23 -0
- mblt_vision/models/ResNeXt50_32X4D.yaml +32 -0
- mblt_vision/models/ResNet101.yaml +32 -0
- mblt_vision/models/ResNet152.yaml +32 -0
- mblt_vision/models/ResNet18.yaml +23 -0
- mblt_vision/models/ResNet34.yaml +23 -0
- mblt_vision/models/ResNet50.yaml +32 -0
- mblt_vision/models/ShuffleNet_V2_X0_5.yaml +23 -0
- mblt_vision/models/ShuffleNet_V2_X1_0.yaml +23 -0
- mblt_vision/models/ShuffleNet_V2_X1_5.yaml +23 -0
- mblt_vision/models/ShuffleNet_V2_X2_0.yaml +23 -0
- mblt_vision/models/SqueezeNet1_0.yaml +23 -0
- mblt_vision/models/SqueezeNet1_1.yaml +23 -0
- mblt_vision/models/Swin_B.yaml +23 -0
- mblt_vision/models/Swin_S.yaml +23 -0
- mblt_vision/models/Swin_T.yaml +23 -0
- mblt_vision/models/VGG11.yaml +23 -0
- mblt_vision/models/VGG11_BN.yaml +23 -0
- mblt_vision/models/VGG13.yaml +23 -0
- mblt_vision/models/VGG13_BN.yaml +23 -0
- mblt_vision/models/VGG16.yaml +23 -0
- mblt_vision/models/VGG16_BN.yaml +23 -0
- mblt_vision/models/VGG19.yaml +23 -0
- mblt_vision/models/VGG19_BN.yaml +23 -0
- mblt_vision/models/ViT_B_16.yaml +67 -0
- mblt_vision/models/ViT_B_32.yaml +23 -0
- mblt_vision/models/ViT_Base_Patch16_224.yaml +22 -0
- mblt_vision/models/ViT_Base_Patch16_384.yaml +22 -0
- mblt_vision/models/ViT_Base_Patch32_224.yaml +22 -0
- mblt_vision/models/ViT_Base_Patch32_384.yaml +22 -0
- mblt_vision/models/ViT_Base_Patch8_224.yaml +22 -0
- mblt_vision/models/ViT_L_16.yaml +67 -0
- mblt_vision/models/ViT_L_32.yaml +23 -0
- mblt_vision/models/ViT_Large_Patch16_224.yaml +22 -0
- mblt_vision/models/ViT_Large_Patch16_384.yaml +22 -0
- mblt_vision/models/ViT_Large_Patch32_384.yaml +22 -0
- mblt_vision/models/ViT_Small_Patch16_224.yaml +22 -0
- mblt_vision/models/ViT_Small_Patch16_384.yaml +22 -0
- mblt_vision/models/ViT_Small_Patch32_224.yaml +22 -0
- mblt_vision/models/ViT_Small_Patch32_384.yaml +22 -0
- mblt_vision/models/ViT_Tiny_Patch16_224.yaml +22 -0
- mblt_vision/models/ViT_Tiny_Patch16_384.yaml +22 -0
- mblt_vision/models/VisFormer_Small.yaml +22 -0
- mblt_vision/models/VisFormer_Tiny.yaml +22 -0
- mblt_vision/models/Wide_ResNet101_2.yaml +32 -0
- mblt_vision/models/Wide_ResNet50_2.yaml +32 -0
- mblt_vision/models/YOLO11l-cls.yaml +23 -0
- mblt_vision/models/YOLO11l-face.yaml +27 -0
- mblt_vision/models/YOLO11l-obb.yaml +28 -0
- mblt_vision/models/YOLO11l-pose.yaml +28 -0
- mblt_vision/models/YOLO11l-seg.yaml +28 -0
- mblt_vision/models/YOLO11l.yaml +27 -0
- mblt_vision/models/YOLO11m-cls.yaml +23 -0
- mblt_vision/models/YOLO11m-face.yaml +27 -0
- mblt_vision/models/YOLO11m-obb.yaml +28 -0
- mblt_vision/models/YOLO11m-pose.yaml +28 -0
- mblt_vision/models/YOLO11m-seg.yaml +28 -0
- mblt_vision/models/YOLO11m.yaml +27 -0
- mblt_vision/models/YOLO11n-cls.yaml +23 -0
- mblt_vision/models/YOLO11n-face.yaml +27 -0
- mblt_vision/models/YOLO11n-obb.yaml +28 -0
- mblt_vision/models/YOLO11n-pose.yaml +28 -0
- mblt_vision/models/YOLO11n-seg.yaml +28 -0
- mblt_vision/models/YOLO11n.yaml +27 -0
- mblt_vision/models/YOLO11s-cls.yaml +23 -0
- mblt_vision/models/YOLO11s-face.yaml +27 -0
- mblt_vision/models/YOLO11s-obb.yaml +28 -0
- mblt_vision/models/YOLO11s-pose.yaml +28 -0
- mblt_vision/models/YOLO11s-seg.yaml +28 -0
- mblt_vision/models/YOLO11s.yaml +27 -0
- mblt_vision/models/YOLO11x-cls.yaml +23 -0
- mblt_vision/models/YOLO11x-obb.yaml +28 -0
- mblt_vision/models/YOLO11x-pose.yaml +28 -0
- mblt_vision/models/YOLO11x-seg.yaml +28 -0
- mblt_vision/models/YOLO11x.yaml +27 -0
- mblt_vision/models/YOLO12l-face.yaml +27 -0
- mblt_vision/models/YOLO12l-seg.yaml +28 -0
- mblt_vision/models/YOLO12l.yaml +27 -0
- mblt_vision/models/YOLO12m-face.yaml +27 -0
- mblt_vision/models/YOLO12m-seg.yaml +28 -0
- mblt_vision/models/YOLO12m.yaml +27 -0
- mblt_vision/models/YOLO12n-face.yaml +27 -0
- mblt_vision/models/YOLO12n-seg.yaml +28 -0
- mblt_vision/models/YOLO12n.yaml +27 -0
- mblt_vision/models/YOLO12s-face.yaml +27 -0
- mblt_vision/models/YOLO12s-seg.yaml +28 -0
- mblt_vision/models/YOLO12s.yaml +27 -0
- mblt_vision/models/YOLO12x-seg.yaml +28 -0
- mblt_vision/models/YOLO12x.yaml +27 -0
- mblt_vision/models/YOLO26l-cls.yaml +23 -0
- mblt_vision/models/YOLO26l-depth.yaml +17 -0
- mblt_vision/models/YOLO26l-distill.yaml +27 -0
- mblt_vision/models/YOLO26l-obb.yaml +28 -0
- mblt_vision/models/YOLO26l-pose.yaml +28 -0
- mblt_vision/models/YOLO26l-seg.yaml +28 -0
- mblt_vision/models/YOLO26l-sem-ade20k.yaml +17 -0
- mblt_vision/models/YOLO26l-sem.yaml +17 -0
- mblt_vision/models/YOLO26l.yaml +27 -0
- mblt_vision/models/YOLO26m-cls.yaml +23 -0
- mblt_vision/models/YOLO26m-depth.yaml +17 -0
- mblt_vision/models/YOLO26m-distill.yaml +27 -0
- mblt_vision/models/YOLO26m-obb.yaml +28 -0
- mblt_vision/models/YOLO26m-pose.yaml +28 -0
- mblt_vision/models/YOLO26m-seg.yaml +28 -0
- mblt_vision/models/YOLO26m-sem-ade20k.yaml +17 -0
- mblt_vision/models/YOLO26m-sem.yaml +17 -0
- mblt_vision/models/YOLO26m.yaml +27 -0
- mblt_vision/models/YOLO26n-cls.yaml +23 -0
- mblt_vision/models/YOLO26n-depth.yaml +17 -0
- mblt_vision/models/YOLO26n-distill.yaml +27 -0
- mblt_vision/models/YOLO26n-obb.yaml +28 -0
- mblt_vision/models/YOLO26n-pose.yaml +28 -0
- mblt_vision/models/YOLO26n-seg.yaml +28 -0
- mblt_vision/models/YOLO26n-sem-ade20k.yaml +17 -0
- mblt_vision/models/YOLO26n-sem.yaml +17 -0
- mblt_vision/models/YOLO26n.yaml +27 -0
- mblt_vision/models/YOLO26s-cls.yaml +23 -0
- mblt_vision/models/YOLO26s-depth.yaml +17 -0
- mblt_vision/models/YOLO26s-distill.yaml +27 -0
- mblt_vision/models/YOLO26s-obb.yaml +28 -0
- mblt_vision/models/YOLO26s-pose.yaml +28 -0
- mblt_vision/models/YOLO26s-seg.yaml +28 -0
- mblt_vision/models/YOLO26s-sem-ade20k.yaml +17 -0
- mblt_vision/models/YOLO26s-sem.yaml +17 -0
- mblt_vision/models/YOLO26s.yaml +27 -0
- mblt_vision/models/YOLO26x-cls.yaml +23 -0
- mblt_vision/models/YOLO26x-depth.yaml +17 -0
- mblt_vision/models/YOLO26x-distill.yaml +27 -0
- mblt_vision/models/YOLO26x-obb.yaml +28 -0
- mblt_vision/models/YOLO26x-pose.yaml +28 -0
- mblt_vision/models/YOLO26x-seg.yaml +28 -0
- mblt_vision/models/YOLO26x-sem-ade20k.yaml +17 -0
- mblt_vision/models/YOLO26x-sem.yaml +17 -0
- mblt_vision/models/YOLO26x.yaml +27 -0
- mblt_vision/models/YOLOv10b.yaml +28 -0
- mblt_vision/models/YOLOv10l-face.yaml +28 -0
- mblt_vision/models/YOLOv10l.yaml +28 -0
- mblt_vision/models/YOLOv10m-face.yaml +28 -0
- mblt_vision/models/YOLOv10m.yaml +28 -0
- mblt_vision/models/YOLOv10n-face.yaml +28 -0
- mblt_vision/models/YOLOv10n.yaml +28 -0
- mblt_vision/models/YOLOv10s-face.yaml +28 -0
- mblt_vision/models/YOLOv10s.yaml +28 -0
- mblt_vision/models/YOLOv10x.yaml +28 -0
- mblt_vision/models/YOLOv3-spp.yaml +44 -0
- mblt_vision/models/YOLOv3-sppu.yaml +27 -0
- mblt_vision/models/YOLOv3-tiny.yaml +38 -0
- mblt_vision/models/YOLOv3-tinyu.yaml +27 -0
- mblt_vision/models/YOLOv3.yaml +44 -0
- mblt_vision/models/YOLOv3u.yaml +27 -0
- mblt_vision/models/YOLOv5l-cls.yaml +22 -0
- mblt_vision/models/YOLOv5l-seg.yaml +45 -0
- mblt_vision/models/YOLOv5l.yaml +44 -0
- mblt_vision/models/YOLOv5l6.yaml +50 -0
- mblt_vision/models/YOLOv5l6u.yaml +27 -0
- mblt_vision/models/YOLOv5lu.yaml +27 -0
- mblt_vision/models/YOLOv5m-cls.yaml +22 -0
- mblt_vision/models/YOLOv5m-seg.yaml +45 -0
- mblt_vision/models/YOLOv5m.yaml +45 -0
- mblt_vision/models/YOLOv5m6.yaml +50 -0
- mblt_vision/models/YOLOv5m6u.yaml +27 -0
- mblt_vision/models/YOLOv5mu.yaml +27 -0
- mblt_vision/models/YOLOv5n-cls.yaml +22 -0
- mblt_vision/models/YOLOv5n-seg.yaml +45 -0
- mblt_vision/models/YOLOv5n.yaml +44 -0
- mblt_vision/models/YOLOv5n6.yaml +50 -0
- mblt_vision/models/YOLOv5n6u.yaml +27 -0
- mblt_vision/models/YOLOv5nu.yaml +27 -0
- mblt_vision/models/YOLOv5s-cls.yaml +22 -0
- mblt_vision/models/YOLOv5s-seg.yaml +45 -0
- mblt_vision/models/YOLOv5s.yaml +44 -0
- mblt_vision/models/YOLOv5s6.yaml +50 -0
- mblt_vision/models/YOLOv5s6u.yaml +27 -0
- mblt_vision/models/YOLOv5su.yaml +27 -0
- mblt_vision/models/YOLOv5x-cls.yaml +22 -0
- mblt_vision/models/YOLOv5x-seg.yaml +45 -0
- mblt_vision/models/YOLOv5x.yaml +44 -0
- mblt_vision/models/YOLOv5x6.yaml +50 -0
- mblt_vision/models/YOLOv5x6u.yaml +27 -0
- mblt_vision/models/YOLOv5xu.yaml +27 -0
- mblt_vision/models/YOLOv6m-face.yaml +27 -0
- mblt_vision/models/YOLOv6n-face.yaml +27 -0
- mblt_vision/models/YOLOv7.yaml +44 -0
- mblt_vision/models/YOLOv7d6.yaml +50 -0
- mblt_vision/models/YOLOv7e6.yaml +50 -0
- mblt_vision/models/YOLOv7e6e.yaml +50 -0
- mblt_vision/models/YOLOv7w6.yaml +50 -0
- mblt_vision/models/YOLOv7x.yaml +44 -0
- mblt_vision/models/YOLOv8l-cls.yaml +23 -0
- mblt_vision/models/YOLOv8l-face.yaml +27 -0
- mblt_vision/models/YOLOv8l-obb.yaml +28 -0
- mblt_vision/models/YOLOv8l-pose.yaml +28 -0
- mblt_vision/models/YOLOv8l-seg.yaml +28 -0
- mblt_vision/models/YOLOv8l.yaml +27 -0
- mblt_vision/models/YOLOv8m-cls.yaml +23 -0
- mblt_vision/models/YOLOv8m-face.yaml +27 -0
- mblt_vision/models/YOLOv8m-obb.yaml +28 -0
- mblt_vision/models/YOLOv8m-pose.yaml +28 -0
- mblt_vision/models/YOLOv8m-seg.yaml +28 -0
- mblt_vision/models/YOLOv8m.yaml +27 -0
- mblt_vision/models/YOLOv8n-cls.yaml +23 -0
- mblt_vision/models/YOLOv8n-face.yaml +27 -0
- mblt_vision/models/YOLOv8n-obb.yaml +28 -0
- mblt_vision/models/YOLOv8n-pose.yaml +28 -0
- mblt_vision/models/YOLOv8n-seg.yaml +28 -0
- mblt_vision/models/YOLOv8n.yaml +27 -0
- mblt_vision/models/YOLOv8s-cls.yaml +23 -0
- mblt_vision/models/YOLOv8s-obb.yaml +28 -0
- mblt_vision/models/YOLOv8s-pose.yaml +28 -0
- mblt_vision/models/YOLOv8s-seg.yaml +28 -0
- mblt_vision/models/YOLOv8s.yaml +27 -0
- mblt_vision/models/YOLOv8x-cls.yaml +23 -0
- mblt_vision/models/YOLOv8x-obb.yaml +28 -0
- mblt_vision/models/YOLOv8x-pose-p6.yaml +28 -0
- mblt_vision/models/YOLOv8x-pose.yaml +28 -0
- mblt_vision/models/YOLOv8x-seg.yaml +28 -0
- mblt_vision/models/YOLOv8x.yaml +27 -0
- mblt_vision/models/YOLOv9c-seg.yaml +28 -0
- mblt_vision/models/YOLOv9c.yaml +27 -0
- mblt_vision/models/YOLOv9e-seg.yaml +28 -0
- mblt_vision/models/YOLOv9e.yaml +27 -0
- mblt_vision/models/YOLOv9m.yaml +27 -0
- mblt_vision/models/YOLOv9s.yaml +27 -0
- mblt_vision/models/YOLOv9t.yaml +27 -0
- mblt_vision/obb/__init__.py +39 -0
- mblt_vision/object_detection/__init__.py +153 -0
- mblt_vision/pose_estimation/__init__.py +41 -0
- mblt_vision/py.typed +1 -0
- mblt_vision/semantic_segmentation/__init__.py +29 -0
- mblt_vision/utils/__init__.py +0 -0
- mblt_vision/utils/datasets/__init__.py +85 -0
- mblt_vision/utils/datasets/ade20k.py +41 -0
- mblt_vision/utils/datasets/cityscapes.py +66 -0
- mblt_vision/utils/datasets/coco.py +243 -0
- mblt_vision/utils/datasets/dataloader.py +1016 -0
- mblt_vision/utils/datasets/dotav1.py +59 -0
- mblt_vision/utils/datasets/imagenet.py +29 -0
- mblt_vision/utils/datasets/organizer.py +2145 -0
- mblt_vision/utils/datasets/readiness.py +1063 -0
- mblt_vision/utils/evaluation/__init__.py +51 -0
- mblt_vision/utils/evaluation/_result.py +22 -0
- mblt_vision/utils/evaluation/eval_ade20k.py +302 -0
- mblt_vision/utils/evaluation/eval_cityscapes.py +32 -0
- mblt_vision/utils/evaluation/eval_coco.py +465 -0
- mblt_vision/utils/evaluation/eval_dota.py +878 -0
- mblt_vision/utils/evaluation/eval_imagenet.py +151 -0
- mblt_vision/utils/evaluation/eval_nyu_depth.py +189 -0
- mblt_vision/utils/evaluation/eval_widerface.py +440 -0
- mblt_vision/utils/letterbox.py +118 -0
- mblt_vision/utils/postprocess/__init__.py +9 -0
- mblt_vision/utils/postprocess/_letterbox.py +102 -0
- mblt_vision/utils/postprocess/base.py +743 -0
- mblt_vision/utils/postprocess/build_post.py +120 -0
- mblt_vision/utils/postprocess/cls_post.py +117 -0
- mblt_vision/utils/postprocess/common.py +1571 -0
- mblt_vision/utils/postprocess/depth_post.py +106 -0
- mblt_vision/utils/postprocess/semantic_seg_post.py +192 -0
- mblt_vision/utils/postprocess/yolo_anchor_post.py +469 -0
- mblt_vision/utils/postprocess/yolo_anchorless_post.py +952 -0
- mblt_vision/utils/postprocess/yolo_dflfree_post.py +983 -0
- mblt_vision/utils/postprocess/yolo_nmsfree_post.py +176 -0
- mblt_vision/utils/preprocess/__init__.py +27 -0
- mblt_vision/utils/preprocess/_validation.py +66 -0
- mblt_vision/utils/preprocess/base.py +157 -0
- mblt_vision/utils/preprocess/build_pre.py +48 -0
- mblt_vision/utils/preprocess/center_crop.py +75 -0
- mblt_vision/utils/preprocess/letterbox.py +123 -0
- mblt_vision/utils/preprocess/normalize.py +94 -0
- mblt_vision/utils/preprocess/order.py +74 -0
- mblt_vision/utils/preprocess/reader.py +94 -0
- mblt_vision/utils/preprocess/resize.py +202 -0
- mblt_vision/utils/preprocess/yolo_pre.py +7 -0
- mblt_vision/utils/results.py +725 -0
- mblt_vision/utils/types.py +15 -0
- mblt_vision/wrapper.py +1121 -0
- mblt_vision_python-0.0.0.dist-info/METADATA +152 -0
- mblt_vision_python-0.0.0.dist-info/RECORD +404 -0
- mblt_vision_python-0.0.0.dist-info/WHEEL +5 -0
- mblt_vision_python-0.0.0.dist-info/entry_points.txt +2 -0
- mblt_vision_python-0.0.0.dist-info/licenses/LICENSE +28 -0
- mblt_vision_python-0.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
"""
|
|
2
|
+
YOLO NMS-free postprocessing.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from typing import Any, cast
|
|
8
|
+
|
|
9
|
+
import torch
|
|
10
|
+
|
|
11
|
+
from .common import dist2bbox, dual_topk
|
|
12
|
+
from .yolo_anchorless_post import YOLOAnchorlessDetectionPost, _AnchorlessNMSInput
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class YOLONMSFreeDetectionPost(YOLOAnchorlessDetectionPost):
|
|
16
|
+
"""Postprocessing for YOLO NMS-free models."""
|
|
17
|
+
|
|
18
|
+
max_det = 300
|
|
19
|
+
|
|
20
|
+
def non_e2e(self, x: list[torch.Tensor]) -> torch.Tensor:
|
|
21
|
+
"""Return the export-style output tensor for NMS-free YOLO models."""
|
|
22
|
+
if len(x) == 2:
|
|
23
|
+
converted = cast(torch.Tensor, self.conversion(x))
|
|
24
|
+
return self._stack_topk_outputs(self.filter_conversion(converted))
|
|
25
|
+
|
|
26
|
+
rearranged = cast(torch.Tensor, self.rearrange(x))
|
|
27
|
+
return self.decode_batch(rearranged)
|
|
28
|
+
|
|
29
|
+
def _stack_topk_outputs(self, outputs: list[torch.Tensor]) -> torch.Tensor:
|
|
30
|
+
"""Pad or trim per-image detections to a fixed batch tensor."""
|
|
31
|
+
padded_outputs = []
|
|
32
|
+
for output in outputs:
|
|
33
|
+
output = output[: self.max_det]
|
|
34
|
+
if output.shape[0] < self.max_det:
|
|
35
|
+
pad = torch.zeros(
|
|
36
|
+
(self.max_det - output.shape[0], 6),
|
|
37
|
+
dtype=output.dtype,
|
|
38
|
+
device=output.device,
|
|
39
|
+
)
|
|
40
|
+
output = torch.cat([output, pad], dim=0)
|
|
41
|
+
padded_outputs.append(output)
|
|
42
|
+
return torch.stack(padded_outputs, dim=0)
|
|
43
|
+
|
|
44
|
+
def decode_batch(self, x: torch.Tensor) -> torch.Tensor:
|
|
45
|
+
"""Decode every anchor, then apply batched top-k selection for export-style output."""
|
|
46
|
+
box, scores = torch.split(x, [self.reg_max * 4, self.nc], dim=1)
|
|
47
|
+
anchors = self.anchors_as_tensor().unsqueeze(0)
|
|
48
|
+
stride = self.stride_as_tensor().unsqueeze(0)
|
|
49
|
+
dbox = dist2bbox(self.dfl(box), anchors, xywh=False, dim=1) * stride
|
|
50
|
+
decoded = torch.cat([dbox, scores], dim=1).transpose(1, 2)
|
|
51
|
+
return self._stack_topk_outputs(
|
|
52
|
+
[
|
|
53
|
+
dual_topk(
|
|
54
|
+
image,
|
|
55
|
+
self.nc,
|
|
56
|
+
self.n_extra,
|
|
57
|
+
max_det=self.max_det,
|
|
58
|
+
conf_thres=self.conf_thres,
|
|
59
|
+
score_is_logits=True,
|
|
60
|
+
)
|
|
61
|
+
for image in decoded
|
|
62
|
+
]
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
def _pre_process(self, x: list[torch.Tensor]) -> tuple[Any, torch.Tensor | None]:
|
|
66
|
+
"""Preprocesses inputs for NMS-free models.
|
|
67
|
+
|
|
68
|
+
Args:
|
|
69
|
+
x (list[torch.Tensor]): Raw model outputs.
|
|
70
|
+
|
|
71
|
+
Returns:
|
|
72
|
+
tuple: (processed_detections, None).
|
|
73
|
+
"""
|
|
74
|
+
if len(x) == 2:
|
|
75
|
+
converted = cast(torch.Tensor, self.conversion(x))
|
|
76
|
+
return self.filter_conversion(converted), None
|
|
77
|
+
rearranged = cast(torch.Tensor, self.rearrange(x))
|
|
78
|
+
return self.decode(rearranged), None
|
|
79
|
+
|
|
80
|
+
def conversion(
|
|
81
|
+
self, x: list[torch.Tensor]
|
|
82
|
+
) -> torch.Tensor | tuple[torch.Tensor, torch.Tensor]:
|
|
83
|
+
"""Convert input tensors.
|
|
84
|
+
Args:
|
|
85
|
+
x (list[torch.Tensor]): Input tensors.
|
|
86
|
+
Returns:
|
|
87
|
+
torch.Tensor: Converted tensor.
|
|
88
|
+
"""
|
|
89
|
+
# sort by element number
|
|
90
|
+
x = sorted(x, key=lambda x: x.size(), reverse=self.nc < 4)
|
|
91
|
+
return torch.cat(x, dim=-1).squeeze(1) # [b, 8400, 84]
|
|
92
|
+
|
|
93
|
+
def filter_conversion(self, x: torch.Tensor) -> list[torch.Tensor]:
|
|
94
|
+
"""Filters out low-confidence detections from a single output tensor.
|
|
95
|
+
|
|
96
|
+
Args:
|
|
97
|
+
x (torch.Tensor): Model output tensor.
|
|
98
|
+
|
|
99
|
+
Returns:
|
|
100
|
+
list[torch.Tensor]: Decoded and filtered outputs for each image.
|
|
101
|
+
"""
|
|
102
|
+
x_list = torch.split(x, 1, dim=0) # [(1, 8400, 84), (1, 8400, 84), ...]
|
|
103
|
+
|
|
104
|
+
return [
|
|
105
|
+
dual_topk(xi.squeeze(0), self.nc, self.n_extra, conf_thres=self.conf_thres)
|
|
106
|
+
for xi in x_list
|
|
107
|
+
]
|
|
108
|
+
|
|
109
|
+
def process_box_cls(self, box_cls: torch.Tensor) -> torch.Tensor:
|
|
110
|
+
"""Processes detection results for a single image.
|
|
111
|
+
|
|
112
|
+
Args:
|
|
113
|
+
box_cls: Raw detections for one image.
|
|
114
|
+
|
|
115
|
+
Returns:
|
|
116
|
+
Decoded and top-k filtered detections.
|
|
117
|
+
"""
|
|
118
|
+
ic = torch.amax(box_cls[-self.nc :, :], dim=0) > self.inv_conf_thres
|
|
119
|
+
box_cls = box_cls[:, ic] # (144, *)
|
|
120
|
+
if box_cls.numel() == 0:
|
|
121
|
+
return box_cls.new_zeros((0, 6))
|
|
122
|
+
anchors = self.anchors_as_tensor()
|
|
123
|
+
stride = self.stride_as_tensor()
|
|
124
|
+
box, scores = torch.split(
|
|
125
|
+
box_cls[None], [self.reg_max * 4, self.nc], dim=1
|
|
126
|
+
) # (1, 64, *), (1, 80, *)
|
|
127
|
+
dbox = (
|
|
128
|
+
dist2bbox(
|
|
129
|
+
self.dfl(box),
|
|
130
|
+
anchors[:, ic],
|
|
131
|
+
xywh=False,
|
|
132
|
+
dim=1,
|
|
133
|
+
)
|
|
134
|
+
* stride[:, ic]
|
|
135
|
+
)
|
|
136
|
+
pre_topk = (
|
|
137
|
+
torch.cat([dbox, scores], dim=1).squeeze(0).transpose(0, 1)
|
|
138
|
+
) # (*, 84)
|
|
139
|
+
return dual_topk(
|
|
140
|
+
pre_topk,
|
|
141
|
+
self.nc,
|
|
142
|
+
self.n_extra,
|
|
143
|
+
conf_thres=self.conf_thres,
|
|
144
|
+
score_is_logits=True,
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
def nms(
|
|
148
|
+
self,
|
|
149
|
+
x: _AnchorlessNMSInput | torch.Tensor | list[torch.Tensor],
|
|
150
|
+
max_det: int = 300,
|
|
151
|
+
max_nms: int = 30000,
|
|
152
|
+
max_wh: int = 7680,
|
|
153
|
+
multi_label: bool = False,
|
|
154
|
+
) -> list[torch.Tensor]:
|
|
155
|
+
"""Perform Non-Maximum Suppression (no-op for NMS-free models).
|
|
156
|
+
|
|
157
|
+
Args:
|
|
158
|
+
x: Decoded detections, optionally with source-layout provenance.
|
|
159
|
+
max_det (int, optional): Maximum number of detections to keep. Defaults to 300.
|
|
160
|
+
max_nms (int, optional): Maximum candidates for NMS. Defaults to 30000.
|
|
161
|
+
max_wh (int, optional): Maximum box width/height. Defaults to 7680.
|
|
162
|
+
multi_label: Ignored because NMS-free outputs already select one
|
|
163
|
+
class per candidate.
|
|
164
|
+
|
|
165
|
+
Returns:
|
|
166
|
+
list[torch.Tensor]: Per-image detections with padded zero rows removed.
|
|
167
|
+
"""
|
|
168
|
+
del max_det, max_nms, max_wh, multi_label
|
|
169
|
+
if isinstance(x, _AnchorlessNMSInput):
|
|
170
|
+
x = x.detections
|
|
171
|
+
if isinstance(x, list):
|
|
172
|
+
return x
|
|
173
|
+
return [xi[xi[:, 4] > 0] for xi in x]
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
YOLONMSFreePost = YOLONMSFreeDetectionPost
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Preprocessing utilities for vision models.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from .base import PreBase, PreOps
|
|
6
|
+
from .build_pre import build_preprocess
|
|
7
|
+
from .center_crop import CenterCrop
|
|
8
|
+
from .letterbox import LetterBox, letterbox_semantic_mask
|
|
9
|
+
from .normalize import Normalize
|
|
10
|
+
from .order import SetOrder
|
|
11
|
+
from .reader import Reader
|
|
12
|
+
from .resize import Resize
|
|
13
|
+
from .yolo_pre import YoloPre
|
|
14
|
+
|
|
15
|
+
__all__ = [
|
|
16
|
+
"CenterCrop",
|
|
17
|
+
"LetterBox",
|
|
18
|
+
"Normalize",
|
|
19
|
+
"PreBase",
|
|
20
|
+
"PreOps",
|
|
21
|
+
"Reader",
|
|
22
|
+
"Resize",
|
|
23
|
+
"SetOrder",
|
|
24
|
+
"YoloPre",
|
|
25
|
+
"build_preprocess",
|
|
26
|
+
"letterbox_semantic_mask",
|
|
27
|
+
]
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"""Validation helpers shared by image preprocessing operations."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from collections.abc import Sequence
|
|
6
|
+
|
|
7
|
+
import numpy as np
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def normalize_uint8_rgb_array(image: np.ndarray, *, operation: str) -> np.ndarray:
|
|
11
|
+
"""Return byte RGB data after validating or scaling a floating-point image.
|
|
12
|
+
|
|
13
|
+
``[0, 1]`` floating-point input is treated as normalized RGB and scaled to
|
|
14
|
+
``[0, 255]``. Other floating-point input must already lie in ``[0, 255]``.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
if image.dtype == np.uint8:
|
|
18
|
+
return image
|
|
19
|
+
if not np.issubdtype(image.dtype, np.floating):
|
|
20
|
+
raise TypeError(
|
|
21
|
+
f"{operation} accepts uint8 arrays or floating-point arrays with RGB "
|
|
22
|
+
f"values in [0, 1] or [0, 255]; got {image.dtype}."
|
|
23
|
+
)
|
|
24
|
+
if not np.isfinite(image).all():
|
|
25
|
+
raise ValueError(
|
|
26
|
+
f"{operation} requires floating-point image arrays to contain only "
|
|
27
|
+
"finite RGB values."
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
min_value = float(image.min())
|
|
31
|
+
max_value = float(image.max())
|
|
32
|
+
if min_value < 0.0 or max_value > 255.0:
|
|
33
|
+
raise ValueError(
|
|
34
|
+
f"{operation} accepts floating-point RGB values only in [0, 1] or "
|
|
35
|
+
f"[0, 255]; got range [{min_value}, {max_value}]."
|
|
36
|
+
)
|
|
37
|
+
if max_value <= 1.0:
|
|
38
|
+
image = image * 255.0
|
|
39
|
+
return np.rint(image).astype(np.uint8)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def normalize_image_size(size: int | Sequence[int], *, name: str = "size") -> list[int]:
|
|
43
|
+
"""Normalize a positive scalar or two-dimensional image size to ``[height, width]``."""
|
|
44
|
+
|
|
45
|
+
if isinstance(size, bool):
|
|
46
|
+
raise TypeError(
|
|
47
|
+
f"{name} must be a positive integer or a two-item integer sequence, got bool."
|
|
48
|
+
)
|
|
49
|
+
if isinstance(size, int):
|
|
50
|
+
if size <= 0:
|
|
51
|
+
raise ValueError(f"{name} must be positive, got {size}.")
|
|
52
|
+
return [size, size]
|
|
53
|
+
if isinstance(size, Sequence) and not isinstance(size, (str, bytes)):
|
|
54
|
+
if len(size) != 2:
|
|
55
|
+
raise ValueError(f"{name} must contain exactly two items, got {size!r}.")
|
|
56
|
+
if not all(
|
|
57
|
+
isinstance(value, int) and not isinstance(value, bool) for value in size
|
|
58
|
+
):
|
|
59
|
+
raise TypeError(f"{name} items must be integers, got {size!r}.")
|
|
60
|
+
normalized = [int(size[0]), int(size[1])]
|
|
61
|
+
if any(value <= 0 for value in normalized):
|
|
62
|
+
raise ValueError(f"{name} items must be positive, got {size!r}.")
|
|
63
|
+
return normalized
|
|
64
|
+
raise TypeError(
|
|
65
|
+
f"{name} must be a positive integer or a two-item integer sequence, got {type(size).__name__}."
|
|
66
|
+
)
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from abc import ABC, abstractmethod
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
import torch
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def _spatial_shape(value: Any) -> tuple[int, int] | None:
|
|
10
|
+
"""Return the height and width of image-like preprocessing input."""
|
|
11
|
+
|
|
12
|
+
shape = getattr(value, "shape", None)
|
|
13
|
+
if shape is None or len(shape) < 2:
|
|
14
|
+
return None
|
|
15
|
+
if len(shape) == 2:
|
|
16
|
+
return int(shape[0]), int(shape[1])
|
|
17
|
+
if len(shape) == 3 and int(shape[-1]) in {1, 3, 4}:
|
|
18
|
+
return int(shape[0]), int(shape[1])
|
|
19
|
+
return int(shape[-2]), int(shape[-1])
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class PreOps(ABC):
|
|
23
|
+
"""Abstract base class for individual preprocessing operations.
|
|
24
|
+
|
|
25
|
+
Attributes:
|
|
26
|
+
device: The torch device where tensors should be placed.
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
def __init__(self) -> None:
|
|
30
|
+
"""Initializes the preprocessing operation."""
|
|
31
|
+
super().__init__()
|
|
32
|
+
self.device = torch.device("cpu")
|
|
33
|
+
|
|
34
|
+
@abstractmethod
|
|
35
|
+
def __call__(
|
|
36
|
+
self,
|
|
37
|
+
x: Any,
|
|
38
|
+
) -> Any:
|
|
39
|
+
"""Executes the preprocess operation.
|
|
40
|
+
|
|
41
|
+
Args:
|
|
42
|
+
x: Input data to be processed.
|
|
43
|
+
|
|
44
|
+
Returns:
|
|
45
|
+
Processed data.
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
def to(
|
|
49
|
+
self,
|
|
50
|
+
device: str | torch.device,
|
|
51
|
+
) -> None:
|
|
52
|
+
"""Move the operation to the specified device.
|
|
53
|
+
|
|
54
|
+
Args:
|
|
55
|
+
device: Device to move the operation to.
|
|
56
|
+
"""
|
|
57
|
+
if isinstance(device, str):
|
|
58
|
+
self.device = torch.device(device)
|
|
59
|
+
elif isinstance(device, torch.device):
|
|
60
|
+
self.device = device
|
|
61
|
+
else:
|
|
62
|
+
raise TypeError(f"Got unexpected type for device={type(device)}.")
|
|
63
|
+
for name, value in self.__dict__.items():
|
|
64
|
+
if isinstance(value, torch.Tensor):
|
|
65
|
+
setattr(self, name, value.to(self.device))
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
class PreBase:
|
|
69
|
+
"""Base class for orchestrating a series of preprocessing operations.
|
|
70
|
+
|
|
71
|
+
Attributes:
|
|
72
|
+
Ops: List of ordered PreOps instances to be applied.
|
|
73
|
+
device: The torch device being used.
|
|
74
|
+
"""
|
|
75
|
+
|
|
76
|
+
def __init__(
|
|
77
|
+
self,
|
|
78
|
+
Ops: list[PreOps],
|
|
79
|
+
) -> None:
|
|
80
|
+
"""Initializes the PreBase class with a list of operations.
|
|
81
|
+
|
|
82
|
+
Args:
|
|
83
|
+
Ops: List of ordered PreOps instances to be applied.
|
|
84
|
+
"""
|
|
85
|
+
self.Ops = Ops
|
|
86
|
+
self._check_ops()
|
|
87
|
+
self.device = torch.device("cpu")
|
|
88
|
+
|
|
89
|
+
def _check_ops(self) -> None:
|
|
90
|
+
"""Check if the operations are valid."""
|
|
91
|
+
for op in self.Ops:
|
|
92
|
+
if not isinstance(op, PreOps):
|
|
93
|
+
raise TypeError(f"Got unsupported type={type(op)}.")
|
|
94
|
+
|
|
95
|
+
def __call__(
|
|
96
|
+
self,
|
|
97
|
+
x: Any,
|
|
98
|
+
) -> Any:
|
|
99
|
+
"""Applies the sequence of preprocessing operations to the input.
|
|
100
|
+
|
|
101
|
+
Args:
|
|
102
|
+
x: Initial input data.
|
|
103
|
+
|
|
104
|
+
Returns:
|
|
105
|
+
Fully processed data.
|
|
106
|
+
"""
|
|
107
|
+
for op in self.Ops:
|
|
108
|
+
x = op(x)
|
|
109
|
+
return x
|
|
110
|
+
|
|
111
|
+
def with_metadata(
|
|
112
|
+
self,
|
|
113
|
+
x: Any,
|
|
114
|
+
) -> tuple[Any, dict[str, Any]]:
|
|
115
|
+
"""Apply preprocessing and return metadata produced by preprocessing operations.
|
|
116
|
+
|
|
117
|
+
Args:
|
|
118
|
+
x: Initial input data.
|
|
119
|
+
|
|
120
|
+
Returns:
|
|
121
|
+
A tuple of the processed data and collected metadata.
|
|
122
|
+
"""
|
|
123
|
+
metadata: dict[str, Any] = {}
|
|
124
|
+
img0_shape = _spatial_shape(x)
|
|
125
|
+
if img0_shape is not None:
|
|
126
|
+
metadata["img0_shape"] = img0_shape
|
|
127
|
+
for op in self.Ops:
|
|
128
|
+
x = op(x)
|
|
129
|
+
if "img0_shape" not in metadata:
|
|
130
|
+
img0_shape = _spatial_shape(x)
|
|
131
|
+
if img0_shape is not None:
|
|
132
|
+
metadata["img0_shape"] = img0_shape
|
|
133
|
+
ratio_pad = getattr(op, "ratio_pad", None)
|
|
134
|
+
if ratio_pad is not None:
|
|
135
|
+
metadata["ratio_pad"] = ratio_pad
|
|
136
|
+
return x, metadata
|
|
137
|
+
|
|
138
|
+
def to(
|
|
139
|
+
self,
|
|
140
|
+
device: str | torch.device,
|
|
141
|
+
) -> None:
|
|
142
|
+
"""Move the operations to the specified device.
|
|
143
|
+
|
|
144
|
+
Args:
|
|
145
|
+
device: Device to move the operations to.
|
|
146
|
+
"""
|
|
147
|
+
if isinstance(device, str):
|
|
148
|
+
self.device = torch.device(device)
|
|
149
|
+
elif isinstance(device, torch.device):
|
|
150
|
+
self.device = device
|
|
151
|
+
else:
|
|
152
|
+
raise TypeError(f"Got unexpected type for device={type(device)}.")
|
|
153
|
+
for name, value in self.__dict__.items():
|
|
154
|
+
if isinstance(value, torch.Tensor):
|
|
155
|
+
setattr(self, name, value.to(self.device))
|
|
156
|
+
for op in self.Ops:
|
|
157
|
+
op.to(self.device)
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Preprocessing builder.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from collections.abc import Mapping
|
|
8
|
+
from typing import Any
|
|
9
|
+
|
|
10
|
+
from .base import PreBase
|
|
11
|
+
from .center_crop import CenterCrop
|
|
12
|
+
from .letterbox import LetterBox
|
|
13
|
+
from .normalize import Normalize
|
|
14
|
+
from .order import SetOrder
|
|
15
|
+
from .reader import Reader
|
|
16
|
+
from .resize import Resize
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def build_preprocess(
|
|
20
|
+
pre_cfg: Mapping[str, Mapping[str, Any]],
|
|
21
|
+
) -> PreBase:
|
|
22
|
+
"""Builds a preprocessing pipeline based on the configuration.
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
pre_cfg: Preprocessing configuration mapping operations to attributes.
|
|
26
|
+
|
|
27
|
+
Returns:
|
|
28
|
+
An orchestrator for the sequence of preprocessing steps.
|
|
29
|
+
"""
|
|
30
|
+
res = []
|
|
31
|
+
for pre_type, pre_attr in pre_cfg.items():
|
|
32
|
+
pre_type_lower = pre_type.lower()
|
|
33
|
+
if pre_type_lower == Reader.__name__.lower():
|
|
34
|
+
res.append(Reader(**pre_attr))
|
|
35
|
+
elif pre_type_lower == Resize.__name__.lower():
|
|
36
|
+
res.append(Resize(**pre_attr))
|
|
37
|
+
elif pre_type_lower == CenterCrop.__name__.lower():
|
|
38
|
+
res.append(CenterCrop(**pre_attr))
|
|
39
|
+
elif pre_type_lower == SetOrder.__name__.lower():
|
|
40
|
+
res.append(SetOrder(**pre_attr))
|
|
41
|
+
elif pre_type_lower == LetterBox.__name__.lower():
|
|
42
|
+
res.append(LetterBox(**pre_attr))
|
|
43
|
+
elif pre_type_lower == Normalize.__name__.lower():
|
|
44
|
+
res.append(Normalize(**pre_attr))
|
|
45
|
+
else:
|
|
46
|
+
raise ValueError(f"Got unsupported pre_type={pre_type}.")
|
|
47
|
+
|
|
48
|
+
return PreBase(res)
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Center crop preprocessing.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
import cv2
|
|
8
|
+
import numpy as np
|
|
9
|
+
import torch
|
|
10
|
+
from PIL import Image
|
|
11
|
+
|
|
12
|
+
from ..types import TensorLike
|
|
13
|
+
from ._validation import normalize_image_size
|
|
14
|
+
from .base import PreOps
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class CenterCrop(PreOps):
|
|
18
|
+
"""
|
|
19
|
+
Center crop the image to a specified size.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
def __init__(self, size: int | list[int] | tuple[int, int]) -> None:
|
|
23
|
+
"""Initializes the CenterCrop operation.
|
|
24
|
+
|
|
25
|
+
Args:
|
|
26
|
+
size (int | list[int]): Target size [h, w]. If int, size is [size, size].
|
|
27
|
+
"""
|
|
28
|
+
super().__init__()
|
|
29
|
+
self.size = normalize_image_size(size)
|
|
30
|
+
|
|
31
|
+
def __call__(self, x: TensorLike | Image.Image) -> np.ndarray:
|
|
32
|
+
"""Applies center crop to the image.
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
x (np.ndarray | torch.Tensor | Image.Image): Input image.
|
|
36
|
+
|
|
37
|
+
Returns:
|
|
38
|
+
np.ndarray: Center-cropped image in HWC format.
|
|
39
|
+
"""
|
|
40
|
+
if isinstance(x, torch.Tensor):
|
|
41
|
+
image = x.detach().cpu().numpy()
|
|
42
|
+
elif isinstance(x, Image.Image):
|
|
43
|
+
image = np.array(x)
|
|
44
|
+
elif isinstance(x, np.ndarray):
|
|
45
|
+
image = x
|
|
46
|
+
else:
|
|
47
|
+
raise TypeError(
|
|
48
|
+
f"CenterCrop expects a NumPy array, tensor, or PIL image, got {type(x).__name__}."
|
|
49
|
+
)
|
|
50
|
+
if image.ndim != 3:
|
|
51
|
+
raise ValueError(
|
|
52
|
+
f"CenterCrop expects a three-dimensional image, got shape {image.shape}."
|
|
53
|
+
)
|
|
54
|
+
H, W = image.shape[:2]
|
|
55
|
+
if (self.size[0] == H) and (self.size[1] == W):
|
|
56
|
+
return image
|
|
57
|
+
elif (self.size[1] > W) or (self.size[0] > H):
|
|
58
|
+
image = cv2.copyMakeBorder(
|
|
59
|
+
image,
|
|
60
|
+
(self.size[0] - H) // 2 if self.size[0] > H else 0,
|
|
61
|
+
(self.size[0] - H + 1) // 2 if self.size[0] > H else 0,
|
|
62
|
+
(self.size[1] - W) // 2 if self.size[1] > W else 0,
|
|
63
|
+
(self.size[1] - W + 1) // 2 if self.size[1] > W else 0,
|
|
64
|
+
cv2.BORDER_CONSTANT,
|
|
65
|
+
value=(0.0,),
|
|
66
|
+
)
|
|
67
|
+
H, W = image.shape[:2]
|
|
68
|
+
crop_top = round((H - self.size[0]) / 2.0)
|
|
69
|
+
crop_left = round((W - self.size[1]) / 2.0)
|
|
70
|
+
image = image[
|
|
71
|
+
crop_top : crop_top + self.size[0],
|
|
72
|
+
crop_left : crop_left + self.size[1],
|
|
73
|
+
:,
|
|
74
|
+
]
|
|
75
|
+
return image.astype(np.uint8)
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import cv2
|
|
4
|
+
import numpy as np
|
|
5
|
+
import torch
|
|
6
|
+
|
|
7
|
+
from ..letterbox import LetterBoxGeometry, RatioPad
|
|
8
|
+
from ..types import TensorLike
|
|
9
|
+
from ._validation import normalize_image_size, normalize_uint8_rgb_array
|
|
10
|
+
from .base import PreOps
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def _apply_letterbox(
|
|
14
|
+
image: np.ndarray,
|
|
15
|
+
img_size: list[int],
|
|
16
|
+
interpolation: int,
|
|
17
|
+
padding_value: int | tuple[int, int, int],
|
|
18
|
+
) -> tuple[np.ndarray, RatioPad]:
|
|
19
|
+
"""Resize and pad an array while preserving its aspect ratio.
|
|
20
|
+
|
|
21
|
+
Args:
|
|
22
|
+
image: Image or two-dimensional semantic mask.
|
|
23
|
+
img_size: Target size as ``[height, width]``.
|
|
24
|
+
interpolation: OpenCV interpolation mode.
|
|
25
|
+
padding_value: Constant border value.
|
|
26
|
+
|
|
27
|
+
Returns:
|
|
28
|
+
The letterboxed array and its resize/padding metadata.
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
input_shape = (int(img_size[0]), int(img_size[1]))
|
|
32
|
+
original_shape = (int(image.shape[0]), int(image.shape[1]))
|
|
33
|
+
geometry = LetterBoxGeometry.from_shapes(input_shape, original_shape)
|
|
34
|
+
resized_height, resized_width = geometry.resized_shape
|
|
35
|
+
if image.shape[:2] != geometry.resized_shape:
|
|
36
|
+
image = cv2.resize(
|
|
37
|
+
image, (resized_width, resized_height), interpolation=interpolation
|
|
38
|
+
)
|
|
39
|
+
top, bottom, left, right = geometry.borders
|
|
40
|
+
image = cv2.copyMakeBorder(
|
|
41
|
+
image,
|
|
42
|
+
top,
|
|
43
|
+
bottom,
|
|
44
|
+
left,
|
|
45
|
+
right,
|
|
46
|
+
cv2.BORDER_CONSTANT,
|
|
47
|
+
value=padding_value,
|
|
48
|
+
)
|
|
49
|
+
return image, geometry.ratio_pad
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def letterbox_semantic_mask(
|
|
53
|
+
mask: np.ndarray,
|
|
54
|
+
img_size: list[int],
|
|
55
|
+
ignore_label: int = 255,
|
|
56
|
+
) -> tuple[np.ndarray, RatioPad]:
|
|
57
|
+
"""Letterbox a semantic mask without interpolating class IDs.
|
|
58
|
+
|
|
59
|
+
Args:
|
|
60
|
+
mask: Two-dimensional semantic class map.
|
|
61
|
+
img_size: Target size as ``[height, width]``.
|
|
62
|
+
ignore_label: Class value used for padded pixels.
|
|
63
|
+
|
|
64
|
+
Returns:
|
|
65
|
+
The letterboxed mask and its resize/padding metadata.
|
|
66
|
+
|
|
67
|
+
Raises:
|
|
68
|
+
ValueError: If the mask is not two-dimensional.
|
|
69
|
+
"""
|
|
70
|
+
|
|
71
|
+
if mask.ndim != 2:
|
|
72
|
+
raise ValueError(
|
|
73
|
+
f"Semantic masks must be two-dimensional, got shape {mask.shape}."
|
|
74
|
+
)
|
|
75
|
+
return _apply_letterbox(mask, img_size, cv2.INTER_NEAREST, ignore_label)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
class LetterBox(PreOps):
|
|
79
|
+
"""Preprocessing for YOLO models, implementing letterbox resizing.
|
|
80
|
+
|
|
81
|
+
Resizes the image while maintaining aspect ratio, adding padding to meet
|
|
82
|
+
target dimensions. Floating-point RGB inputs in ``[0, 1]`` are scaled to
|
|
83
|
+
byte RGB; other floating-point values must be finite and in ``[0, 255]``.
|
|
84
|
+
Based on Ultralytics implementation.
|
|
85
|
+
|
|
86
|
+
Ref: https://github.com/ultralytics/ultralytics/blob/main/ultralytics/data/augment.py#L1535
|
|
87
|
+
"""
|
|
88
|
+
|
|
89
|
+
def __init__(self, img_size: list[int]) -> None:
|
|
90
|
+
"""Initializes LetterBox with target image size.
|
|
91
|
+
|
|
92
|
+
Args:
|
|
93
|
+
img_size (list[int]): Target image size [h, w].
|
|
94
|
+
"""
|
|
95
|
+
super().__init__()
|
|
96
|
+
self.img_size = normalize_image_size(img_size, name="img_size")
|
|
97
|
+
self.ratio_pad: tuple[tuple[float, float], tuple[float, float]] | None = None
|
|
98
|
+
|
|
99
|
+
def __call__(self, x: TensorLike) -> torch.Tensor:
|
|
100
|
+
"""Executes YOLO preprocessing (letterbox resizing).
|
|
101
|
+
|
|
102
|
+
Args:
|
|
103
|
+
x (TensorLike): Input image.
|
|
104
|
+
|
|
105
|
+
Returns:
|
|
106
|
+
torch.Tensor: Preprocessed image in HWC format on the selected device.
|
|
107
|
+
"""
|
|
108
|
+
if isinstance(x, torch.Tensor):
|
|
109
|
+
x = x.detach().cpu().numpy()
|
|
110
|
+
elif not isinstance(x, np.ndarray):
|
|
111
|
+
raise TypeError(
|
|
112
|
+
f"LetterBox expects a NumPy array or tensor, got {type(x).__name__}."
|
|
113
|
+
)
|
|
114
|
+
if x.ndim != 3:
|
|
115
|
+
raise ValueError(f"LetterBox expects an HWC image, got shape {x.shape}.")
|
|
116
|
+
x = normalize_uint8_rgb_array(x, operation="LetterBox")
|
|
117
|
+
img, self.ratio_pad = _apply_letterbox(
|
|
118
|
+
x,
|
|
119
|
+
self.img_size,
|
|
120
|
+
cv2.INTER_LINEAR,
|
|
121
|
+
(114, 114, 114),
|
|
122
|
+
)
|
|
123
|
+
return torch.from_numpy(img).to(self.device).byte()
|