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.
Files changed (404) hide show
  1. mblt_vision/__init__.py +86 -0
  2. mblt_vision/_api.py +53 -0
  3. mblt_vision/_compat.py +227 -0
  4. mblt_vision/_model_paths.py +137 -0
  5. mblt_vision/_tasks.py +30 -0
  6. mblt_vision/benchmark/__init__.py +1 -0
  7. mblt_vision/benchmark/argparse_utils.py +106 -0
  8. mblt_vision/benchmark/chart_utils.py +146 -0
  9. mblt_vision/benchmark/io_utils.py +64 -0
  10. mblt_vision/benchmark/summary_utils.py +770 -0
  11. mblt_vision/cli/__init__.py +5 -0
  12. mblt_vision/cli/__main__.py +5 -0
  13. mblt_vision/cli/_vision.py +337 -0
  14. mblt_vision/cli/compile.py +117 -0
  15. mblt_vision/cli/main.py +35 -0
  16. mblt_vision/cli/predict.py +64 -0
  17. mblt_vision/cli/val.py +562 -0
  18. mblt_vision/compile/__init__.py +21 -0
  19. mblt_vision/compile/vision.py +1120 -0
  20. mblt_vision/datasets/__init__.py +15 -0
  21. mblt_vision/datasets/ade20k.yaml +164 -0
  22. mblt_vision/datasets/cityscapes.yaml +54 -0
  23. mblt_vision/datasets/coco.yaml +178 -0
  24. mblt_vision/datasets/dotav1.yaml +28 -0
  25. mblt_vision/datasets/imagenet.yaml +1019 -0
  26. mblt_vision/datasets/imagenet_synsets.txt +1000 -0
  27. mblt_vision/datasets/nyu-depth.yaml +7 -0
  28. mblt_vision/datasets/registry.py +158 -0
  29. mblt_vision/datasets/widerface.yaml +9 -0
  30. mblt_vision/depth_estimation/__init__.py +19 -0
  31. mblt_vision/face_detection/__init__.py +43 -0
  32. mblt_vision/image_classification/__init__.py +311 -0
  33. mblt_vision/instance_segmentation/__init__.py +65 -0
  34. mblt_vision/models/AlexNet.yaml +23 -0
  35. mblt_vision/models/CAFormer_B36.yaml +22 -0
  36. mblt_vision/models/CAFormer_M36.yaml +22 -0
  37. mblt_vision/models/CAFormer_S18.yaml +22 -0
  38. mblt_vision/models/CAFormer_S36.yaml +22 -0
  39. mblt_vision/models/CoAtNet_0_RW_224.yaml +22 -0
  40. mblt_vision/models/CoAtNet_1_RW_224.yaml +22 -0
  41. mblt_vision/models/CoAtNet_2_RW_224.yaml +22 -0
  42. mblt_vision/models/ConvFormer_B36.yaml +22 -0
  43. mblt_vision/models/ConvFormer_M36.yaml +22 -0
  44. mblt_vision/models/ConvFormer_S18.yaml +22 -0
  45. mblt_vision/models/ConvFormer_S36.yaml +22 -0
  46. mblt_vision/models/ConvNext_Base.yaml +23 -0
  47. mblt_vision/models/ConvNext_Large.yaml +23 -0
  48. mblt_vision/models/ConvNext_Small.yaml +23 -0
  49. mblt_vision/models/ConvNext_Tiny.yaml +23 -0
  50. mblt_vision/models/DeiT3_Base_Patch16_224.yaml +22 -0
  51. mblt_vision/models/DeiT3_Base_Patch16_384.yaml +22 -0
  52. mblt_vision/models/DeiT3_Large_Patch16_224.yaml +22 -0
  53. mblt_vision/models/DeiT3_Large_Patch16_384.yaml +22 -0
  54. mblt_vision/models/DeiT3_Medium_Patch16_224.yaml +22 -0
  55. mblt_vision/models/DeiT3_Small_Patch16_224.yaml +22 -0
  56. mblt_vision/models/DeiT3_Small_Patch16_384.yaml +22 -0
  57. mblt_vision/models/DeiT_Base_Patch16_224.yaml +22 -0
  58. mblt_vision/models/DeiT_Base_Patch16_384.yaml +22 -0
  59. mblt_vision/models/DeiT_Small_Patch16_224.yaml +22 -0
  60. mblt_vision/models/DeiT_Tiny_Patch16_224.yaml +22 -0
  61. mblt_vision/models/DenseNet121.yaml +23 -0
  62. mblt_vision/models/DenseNet161.yaml +23 -0
  63. mblt_vision/models/DenseNet169.yaml +23 -0
  64. mblt_vision/models/DenseNet201.yaml +23 -0
  65. mblt_vision/models/EfficientFormer_L1.yaml +22 -0
  66. mblt_vision/models/EfficientFormer_L3.yaml +22 -0
  67. mblt_vision/models/EfficientFormer_L7.yaml +22 -0
  68. mblt_vision/models/EfficientNet_B0.yaml +23 -0
  69. mblt_vision/models/EfficientNet_B1.yaml +32 -0
  70. mblt_vision/models/EfficientNet_B2.yaml +23 -0
  71. mblt_vision/models/EfficientNet_B3.yaml +23 -0
  72. mblt_vision/models/EfficientNet_B4.yaml +23 -0
  73. mblt_vision/models/EfficientNet_B5.yaml +23 -0
  74. mblt_vision/models/EfficientNet_B6.yaml +23 -0
  75. mblt_vision/models/EfficientNet_B7.yaml +23 -0
  76. mblt_vision/models/EfficientNet_V2_L.yaml +23 -0
  77. mblt_vision/models/EfficientNet_V2_M.yaml +23 -0
  78. mblt_vision/models/EfficientNet_V2_S.yaml +23 -0
  79. mblt_vision/models/FlexiVit_Base.yaml +22 -0
  80. mblt_vision/models/FlexiVit_Large.yaml +22 -0
  81. mblt_vision/models/FlexiVit_Small.yaml +22 -0
  82. mblt_vision/models/GELANc-seg.yaml +29 -0
  83. mblt_vision/models/GELANc.yaml +28 -0
  84. mblt_vision/models/GELANe.yaml +28 -0
  85. mblt_vision/models/GELANm.yaml +28 -0
  86. mblt_vision/models/GELANs.yaml +28 -0
  87. mblt_vision/models/GoogLeNet.yaml +23 -0
  88. mblt_vision/models/Inception_V3.yaml +23 -0
  89. mblt_vision/models/LeViT_Conv_128.yaml +22 -0
  90. mblt_vision/models/LeViT_Conv_128S.yaml +22 -0
  91. mblt_vision/models/LeViT_Conv_192.yaml +22 -0
  92. mblt_vision/models/LeViT_Conv_256.yaml +22 -0
  93. mblt_vision/models/LeViT_Conv_384.yaml +22 -0
  94. mblt_vision/models/MNASNet0_5.yaml +23 -0
  95. mblt_vision/models/MNASNet0_75.yaml +23 -0
  96. mblt_vision/models/MNASNet1_0.yaml +23 -0
  97. mblt_vision/models/MNASNet1_3.yaml +23 -0
  98. mblt_vision/models/MobileNet_V2.yaml +32 -0
  99. mblt_vision/models/MobileNet_V3_Large.yaml +32 -0
  100. mblt_vision/models/MobileNet_V3_Small.yaml +23 -0
  101. mblt_vision/models/RegNet_X_16GF.yaml +32 -0
  102. mblt_vision/models/RegNet_X_1_6GF.yaml +32 -0
  103. mblt_vision/models/RegNet_X_32GF.yaml +32 -0
  104. mblt_vision/models/RegNet_X_3_2GF.yaml +32 -0
  105. mblt_vision/models/RegNet_X_400MF.yaml +32 -0
  106. mblt_vision/models/RegNet_X_800MF.yaml +32 -0
  107. mblt_vision/models/RegNet_X_8GF.yaml +32 -0
  108. mblt_vision/models/RegNet_Y_16GF.yaml +76 -0
  109. mblt_vision/models/RegNet_Y_1_6GF.yaml +32 -0
  110. mblt_vision/models/RegNet_Y_32GF.yaml +76 -0
  111. mblt_vision/models/RegNet_Y_3_2GF.yaml +32 -0
  112. mblt_vision/models/RegNet_Y_400MF.yaml +32 -0
  113. mblt_vision/models/RegNet_Y_800MF.yaml +32 -0
  114. mblt_vision/models/RegNet_Y_8GF.yaml +32 -0
  115. mblt_vision/models/RepViT_M0_9.yaml +22 -0
  116. mblt_vision/models/RepViT_M1.yaml +22 -0
  117. mblt_vision/models/RepViT_M1_0.yaml +22 -0
  118. mblt_vision/models/RepViT_M1_1.yaml +22 -0
  119. mblt_vision/models/RepViT_M1_5.yaml +22 -0
  120. mblt_vision/models/RepViT_M2.yaml +22 -0
  121. mblt_vision/models/RepViT_M2_3.yaml +22 -0
  122. mblt_vision/models/RepViT_M3.yaml +22 -0
  123. mblt_vision/models/ResNeXt101_32X8D.yaml +32 -0
  124. mblt_vision/models/ResNeXt101_64X4D.yaml +23 -0
  125. mblt_vision/models/ResNeXt50_32X4D.yaml +32 -0
  126. mblt_vision/models/ResNet101.yaml +32 -0
  127. mblt_vision/models/ResNet152.yaml +32 -0
  128. mblt_vision/models/ResNet18.yaml +23 -0
  129. mblt_vision/models/ResNet34.yaml +23 -0
  130. mblt_vision/models/ResNet50.yaml +32 -0
  131. mblt_vision/models/ShuffleNet_V2_X0_5.yaml +23 -0
  132. mblt_vision/models/ShuffleNet_V2_X1_0.yaml +23 -0
  133. mblt_vision/models/ShuffleNet_V2_X1_5.yaml +23 -0
  134. mblt_vision/models/ShuffleNet_V2_X2_0.yaml +23 -0
  135. mblt_vision/models/SqueezeNet1_0.yaml +23 -0
  136. mblt_vision/models/SqueezeNet1_1.yaml +23 -0
  137. mblt_vision/models/Swin_B.yaml +23 -0
  138. mblt_vision/models/Swin_S.yaml +23 -0
  139. mblt_vision/models/Swin_T.yaml +23 -0
  140. mblt_vision/models/VGG11.yaml +23 -0
  141. mblt_vision/models/VGG11_BN.yaml +23 -0
  142. mblt_vision/models/VGG13.yaml +23 -0
  143. mblt_vision/models/VGG13_BN.yaml +23 -0
  144. mblt_vision/models/VGG16.yaml +23 -0
  145. mblt_vision/models/VGG16_BN.yaml +23 -0
  146. mblt_vision/models/VGG19.yaml +23 -0
  147. mblt_vision/models/VGG19_BN.yaml +23 -0
  148. mblt_vision/models/ViT_B_16.yaml +67 -0
  149. mblt_vision/models/ViT_B_32.yaml +23 -0
  150. mblt_vision/models/ViT_Base_Patch16_224.yaml +22 -0
  151. mblt_vision/models/ViT_Base_Patch16_384.yaml +22 -0
  152. mblt_vision/models/ViT_Base_Patch32_224.yaml +22 -0
  153. mblt_vision/models/ViT_Base_Patch32_384.yaml +22 -0
  154. mblt_vision/models/ViT_Base_Patch8_224.yaml +22 -0
  155. mblt_vision/models/ViT_L_16.yaml +67 -0
  156. mblt_vision/models/ViT_L_32.yaml +23 -0
  157. mblt_vision/models/ViT_Large_Patch16_224.yaml +22 -0
  158. mblt_vision/models/ViT_Large_Patch16_384.yaml +22 -0
  159. mblt_vision/models/ViT_Large_Patch32_384.yaml +22 -0
  160. mblt_vision/models/ViT_Small_Patch16_224.yaml +22 -0
  161. mblt_vision/models/ViT_Small_Patch16_384.yaml +22 -0
  162. mblt_vision/models/ViT_Small_Patch32_224.yaml +22 -0
  163. mblt_vision/models/ViT_Small_Patch32_384.yaml +22 -0
  164. mblt_vision/models/ViT_Tiny_Patch16_224.yaml +22 -0
  165. mblt_vision/models/ViT_Tiny_Patch16_384.yaml +22 -0
  166. mblt_vision/models/VisFormer_Small.yaml +22 -0
  167. mblt_vision/models/VisFormer_Tiny.yaml +22 -0
  168. mblt_vision/models/Wide_ResNet101_2.yaml +32 -0
  169. mblt_vision/models/Wide_ResNet50_2.yaml +32 -0
  170. mblt_vision/models/YOLO11l-cls.yaml +23 -0
  171. mblt_vision/models/YOLO11l-face.yaml +27 -0
  172. mblt_vision/models/YOLO11l-obb.yaml +28 -0
  173. mblt_vision/models/YOLO11l-pose.yaml +28 -0
  174. mblt_vision/models/YOLO11l-seg.yaml +28 -0
  175. mblt_vision/models/YOLO11l.yaml +27 -0
  176. mblt_vision/models/YOLO11m-cls.yaml +23 -0
  177. mblt_vision/models/YOLO11m-face.yaml +27 -0
  178. mblt_vision/models/YOLO11m-obb.yaml +28 -0
  179. mblt_vision/models/YOLO11m-pose.yaml +28 -0
  180. mblt_vision/models/YOLO11m-seg.yaml +28 -0
  181. mblt_vision/models/YOLO11m.yaml +27 -0
  182. mblt_vision/models/YOLO11n-cls.yaml +23 -0
  183. mblt_vision/models/YOLO11n-face.yaml +27 -0
  184. mblt_vision/models/YOLO11n-obb.yaml +28 -0
  185. mblt_vision/models/YOLO11n-pose.yaml +28 -0
  186. mblt_vision/models/YOLO11n-seg.yaml +28 -0
  187. mblt_vision/models/YOLO11n.yaml +27 -0
  188. mblt_vision/models/YOLO11s-cls.yaml +23 -0
  189. mblt_vision/models/YOLO11s-face.yaml +27 -0
  190. mblt_vision/models/YOLO11s-obb.yaml +28 -0
  191. mblt_vision/models/YOLO11s-pose.yaml +28 -0
  192. mblt_vision/models/YOLO11s-seg.yaml +28 -0
  193. mblt_vision/models/YOLO11s.yaml +27 -0
  194. mblt_vision/models/YOLO11x-cls.yaml +23 -0
  195. mblt_vision/models/YOLO11x-obb.yaml +28 -0
  196. mblt_vision/models/YOLO11x-pose.yaml +28 -0
  197. mblt_vision/models/YOLO11x-seg.yaml +28 -0
  198. mblt_vision/models/YOLO11x.yaml +27 -0
  199. mblt_vision/models/YOLO12l-face.yaml +27 -0
  200. mblt_vision/models/YOLO12l-seg.yaml +28 -0
  201. mblt_vision/models/YOLO12l.yaml +27 -0
  202. mblt_vision/models/YOLO12m-face.yaml +27 -0
  203. mblt_vision/models/YOLO12m-seg.yaml +28 -0
  204. mblt_vision/models/YOLO12m.yaml +27 -0
  205. mblt_vision/models/YOLO12n-face.yaml +27 -0
  206. mblt_vision/models/YOLO12n-seg.yaml +28 -0
  207. mblt_vision/models/YOLO12n.yaml +27 -0
  208. mblt_vision/models/YOLO12s-face.yaml +27 -0
  209. mblt_vision/models/YOLO12s-seg.yaml +28 -0
  210. mblt_vision/models/YOLO12s.yaml +27 -0
  211. mblt_vision/models/YOLO12x-seg.yaml +28 -0
  212. mblt_vision/models/YOLO12x.yaml +27 -0
  213. mblt_vision/models/YOLO26l-cls.yaml +23 -0
  214. mblt_vision/models/YOLO26l-depth.yaml +17 -0
  215. mblt_vision/models/YOLO26l-distill.yaml +27 -0
  216. mblt_vision/models/YOLO26l-obb.yaml +28 -0
  217. mblt_vision/models/YOLO26l-pose.yaml +28 -0
  218. mblt_vision/models/YOLO26l-seg.yaml +28 -0
  219. mblt_vision/models/YOLO26l-sem-ade20k.yaml +17 -0
  220. mblt_vision/models/YOLO26l-sem.yaml +17 -0
  221. mblt_vision/models/YOLO26l.yaml +27 -0
  222. mblt_vision/models/YOLO26m-cls.yaml +23 -0
  223. mblt_vision/models/YOLO26m-depth.yaml +17 -0
  224. mblt_vision/models/YOLO26m-distill.yaml +27 -0
  225. mblt_vision/models/YOLO26m-obb.yaml +28 -0
  226. mblt_vision/models/YOLO26m-pose.yaml +28 -0
  227. mblt_vision/models/YOLO26m-seg.yaml +28 -0
  228. mblt_vision/models/YOLO26m-sem-ade20k.yaml +17 -0
  229. mblt_vision/models/YOLO26m-sem.yaml +17 -0
  230. mblt_vision/models/YOLO26m.yaml +27 -0
  231. mblt_vision/models/YOLO26n-cls.yaml +23 -0
  232. mblt_vision/models/YOLO26n-depth.yaml +17 -0
  233. mblt_vision/models/YOLO26n-distill.yaml +27 -0
  234. mblt_vision/models/YOLO26n-obb.yaml +28 -0
  235. mblt_vision/models/YOLO26n-pose.yaml +28 -0
  236. mblt_vision/models/YOLO26n-seg.yaml +28 -0
  237. mblt_vision/models/YOLO26n-sem-ade20k.yaml +17 -0
  238. mblt_vision/models/YOLO26n-sem.yaml +17 -0
  239. mblt_vision/models/YOLO26n.yaml +27 -0
  240. mblt_vision/models/YOLO26s-cls.yaml +23 -0
  241. mblt_vision/models/YOLO26s-depth.yaml +17 -0
  242. mblt_vision/models/YOLO26s-distill.yaml +27 -0
  243. mblt_vision/models/YOLO26s-obb.yaml +28 -0
  244. mblt_vision/models/YOLO26s-pose.yaml +28 -0
  245. mblt_vision/models/YOLO26s-seg.yaml +28 -0
  246. mblt_vision/models/YOLO26s-sem-ade20k.yaml +17 -0
  247. mblt_vision/models/YOLO26s-sem.yaml +17 -0
  248. mblt_vision/models/YOLO26s.yaml +27 -0
  249. mblt_vision/models/YOLO26x-cls.yaml +23 -0
  250. mblt_vision/models/YOLO26x-depth.yaml +17 -0
  251. mblt_vision/models/YOLO26x-distill.yaml +27 -0
  252. mblt_vision/models/YOLO26x-obb.yaml +28 -0
  253. mblt_vision/models/YOLO26x-pose.yaml +28 -0
  254. mblt_vision/models/YOLO26x-seg.yaml +28 -0
  255. mblt_vision/models/YOLO26x-sem-ade20k.yaml +17 -0
  256. mblt_vision/models/YOLO26x-sem.yaml +17 -0
  257. mblt_vision/models/YOLO26x.yaml +27 -0
  258. mblt_vision/models/YOLOv10b.yaml +28 -0
  259. mblt_vision/models/YOLOv10l-face.yaml +28 -0
  260. mblt_vision/models/YOLOv10l.yaml +28 -0
  261. mblt_vision/models/YOLOv10m-face.yaml +28 -0
  262. mblt_vision/models/YOLOv10m.yaml +28 -0
  263. mblt_vision/models/YOLOv10n-face.yaml +28 -0
  264. mblt_vision/models/YOLOv10n.yaml +28 -0
  265. mblt_vision/models/YOLOv10s-face.yaml +28 -0
  266. mblt_vision/models/YOLOv10s.yaml +28 -0
  267. mblt_vision/models/YOLOv10x.yaml +28 -0
  268. mblt_vision/models/YOLOv3-spp.yaml +44 -0
  269. mblt_vision/models/YOLOv3-sppu.yaml +27 -0
  270. mblt_vision/models/YOLOv3-tiny.yaml +38 -0
  271. mblt_vision/models/YOLOv3-tinyu.yaml +27 -0
  272. mblt_vision/models/YOLOv3.yaml +44 -0
  273. mblt_vision/models/YOLOv3u.yaml +27 -0
  274. mblt_vision/models/YOLOv5l-cls.yaml +22 -0
  275. mblt_vision/models/YOLOv5l-seg.yaml +45 -0
  276. mblt_vision/models/YOLOv5l.yaml +44 -0
  277. mblt_vision/models/YOLOv5l6.yaml +50 -0
  278. mblt_vision/models/YOLOv5l6u.yaml +27 -0
  279. mblt_vision/models/YOLOv5lu.yaml +27 -0
  280. mblt_vision/models/YOLOv5m-cls.yaml +22 -0
  281. mblt_vision/models/YOLOv5m-seg.yaml +45 -0
  282. mblt_vision/models/YOLOv5m.yaml +45 -0
  283. mblt_vision/models/YOLOv5m6.yaml +50 -0
  284. mblt_vision/models/YOLOv5m6u.yaml +27 -0
  285. mblt_vision/models/YOLOv5mu.yaml +27 -0
  286. mblt_vision/models/YOLOv5n-cls.yaml +22 -0
  287. mblt_vision/models/YOLOv5n-seg.yaml +45 -0
  288. mblt_vision/models/YOLOv5n.yaml +44 -0
  289. mblt_vision/models/YOLOv5n6.yaml +50 -0
  290. mblt_vision/models/YOLOv5n6u.yaml +27 -0
  291. mblt_vision/models/YOLOv5nu.yaml +27 -0
  292. mblt_vision/models/YOLOv5s-cls.yaml +22 -0
  293. mblt_vision/models/YOLOv5s-seg.yaml +45 -0
  294. mblt_vision/models/YOLOv5s.yaml +44 -0
  295. mblt_vision/models/YOLOv5s6.yaml +50 -0
  296. mblt_vision/models/YOLOv5s6u.yaml +27 -0
  297. mblt_vision/models/YOLOv5su.yaml +27 -0
  298. mblt_vision/models/YOLOv5x-cls.yaml +22 -0
  299. mblt_vision/models/YOLOv5x-seg.yaml +45 -0
  300. mblt_vision/models/YOLOv5x.yaml +44 -0
  301. mblt_vision/models/YOLOv5x6.yaml +50 -0
  302. mblt_vision/models/YOLOv5x6u.yaml +27 -0
  303. mblt_vision/models/YOLOv5xu.yaml +27 -0
  304. mblt_vision/models/YOLOv6m-face.yaml +27 -0
  305. mblt_vision/models/YOLOv6n-face.yaml +27 -0
  306. mblt_vision/models/YOLOv7.yaml +44 -0
  307. mblt_vision/models/YOLOv7d6.yaml +50 -0
  308. mblt_vision/models/YOLOv7e6.yaml +50 -0
  309. mblt_vision/models/YOLOv7e6e.yaml +50 -0
  310. mblt_vision/models/YOLOv7w6.yaml +50 -0
  311. mblt_vision/models/YOLOv7x.yaml +44 -0
  312. mblt_vision/models/YOLOv8l-cls.yaml +23 -0
  313. mblt_vision/models/YOLOv8l-face.yaml +27 -0
  314. mblt_vision/models/YOLOv8l-obb.yaml +28 -0
  315. mblt_vision/models/YOLOv8l-pose.yaml +28 -0
  316. mblt_vision/models/YOLOv8l-seg.yaml +28 -0
  317. mblt_vision/models/YOLOv8l.yaml +27 -0
  318. mblt_vision/models/YOLOv8m-cls.yaml +23 -0
  319. mblt_vision/models/YOLOv8m-face.yaml +27 -0
  320. mblt_vision/models/YOLOv8m-obb.yaml +28 -0
  321. mblt_vision/models/YOLOv8m-pose.yaml +28 -0
  322. mblt_vision/models/YOLOv8m-seg.yaml +28 -0
  323. mblt_vision/models/YOLOv8m.yaml +27 -0
  324. mblt_vision/models/YOLOv8n-cls.yaml +23 -0
  325. mblt_vision/models/YOLOv8n-face.yaml +27 -0
  326. mblt_vision/models/YOLOv8n-obb.yaml +28 -0
  327. mblt_vision/models/YOLOv8n-pose.yaml +28 -0
  328. mblt_vision/models/YOLOv8n-seg.yaml +28 -0
  329. mblt_vision/models/YOLOv8n.yaml +27 -0
  330. mblt_vision/models/YOLOv8s-cls.yaml +23 -0
  331. mblt_vision/models/YOLOv8s-obb.yaml +28 -0
  332. mblt_vision/models/YOLOv8s-pose.yaml +28 -0
  333. mblt_vision/models/YOLOv8s-seg.yaml +28 -0
  334. mblt_vision/models/YOLOv8s.yaml +27 -0
  335. mblt_vision/models/YOLOv8x-cls.yaml +23 -0
  336. mblt_vision/models/YOLOv8x-obb.yaml +28 -0
  337. mblt_vision/models/YOLOv8x-pose-p6.yaml +28 -0
  338. mblt_vision/models/YOLOv8x-pose.yaml +28 -0
  339. mblt_vision/models/YOLOv8x-seg.yaml +28 -0
  340. mblt_vision/models/YOLOv8x.yaml +27 -0
  341. mblt_vision/models/YOLOv9c-seg.yaml +28 -0
  342. mblt_vision/models/YOLOv9c.yaml +27 -0
  343. mblt_vision/models/YOLOv9e-seg.yaml +28 -0
  344. mblt_vision/models/YOLOv9e.yaml +27 -0
  345. mblt_vision/models/YOLOv9m.yaml +27 -0
  346. mblt_vision/models/YOLOv9s.yaml +27 -0
  347. mblt_vision/models/YOLOv9t.yaml +27 -0
  348. mblt_vision/obb/__init__.py +39 -0
  349. mblt_vision/object_detection/__init__.py +153 -0
  350. mblt_vision/pose_estimation/__init__.py +41 -0
  351. mblt_vision/py.typed +1 -0
  352. mblt_vision/semantic_segmentation/__init__.py +29 -0
  353. mblt_vision/utils/__init__.py +0 -0
  354. mblt_vision/utils/datasets/__init__.py +85 -0
  355. mblt_vision/utils/datasets/ade20k.py +41 -0
  356. mblt_vision/utils/datasets/cityscapes.py +66 -0
  357. mblt_vision/utils/datasets/coco.py +243 -0
  358. mblt_vision/utils/datasets/dataloader.py +1016 -0
  359. mblt_vision/utils/datasets/dotav1.py +59 -0
  360. mblt_vision/utils/datasets/imagenet.py +29 -0
  361. mblt_vision/utils/datasets/organizer.py +2145 -0
  362. mblt_vision/utils/datasets/readiness.py +1063 -0
  363. mblt_vision/utils/evaluation/__init__.py +51 -0
  364. mblt_vision/utils/evaluation/_result.py +22 -0
  365. mblt_vision/utils/evaluation/eval_ade20k.py +302 -0
  366. mblt_vision/utils/evaluation/eval_cityscapes.py +32 -0
  367. mblt_vision/utils/evaluation/eval_coco.py +465 -0
  368. mblt_vision/utils/evaluation/eval_dota.py +878 -0
  369. mblt_vision/utils/evaluation/eval_imagenet.py +151 -0
  370. mblt_vision/utils/evaluation/eval_nyu_depth.py +189 -0
  371. mblt_vision/utils/evaluation/eval_widerface.py +440 -0
  372. mblt_vision/utils/letterbox.py +118 -0
  373. mblt_vision/utils/postprocess/__init__.py +9 -0
  374. mblt_vision/utils/postprocess/_letterbox.py +102 -0
  375. mblt_vision/utils/postprocess/base.py +743 -0
  376. mblt_vision/utils/postprocess/build_post.py +120 -0
  377. mblt_vision/utils/postprocess/cls_post.py +117 -0
  378. mblt_vision/utils/postprocess/common.py +1571 -0
  379. mblt_vision/utils/postprocess/depth_post.py +106 -0
  380. mblt_vision/utils/postprocess/semantic_seg_post.py +192 -0
  381. mblt_vision/utils/postprocess/yolo_anchor_post.py +469 -0
  382. mblt_vision/utils/postprocess/yolo_anchorless_post.py +952 -0
  383. mblt_vision/utils/postprocess/yolo_dflfree_post.py +983 -0
  384. mblt_vision/utils/postprocess/yolo_nmsfree_post.py +176 -0
  385. mblt_vision/utils/preprocess/__init__.py +27 -0
  386. mblt_vision/utils/preprocess/_validation.py +66 -0
  387. mblt_vision/utils/preprocess/base.py +157 -0
  388. mblt_vision/utils/preprocess/build_pre.py +48 -0
  389. mblt_vision/utils/preprocess/center_crop.py +75 -0
  390. mblt_vision/utils/preprocess/letterbox.py +123 -0
  391. mblt_vision/utils/preprocess/normalize.py +94 -0
  392. mblt_vision/utils/preprocess/order.py +74 -0
  393. mblt_vision/utils/preprocess/reader.py +94 -0
  394. mblt_vision/utils/preprocess/resize.py +202 -0
  395. mblt_vision/utils/preprocess/yolo_pre.py +7 -0
  396. mblt_vision/utils/results.py +725 -0
  397. mblt_vision/utils/types.py +15 -0
  398. mblt_vision/wrapper.py +1121 -0
  399. mblt_vision_python-0.0.0.dist-info/METADATA +152 -0
  400. mblt_vision_python-0.0.0.dist-info/RECORD +404 -0
  401. mblt_vision_python-0.0.0.dist-info/WHEEL +5 -0
  402. mblt_vision_python-0.0.0.dist-info/entry_points.txt +2 -0
  403. mblt_vision_python-0.0.0.dist-info/licenses/LICENSE +28 -0
  404. mblt_vision_python-0.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,440 @@
1
+ """Evaluation script for WiderFace face detection."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import math
6
+ import os
7
+ from pathlib import Path
8
+ from time import time
9
+ from typing import TYPE_CHECKING, Any, NamedTuple, cast
10
+
11
+ import numpy as np
12
+ from mblt_vision.utils.postprocess.base import YOLODetectionPostBase
13
+ from scipy.io import loadmat
14
+ from tqdm import tqdm
15
+
16
+ from ..datasets import CustomWiderFaceDataset, get_widerface_loader
17
+ from ..datasets.readiness import (
18
+ _load_widerface_image_names,
19
+ _widerface_image_shapes,
20
+ _widerface_difficulty_metadata_ready,
21
+ )
22
+
23
+ if TYPE_CHECKING:
24
+ from ...wrapper import MBLT_Engine
25
+
26
+ CustomWiderface = CustomWiderFaceDataset
27
+
28
+
29
+ class WiderFaceResult(NamedTuple):
30
+ """WiderFace AP metrics."""
31
+
32
+ easy_ap: float
33
+ medium_ap: float
34
+ hard_ap: float
35
+
36
+ @property
37
+ def mean_ap(self) -> float:
38
+ """Return the mean AP across Easy, Medium, and Hard."""
39
+
40
+ return (self.easy_ap + self.medium_ap + self.hard_ap) / 3.0
41
+
42
+ @property
43
+ def primary_score(self) -> float:
44
+ """Return mean AP across the three validation splits."""
45
+
46
+ return self.mean_ap
47
+
48
+ @property
49
+ def secondary_score(self) -> float:
50
+ """Return Hard-set AP."""
51
+
52
+ return self.hard_ap
53
+
54
+
55
+ def _empty_prediction() -> np.ndarray:
56
+ """Return an empty WiderFace prediction array."""
57
+
58
+ return np.zeros((0, 5), dtype=np.float32)
59
+
60
+
61
+ def _initialize_predictions(
62
+ dataset: CustomWiderFaceDataset,
63
+ ) -> dict[str, dict[str, np.ndarray]]:
64
+ """Initialize empty predictions for every WiderFace sample."""
65
+
66
+ predictions: dict[str, dict[str, np.ndarray]] = {}
67
+ for _, event_name, file_name in dataset.samples:
68
+ predictions.setdefault(event_name, {})[os.path.splitext(file_name)[0]] = (
69
+ _empty_prediction()
70
+ )
71
+ return predictions
72
+
73
+
74
+ def _boxes_scores_to_prediction(
75
+ boxes: list[list[float]], scores: list[float]
76
+ ) -> np.ndarray:
77
+ """Convert xywh boxes and scores to a WiderFace prediction array."""
78
+
79
+ if len(boxes) != len(scores):
80
+ raise ValueError(
81
+ "WiderFace postprocess returned unequal box and score counts: "
82
+ f"boxes={len(boxes)}, scores={len(scores)}."
83
+ )
84
+ if not boxes:
85
+ return _empty_prediction()
86
+ prediction = np.zeros((len(boxes), 5), dtype=np.float32)
87
+ for index, (box, score) in enumerate(zip(boxes, scores)):
88
+ prediction[index, :4] = np.asarray(box, dtype=np.float32)
89
+ prediction[index, 4] = float(score)
90
+ return prediction
91
+
92
+
93
+ def eval_widerface(
94
+ model: MBLT_Engine,
95
+ data_path: str,
96
+ batch_size: int,
97
+ conf_thres: float | None = None,
98
+ iou_thres: float | None = None,
99
+ ) -> WiderFaceResult:
100
+ """Evaluate a face-detection model on WiderFace validation data.
101
+
102
+ Args:
103
+ model: The face-detection engine to evaluate.
104
+ data_path: Organized WiderFace dataset root.
105
+ batch_size: Validation batch size.
106
+ conf_thres: Optional confidence threshold override.
107
+ iou_thres: Optional IoU threshold override.
108
+
109
+ Returns:
110
+ WiderFace Easy, Medium, and Hard AP metrics.
111
+ """
112
+
113
+ if model.post_cfg["task"] != "face_detection":
114
+ raise NotImplementedError(
115
+ f"Task {model.post_cfg['task']} is not supported for WiderFace evaluation."
116
+ )
117
+ dataset_name = model.post_cfg.get("dataset")
118
+ if not isinstance(dataset_name, str) or dataset_name.lower() != "widerface":
119
+ raise ValueError(
120
+ "WiderFace evaluation requires model post_cfg.dataset to be 'widerface', "
121
+ f"got {dataset_name!r}."
122
+ )
123
+
124
+ dataset_root = Path(data_path)
125
+ expected_images = _load_widerface_image_names(dataset_root / "wider_face_val.mat")
126
+ image_shapes = (
127
+ _widerface_image_shapes(dataset_root, expected_images)
128
+ if expected_images is not None
129
+ else None
130
+ )
131
+ if (
132
+ expected_images is None
133
+ or image_shapes is None
134
+ or not _widerface_difficulty_metadata_ready(
135
+ dataset_root, expected_images, image_shapes=image_shapes
136
+ )
137
+ ):
138
+ raise ValueError(
139
+ "WiderFace evaluation metadata is malformed or has inconsistent difficulty indices."
140
+ )
141
+
142
+ dataset = CustomWiderface(os.path.join(data_path, "images"))
143
+ actual_images: dict[str, set[str]] = {}
144
+ for _, event_name, file_name in dataset.samples:
145
+ actual_images.setdefault(event_name, set()).add(file_name)
146
+ if actual_images != expected_images or sum(
147
+ len(file_names) for file_names in actual_images.values()
148
+ ) != len(dataset.samples):
149
+ raise ValueError(
150
+ "WiderFace image tree does not match the validation metadata identities."
151
+ )
152
+ dataloader = get_widerface_loader(
153
+ dataset, batch_size, model.preprocess_with_metadata
154
+ )
155
+ model.set_postprocess_thresholds(conf_thres=conf_thres, iou_thres=iou_thres)
156
+
157
+ predictions = _initialize_predictions(dataset)
158
+ num_data = len(dataset)
159
+ total_iter = math.ceil(num_data / batch_size)
160
+ pbar = tqdm(dataloader, total=total_iter, desc="Evaluating WiderFace")
161
+ inference_time = 0.0
162
+ cum_num_data = 0
163
+
164
+ for input_npu, org_shape, ratio_pad, target_classes, fnames in pbar:
165
+ cum_num_data += len(fnames)
166
+ tic = time()
167
+ out_npu = model(input_npu)
168
+ inference_time += time() - tic
169
+ nms_outs = model.postprocess(out_npu)
170
+ input_shape = (int(input_npu.shape[1]), int(input_npu.shape[2]))
171
+ img0_shapes = [(int(shape[0]), int(shape[1])) for shape in org_shape.tolist()]
172
+ postprocessor = cast(YOLODetectionPostBase, model.postprocessor)
173
+ _, boxes_list, scores_list = postprocessor.nmsout2eval(
174
+ nms_outs.output,
175
+ input_shape,
176
+ img0_shapes,
177
+ ratio_pad=ratio_pad,
178
+ )
179
+ batch_lengths = {
180
+ "input batch": int(input_npu.shape[0]),
181
+ "original shapes": len(org_shape),
182
+ "ratio pads": len(ratio_pad),
183
+ "target classes": len(target_classes),
184
+ "file names": len(fnames),
185
+ "boxes": len(boxes_list),
186
+ "scores": len(scores_list),
187
+ }
188
+ if len(set(batch_lengths.values())) != 1:
189
+ details = ", ".join(
190
+ f"{name}={length}" for name, length in batch_lengths.items()
191
+ )
192
+ raise ValueError(f"WiderFace evaluation batch length mismatch: {details}.")
193
+
194
+ for event_name, file_name, boxes, scores in zip(
195
+ target_classes, fnames, boxes_list, scores_list, strict=True
196
+ ):
197
+ predictions[event_name][os.path.splitext(file_name)[0]] = (
198
+ _boxes_scores_to_prediction(boxes, scores)
199
+ )
200
+
201
+ pbar.set_postfix_str(f"NPU FPS: {cum_num_data / inference_time:.3f}")
202
+
203
+ pbar.close()
204
+ aps = evaluation(norm_score(predictions), data_path)
205
+ print("WiderFace evaluation completed")
206
+ return WiderFaceResult(*aps)
207
+
208
+
209
+ def bbox_overlaps(boxes: np.ndarray, query_boxes: np.ndarray) -> np.ndarray:
210
+ """Compute pairwise IoU overlaps between boxes and query boxes."""
211
+
212
+ boxes = boxes.astype(np.float32)
213
+ query_boxes = query_boxes.astype(np.float32)
214
+
215
+ boxes = boxes[:, None, :]
216
+ query_boxes = query_boxes[None, :, :]
217
+
218
+ iw = (
219
+ np.minimum(boxes[..., 2], query_boxes[..., 2])
220
+ - np.maximum(boxes[..., 0], query_boxes[..., 0])
221
+ + 1
222
+ )
223
+ ih = (
224
+ np.minimum(boxes[..., 3], query_boxes[..., 3])
225
+ - np.maximum(boxes[..., 1], query_boxes[..., 1])
226
+ + 1
227
+ )
228
+ iw = np.maximum(iw, 0)
229
+ ih = np.maximum(ih, 0)
230
+ inter = iw * ih
231
+
232
+ box_area = (boxes[..., 2] - boxes[..., 0] + 1) * (boxes[..., 3] - boxes[..., 1] + 1)
233
+ query_area = (query_boxes[..., 2] - query_boxes[..., 0] + 1) * (
234
+ query_boxes[..., 3] - query_boxes[..., 1] + 1
235
+ )
236
+ union = box_area + query_area - inter
237
+
238
+ return inter / union
239
+
240
+
241
+ def get_gt_boxes(gt_dir: str) -> tuple[Any, ...]:
242
+ """Load WiderFace evaluation `.mat` files from the organized dataset."""
243
+
244
+ gt_mat = loadmat(os.path.join(gt_dir, "wider_face_val.mat"))
245
+ hard_mat = loadmat(os.path.join(gt_dir, "wider_hard_val.mat"))
246
+ medium_mat = loadmat(os.path.join(gt_dir, "wider_medium_val.mat"))
247
+ easy_mat = loadmat(os.path.join(gt_dir, "wider_easy_val.mat"))
248
+
249
+ facebox_list = gt_mat["face_bbx_list"]
250
+ event_list = gt_mat["event_list"]
251
+ file_list = gt_mat["file_list"]
252
+ hard_gt_list = hard_mat["gt_list"]
253
+ medium_gt_list = medium_mat["gt_list"]
254
+ easy_gt_list = easy_mat["gt_list"]
255
+
256
+ return (
257
+ facebox_list,
258
+ event_list,
259
+ file_list,
260
+ hard_gt_list,
261
+ medium_gt_list,
262
+ easy_gt_list,
263
+ )
264
+
265
+
266
+ def norm_score(pred: dict[str, Any]) -> dict[str, Any]:
267
+ """Normalize WiderFace prediction scores to ``[0, 1]``."""
268
+
269
+ max_score = -1e9
270
+ min_score = 1e9
271
+ found = False
272
+
273
+ for _, event_predictions in pred.items():
274
+ for _, image_predictions in event_predictions.items():
275
+ if len(image_predictions) == 0:
276
+ continue
277
+ found = True
278
+ _min = float(np.min(image_predictions[:, -1]))
279
+ _max = float(np.max(image_predictions[:, -1]))
280
+ if _max > max_score:
281
+ max_score = _max
282
+ if _min < min_score:
283
+ min_score = _min
284
+
285
+ if not found:
286
+ return pred
287
+
288
+ diff = max_score - min_score
289
+ if diff <= 0:
290
+ return pred
291
+
292
+ for _, event_predictions in pred.items():
293
+ for _, image_predictions in event_predictions.items():
294
+ if len(image_predictions) == 0:
295
+ continue
296
+ image_predictions[:, -1] = (image_predictions[:, -1] - min_score) / diff
297
+
298
+ return pred
299
+
300
+
301
+ def image_eval(
302
+ pred: np.ndarray, gt: np.ndarray, ignore: np.ndarray, iou_thresh: float
303
+ ) -> tuple[np.ndarray, np.ndarray]:
304
+ """Evaluate one image worth of WiderFace predictions."""
305
+
306
+ _pred = pred.copy()
307
+ _gt = gt.copy()
308
+ pred_recall = np.zeros(_pred.shape[0])
309
+ recall_list = np.zeros(_gt.shape[0])
310
+ proposal_list = np.ones(_pred.shape[0])
311
+
312
+ _pred[:, 2] = _pred[:, 2] + _pred[:, 0]
313
+ _pred[:, 3] = _pred[:, 3] + _pred[:, 1]
314
+ _gt[:, 2] = _gt[:, 2] + _gt[:, 0]
315
+ _gt[:, 3] = _gt[:, 3] + _gt[:, 1]
316
+
317
+ overlaps = bbox_overlaps(_pred[:, :4], _gt)
318
+
319
+ for prediction_index in range(_pred.shape[0]):
320
+ gt_overlap = overlaps[prediction_index]
321
+ max_overlap = np.max(gt_overlap)
322
+ max_idx = np.argmax(gt_overlap)
323
+ if max_overlap >= iou_thresh:
324
+ if ignore[max_idx] == 0:
325
+ recall_list[max_idx] = -1
326
+ proposal_list[prediction_index] = -1
327
+ elif recall_list[max_idx] == 0:
328
+ recall_list[max_idx] = 1
329
+
330
+ r_keep_index = np.where(recall_list == 1)[0]
331
+ pred_recall[prediction_index] = len(r_keep_index)
332
+ return pred_recall, proposal_list
333
+
334
+
335
+ def img_pr_info(
336
+ thresh_num: int,
337
+ pred_info: np.ndarray,
338
+ proposal_list: np.ndarray,
339
+ pred_recall: np.ndarray,
340
+ ) -> np.ndarray:
341
+ """Compute precision and recall contributions for one image."""
342
+
343
+ pr_info = np.zeros((thresh_num, 2), dtype=np.float32)
344
+ for threshold_index in range(thresh_num):
345
+ thresh = 1 - (threshold_index + 1) / thresh_num
346
+ recall_index = np.where(pred_info[:, 4] >= thresh)[0]
347
+ if len(recall_index) == 0:
348
+ pr_info[threshold_index, 0] = 0
349
+ pr_info[threshold_index, 1] = 0
350
+ else:
351
+ last_index = recall_index[-1]
352
+ proposal_index = np.where(proposal_list[: last_index + 1] == 1)[0]
353
+ pr_info[threshold_index, 0] = len(proposal_index)
354
+ pr_info[threshold_index, 1] = pred_recall[last_index]
355
+ return pr_info
356
+
357
+
358
+ def dataset_pr_info(
359
+ thresh_num: int, pr_curve: np.ndarray, count_face: int
360
+ ) -> np.ndarray:
361
+ """Normalize a WiderFace precision-recall accumulator."""
362
+
363
+ _pr_curve = np.zeros((thresh_num, 2), dtype=np.float32)
364
+ for threshold_index in range(thresh_num):
365
+ proposals = pr_curve[threshold_index, 0]
366
+ matched = pr_curve[threshold_index, 1]
367
+ _pr_curve[threshold_index, 0] = matched / proposals if proposals > 0 else 0.0
368
+ _pr_curve[threshold_index, 1] = matched / count_face if count_face > 0 else 0.0
369
+ return _pr_curve
370
+
371
+
372
+ def voc_ap(rec: np.ndarray, prec: np.ndarray) -> float:
373
+ """Compute VOC-style average precision."""
374
+
375
+ mrec = np.concatenate((np.array([0.0]), rec, np.array([1.0])))
376
+ mpre = np.concatenate((np.array([0.0]), prec, np.array([0.0])))
377
+
378
+ for index in range(mpre.size - 1, 0, -1):
379
+ mpre[index - 1] = np.maximum(mpre[index - 1], mpre[index])
380
+
381
+ recall_change_index = np.where(mrec[1:] != mrec[:-1])[0]
382
+ ap = np.sum(
383
+ (mrec[recall_change_index + 1] - mrec[recall_change_index])
384
+ * mpre[recall_change_index + 1]
385
+ )
386
+ return float(ap)
387
+
388
+
389
+ def evaluation(
390
+ pred: dict[str, Any], gt_path: str, iou_thresh: float = 0.5
391
+ ) -> list[float]:
392
+ """Evaluate WiderFace predictions against Easy, Medium, and Hard settings."""
393
+
394
+ facebox_list, event_list, file_list, hard_gt_list, medium_gt_list, easy_gt_list = (
395
+ get_gt_boxes(gt_path)
396
+ )
397
+ event_num = len(event_list)
398
+ thresh_num = 1000
399
+ settings = ["easy", "medium", "hard"]
400
+ setting_gts = [easy_gt_list, medium_gt_list, hard_gt_list]
401
+ aps = []
402
+ for setting_id in range(3):
403
+ gt_list = setting_gts[setting_id]
404
+ count_face = 0
405
+ pr_curve = np.zeros((thresh_num, 2), dtype=np.float32)
406
+ pbar = tqdm(range(event_num))
407
+ for event_index in pbar:
408
+ pbar.set_description(f"Processing {settings[setting_id]}")
409
+ event_name = str(event_list[event_index][0][0])
410
+ img_list = file_list[event_index][0]
411
+ pred_list = pred[event_name]
412
+ sub_gt_list = gt_list[event_index][0]
413
+ gt_bbx_list = facebox_list[event_index][0]
414
+ for image_index, img_info in enumerate(img_list):
415
+ pred_info = pred_list[str(img_info[0][0])]
416
+ gt_boxes = np.array(gt_bbx_list[image_index][0], dtype=np.float32)
417
+ keep_index = np.array(sub_gt_list[image_index][0], dtype=np.int64)
418
+ count_face += len(keep_index)
419
+
420
+ if len(gt_boxes) == 0 or len(pred_info) == 0:
421
+ continue
422
+ ignore = np.zeros(gt_boxes.shape[0])
423
+ if len(keep_index) != 0:
424
+ ignore[keep_index - 1] = 1
425
+ pred_recall, proposal_list = image_eval(
426
+ pred_info, gt_boxes, ignore, iou_thresh
427
+ )
428
+ pr_curve += img_pr_info(
429
+ thresh_num, pred_info, proposal_list, pred_recall
430
+ )
431
+ pbar.close()
432
+ pr_curve = dataset_pr_info(thresh_num, pr_curve, count_face)
433
+ aps.append(voc_ap(pr_curve[:, 1], pr_curve[:, 0]))
434
+
435
+ print("==================== Results ====================")
436
+ print(f"Easy Val AP: {aps[0]}")
437
+ print(f"Medium Val AP: {aps[1]}")
438
+ print(f"Hard Val AP: {aps[2]}")
439
+ print("=================================================")
440
+ return aps
@@ -0,0 +1,118 @@
1
+ """Shared forward and inverse geometry for aspect-preserving letterboxing."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import dataclass
6
+ from typing import TypeAlias
7
+
8
+ RatioPad: TypeAlias = tuple[tuple[float, float], tuple[float, float]]
9
+
10
+
11
+ @dataclass(frozen=True)
12
+ class LetterBoxGeometry:
13
+ """Geometry shared by letterbox preprocessing and output restoration."""
14
+
15
+ input_shape: tuple[int, int]
16
+ original_shape: tuple[int, int]
17
+ ratio: float
18
+ resized_shape: tuple[int, int]
19
+ pad: tuple[int, int]
20
+
21
+ @classmethod
22
+ def from_shapes(
23
+ cls,
24
+ input_shape: tuple[int, int],
25
+ original_shape: tuple[int, int],
26
+ ) -> LetterBoxGeometry:
27
+ """Calculate YOLO-style centered letterbox geometry.
28
+
29
+ Args:
30
+ input_shape: Target shape as ``(height, width)``.
31
+ original_shape: Source shape as ``(height, width)``.
32
+
33
+ Returns:
34
+ Calculated resize ratio, resized shape, and top-left padding.
35
+ """
36
+
37
+ input_height, input_width = input_shape
38
+ original_height, original_width = original_shape
39
+ ratio = min(input_height / original_height, input_width / original_width)
40
+ resized_height = int(round(original_height * ratio))
41
+ resized_width = int(round(original_width * ratio))
42
+ left = int(round((input_width - resized_width) / 2 - 0.1))
43
+ top = int(round((input_height - resized_height) / 2 - 0.1))
44
+ return cls(
45
+ input_shape=input_shape,
46
+ original_shape=original_shape,
47
+ ratio=ratio,
48
+ resized_shape=(resized_height, resized_width),
49
+ pad=(left, top),
50
+ )
51
+
52
+ @property
53
+ def ratio_pad(self) -> RatioPad:
54
+ """Return metadata consumed by inverse letterbox operations."""
55
+
56
+ return ((self.ratio, self.ratio), self.pad)
57
+
58
+ @property
59
+ def borders(self) -> tuple[int, int, int, int]:
60
+ """Return OpenCV border widths as ``(top, bottom, left, right)``."""
61
+
62
+ input_height, input_width = self.input_shape
63
+ resized_height, resized_width = self.resized_shape
64
+ left, top = self.pad
65
+ return (
66
+ top,
67
+ input_height - resized_height - top,
68
+ left,
69
+ input_width - resized_width - left,
70
+ )
71
+
72
+ def crop_bounds(
73
+ self,
74
+ output_shape: tuple[int, int],
75
+ pad: tuple[float, float] | None = None,
76
+ ) -> tuple[int, int, int, int]:
77
+ """Scale inverse-letterbox crop bounds to a dense output shape.
78
+
79
+ Args:
80
+ output_shape: Dense output shape as ``(height, width)``.
81
+ pad: Optional exact top-left padding metadata as ``(x, y)``.
82
+
83
+ Returns:
84
+ Crop bounds as ``(top, bottom, left, right)``.
85
+ """
86
+
87
+ output_height, output_width = output_shape
88
+ input_height, input_width = self.input_shape
89
+ scale_x = output_width / input_width
90
+ scale_y = output_height / input_height
91
+ pad_x, pad_y = self.pad if pad is None else pad
92
+ left = int(round(pad_x * scale_x))
93
+ top = int(round(pad_y * scale_y))
94
+ resized_height, resized_width = self.resized_shape
95
+ right = left + int(round(resized_width * scale_x))
96
+ bottom = top + int(round(resized_height * scale_y))
97
+ return top, bottom, left, right
98
+
99
+
100
+ def resolve_ratio_pad(
101
+ input_shape: tuple[int, int],
102
+ original_shape: tuple[int, int],
103
+ ratio_pad: RatioPad | None = None,
104
+ ) -> RatioPad:
105
+ """Return supplied letterbox metadata or derive it from image shapes.
106
+
107
+ Args:
108
+ input_shape: Letterboxed shape as ``(height, width)``.
109
+ original_shape: Source shape as ``(height, width)``.
110
+ ratio_pad: Optional metadata recorded during preprocessing.
111
+
112
+ Returns:
113
+ Resize ratios and top-left padding as ``((ratio_x, ratio_y), (pad_x, pad_y))``.
114
+ """
115
+
116
+ if ratio_pad is not None:
117
+ return ratio_pad
118
+ return LetterBoxGeometry.from_shapes(input_shape, original_shape).ratio_pad
@@ -0,0 +1,9 @@
1
+ """
2
+ Postprocessing utilities for vision models.
3
+ """
4
+
5
+ from .build_post import build_postprocess
6
+ from .depth_post import DepthPost
7
+ from .semantic_seg_post import SemanticSegPost
8
+
9
+ __all__ = ["DepthPost", "SemanticSegPost", "build_postprocess"]
@@ -0,0 +1,102 @@
1
+ """Private helpers shared by dense prediction postprocessors."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from collections.abc import Sequence
6
+ from typing import Any
7
+
8
+ import torch
9
+
10
+ from ..letterbox import LetterBoxGeometry, RatioPad, resolve_ratio_pad
11
+ from .common import normalize_ratio_pads
12
+
13
+
14
+ def get_letterbox_input_shape(
15
+ pre_cfg: dict[str, Any],
16
+ requirement_name: str,
17
+ size_name: str | None = None,
18
+ ) -> tuple[int, int]:
19
+ """Validate and return a dense task's configured letterbox input shape.
20
+
21
+ Args:
22
+ pre_cfg: Model preprocessing configuration.
23
+ requirement_name: Task name used when LetterBox is absent.
24
+ size_name: Optional shorter name used for invalid-size errors.
25
+
26
+ Returns:
27
+ Configured input height and width.
28
+
29
+ Raises:
30
+ ValueError: If LetterBox or its two-item image size is missing or invalid.
31
+ """
32
+
33
+ letterbox_cfg = pre_cfg.get("LetterBox")
34
+ if not isinstance(letterbox_cfg, dict) or "img_size" not in letterbox_cfg:
35
+ raise ValueError(
36
+ f"{requirement_name} requires a LetterBox configuration in pre_cfg."
37
+ )
38
+ image_size = letterbox_cfg["img_size"]
39
+ if not isinstance(image_size, list) or len(image_size) != 2:
40
+ raise ValueError(
41
+ f"{size_name or requirement_name} LetterBox img_size must be a two-item [height, width] list."
42
+ )
43
+ return int(image_size[0]), int(image_size[1])
44
+
45
+
46
+ def resolve_ratio_pads(
47
+ ratio_pad: RatioPad | Sequence[RatioPad | None] | None,
48
+ batch_size: int,
49
+ shapes: Sequence[tuple[int, int]],
50
+ input_shape: tuple[int, int],
51
+ ) -> list[RatioPad]:
52
+ """Normalize letterbox metadata and derive values missing from a dense task batch.
53
+
54
+ Args:
55
+ ratio_pad: Shared or per-image letterbox metadata.
56
+ batch_size: Number of images in the output batch.
57
+ shapes: Original image shapes.
58
+ input_shape: Configured model input shape.
59
+
60
+ Returns:
61
+ One resolved ratio/padding pair per batch item.
62
+
63
+ Raises:
64
+ ValueError: If ratio/padding metadata is invalid for the batch.
65
+ """
66
+
67
+ pads = normalize_ratio_pads(ratio_pad, batch_size)
68
+ return [
69
+ resolve_ratio_pad(input_shape, shape, pad) for pad, shape in zip(pads, shapes)
70
+ ]
71
+
72
+
73
+ def crop_letterbox(
74
+ output: torch.Tensor,
75
+ shape: tuple[int, int],
76
+ ratio_pad: RatioPad,
77
+ input_shape: tuple[int, int],
78
+ task_name: str,
79
+ ) -> torch.Tensor:
80
+ """Crop letterbox padding from a dense two-dimensional output.
81
+
82
+ Args:
83
+ output: Dense two-dimensional model output.
84
+ shape: Original image height and width.
85
+ ratio_pad: Resize ratio and padding applied during preprocessing.
86
+ input_shape: Configured model input height and width.
87
+ task_name: Task label used in validation errors.
88
+
89
+ Returns:
90
+ Output with letterbox padding removed.
91
+
92
+ Raises:
93
+ ValueError: If inverse letterboxing produces an empty crop.
94
+ """
95
+
96
+ geometry = LetterBoxGeometry.from_shapes(input_shape, shape)
97
+ output_shape = (int(output.shape[0]), int(output.shape[1]))
98
+ top, bottom, left, right = geometry.crop_bounds(output_shape, pad=ratio_pad[1])
99
+ cropped = output[top:bottom, left:right]
100
+ if cropped.numel() == 0:
101
+ raise ValueError(f"{task_name} letterbox restoration produced an empty crop.")
102
+ return cropped