xView.yaml 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. # Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license
  2. # DIUx xView 2018 Challenge https://challenge.xviewdataset.org by U.S. National Geospatial-Intelligence Agency (NGA)
  3. # -------- DOWNLOAD DATA MANUALLY and jar xf val_images.zip to 'datasets/xView' before running train command! --------
  4. # Documentation: https://docs.ultralytics.com/datasets/detect/xview/
  5. # Example usage: yolo train data=xView.yaml
  6. # parent
  7. # ├── ultralytics
  8. # └── datasets
  9. # └── xView ← downloads here (20.7 GB)
  10. # Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, path/to/imgs2, ..]
  11. path: ../datasets/xView # dataset root dir
  12. train: images/autosplit_train.txt # train images (relative to 'path') 90% of 847 train images
  13. val: images/autosplit_val.txt # train images (relative to 'path') 10% of 847 train images
  14. # Classes
  15. names:
  16. 0: Fixed-wing Aircraft
  17. 1: Small Aircraft
  18. 2: Cargo Plane
  19. 3: Helicopter
  20. 4: Passenger Vehicle
  21. 5: Small Car
  22. 6: Bus
  23. 7: Pickup Truck
  24. 8: Utility Truck
  25. 9: Truck
  26. 10: Cargo Truck
  27. 11: Truck w/Box
  28. 12: Truck Tractor
  29. 13: Trailer
  30. 14: Truck w/Flatbed
  31. 15: Truck w/Liquid
  32. 16: Crane Truck
  33. 17: Railway Vehicle
  34. 18: Passenger Car
  35. 19: Cargo Car
  36. 20: Flat Car
  37. 21: Tank car
  38. 22: Locomotive
  39. 23: Maritime Vessel
  40. 24: Motorboat
  41. 25: Sailboat
  42. 26: Tugboat
  43. 27: Barge
  44. 28: Fishing Vessel
  45. 29: Ferry
  46. 30: Yacht
  47. 31: Container Ship
  48. 32: Oil Tanker
  49. 33: Engineering Vehicle
  50. 34: Tower crane
  51. 35: Container Crane
  52. 36: Reach Stacker
  53. 37: Straddle Carrier
  54. 38: Mobile Crane
  55. 39: Dump Truck
  56. 40: Haul Truck
  57. 41: Scraper/Tractor
  58. 42: Front loader/Bulldozer
  59. 43: Excavator
  60. 44: Cement Mixer
  61. 45: Ground Grader
  62. 46: Hut/Tent
  63. 47: Shed
  64. 48: Building
  65. 49: Aircraft Hangar
  66. 50: Damaged Building
  67. 51: Facility
  68. 52: Construction Site
  69. 53: Vehicle Lot
  70. 54: Helipad
  71. 55: Storage Tank
  72. 56: Shipping container lot
  73. 57: Shipping Container
  74. 58: Pylon
  75. 59: Tower
  76. # Download script/URL (optional) ---------------------------------------------------------------------------------------
  77. download: |
  78. import json
  79. import os
  80. from pathlib import Path
  81. import numpy as np
  82. from PIL import Image
  83. from tqdm import tqdm
  84. from ultralytics.data.utils import autosplit
  85. from ultralytics.utils.ops import xyxy2xywhn
  86. def convert_labels(fname=Path('xView/xView_train.geojson')):
  87. # Convert xView geoJSON labels to YOLO format
  88. path = fname.parent
  89. with open(fname) as f:
  90. print(f'Loading {fname}...')
  91. data = json.load(f)
  92. # Make dirs
  93. labels = Path(path / 'labels' / 'train')
  94. os.system(f'rm -rf {labels}')
  95. labels.mkdir(parents=True, exist_ok=True)
  96. # xView classes 11-94 to 0-59
  97. xview_class2index = [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, -1, 3, -1, 4, 5, 6, 7, 8, -1, 9, 10, 11,
  98. 12, 13, 14, 15, -1, -1, 16, 17, 18, 19, 20, 21, 22, -1, 23, 24, 25, -1, 26, 27, -1, 28, -1,
  99. 29, 30, 31, 32, 33, 34, 35, 36, 37, -1, 38, 39, 40, 41, 42, 43, 44, 45, -1, -1, -1, -1, 46,
  100. 47, 48, 49, -1, 50, 51, -1, 52, -1, -1, -1, 53, 54, -1, 55, -1, -1, 56, -1, 57, -1, 58, 59]
  101. shapes = {}
  102. for feature in tqdm(data['features'], desc=f'Converting {fname}'):
  103. p = feature['properties']
  104. if p['bounds_imcoords']:
  105. id = p['image_id']
  106. file = path / 'train_images' / id
  107. if file.exists(): # 1395.tif missing
  108. try:
  109. box = np.array([int(num) for num in p['bounds_imcoords'].split(",")])
  110. assert box.shape[0] == 4, f'incorrect box shape {box.shape[0]}'
  111. cls = p['type_id']
  112. cls = xview_class2index[int(cls)] # xView class to 0-60
  113. assert 59 >= cls >= 0, f'incorrect class index {cls}'
  114. # Write YOLO label
  115. if id not in shapes:
  116. shapes[id] = Image.open(file).size
  117. box = xyxy2xywhn(box[None].astype(np.float), w=shapes[id][0], h=shapes[id][1], clip=True)
  118. with open((labels / id).with_suffix('.txt'), 'a') as f:
  119. f.write(f"{cls} {' '.join(f'{x:.6f}' for x in box[0])}\n") # write label.txt
  120. except Exception as e:
  121. print(f'WARNING: skipping one label for {file}: {e}')
  122. # Download manually from https://challenge.xviewdataset.org
  123. dir = Path(yaml['path']) # dataset root dir
  124. # urls = ['https://d307kc0mrhucc3.cloudfront.net/train_labels.zip', # train labels
  125. # 'https://d307kc0mrhucc3.cloudfront.net/train_images.zip', # 15G, 847 train images
  126. # 'https://d307kc0mrhucc3.cloudfront.net/val_images.zip'] # 5G, 282 val images (no labels)
  127. # download(urls, dir=dir)
  128. # Convert labels
  129. convert_labels(dir / 'xView_train.geojson')
  130. # Move images
  131. images = Path(dir / 'images')
  132. images.mkdir(parents=True, exist_ok=True)
  133. Path(dir / 'train_images').rename(dir / 'images' / 'train')
  134. Path(dir / 'val_images').rename(dir / 'images' / 'val')
  135. # Split
  136. autosplit(dir / 'images' / 'train')