xView.yaml 5.0 KB

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