Spaces:
Running
Running
Upload 87 files
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- .gitattributes +2 -0
- data/Argoverse.yaml +67 -0
- data/GlobalWheat2020.yaml +54 -0
- data/Objects365.yaml +114 -0
- data/README.dataset.txt +6 -0
- data/README.roboflow.txt +29 -0
- data/SKU-110K.yaml +53 -0
- data/VOC.yaml +81 -0
- data/VisDrone.yaml +61 -0
- data/coco.yaml +45 -0
- data/coco128.yaml +30 -0
- data/data.yaml +13 -0
- data/hyps/hyp.Objects365.yaml +34 -0
- data/hyps/hyp.VOC.yaml +40 -0
- data/hyps/hyp.scratch-high.yaml +34 -0
- data/hyps/hyp.scratch-low.yaml +34 -0
- data/hyps/hyp.scratch-med.yaml +34 -0
- data/images/bus.jpg +3 -0
- data/images/zidane.jpg +3 -0
- data/scripts/download_weights.sh +20 -0
- data/scripts/get_coco.sh +27 -0
- data/scripts/get_coco128.sh +17 -0
- data/xView.yaml +102 -0
- utils/__init__.py +36 -0
- utils/__pycache__/__init__.cpython-310.pyc +0 -0
- utils/__pycache__/__init__.cpython-311.pyc +0 -0
- utils/__pycache__/augmentations.cpython-310.pyc +0 -0
- utils/__pycache__/augmentations.cpython-311.pyc +0 -0
- utils/__pycache__/autoanchor.cpython-310.pyc +0 -0
- utils/__pycache__/autoanchor.cpython-311.pyc +0 -0
- utils/__pycache__/autobatch.cpython-310.pyc +0 -0
- utils/__pycache__/autobatch.cpython-311.pyc +0 -0
- utils/__pycache__/callbacks.cpython-310.pyc +0 -0
- utils/__pycache__/callbacks.cpython-311.pyc +0 -0
- utils/__pycache__/dataloaders.cpython-310.pyc +0 -0
- utils/__pycache__/dataloaders.cpython-311.pyc +0 -0
- utils/__pycache__/downloads.cpython-310.pyc +0 -0
- utils/__pycache__/downloads.cpython-311.pyc +0 -0
- utils/__pycache__/general.cpython-310.pyc +0 -0
- utils/__pycache__/general.cpython-311.pyc +0 -0
- utils/__pycache__/loss.cpython-310.pyc +0 -0
- utils/__pycache__/loss.cpython-311.pyc +0 -0
- utils/__pycache__/metrics.cpython-310.pyc +0 -0
- utils/__pycache__/metrics.cpython-311.pyc +0 -0
- utils/__pycache__/plots.cpython-310.pyc +0 -0
- utils/__pycache__/plots.cpython-311.pyc +0 -0
- utils/__pycache__/torch_utils.cpython-310.pyc +0 -0
- utils/__pycache__/torch_utils.cpython-311.pyc +0 -0
- utils/activations.py +103 -0
- utils/augmentations.py +284 -0
.gitattributes
CHANGED
@@ -33,3 +33,5 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
36 |
+
data/images/bus.jpg filter=lfs diff=lfs merge=lfs -text
|
37 |
+
data/images/zidane.jpg filter=lfs diff=lfs merge=lfs -text
|
data/Argoverse.yaml
ADDED
@@ -0,0 +1,67 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# YOLOv5 🚀 by Ultralytics, GPL-3.0 license
|
2 |
+
# Argoverse-HD dataset (ring-front-center camera) http://www.cs.cmu.edu/~mengtial/proj/streaming/ by Argo AI
|
3 |
+
# Example usage: python train.py --data Argoverse.yaml
|
4 |
+
# parent
|
5 |
+
# ├── yolov5
|
6 |
+
# └── datasets
|
7 |
+
# └── Argoverse ← downloads here (31.3 GB)
|
8 |
+
|
9 |
+
|
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/Argoverse # dataset root dir
|
12 |
+
train: Argoverse-1.1/images/train/ # train images (relative to 'path') 39384 images
|
13 |
+
val: Argoverse-1.1/images/val/ # val images (relative to 'path') 15062 images
|
14 |
+
test: Argoverse-1.1/images/test/ # test images (optional) https://eval.ai/web/challenges/challenge-page/800/overview
|
15 |
+
|
16 |
+
# Classes
|
17 |
+
nc: 8 # number of classes
|
18 |
+
names: ['person', 'bicycle', 'car', 'motorcycle', 'bus', 'truck', 'traffic_light', 'stop_sign'] # class names
|
19 |
+
|
20 |
+
|
21 |
+
# Download script/URL (optional) ---------------------------------------------------------------------------------------
|
22 |
+
download: |
|
23 |
+
import json
|
24 |
+
|
25 |
+
from tqdm import tqdm
|
26 |
+
from utils.general import download, Path
|
27 |
+
|
28 |
+
|
29 |
+
def argoverse2yolo(set):
|
30 |
+
labels = {}
|
31 |
+
a = json.load(open(set, "rb"))
|
32 |
+
for annot in tqdm(a['annotations'], desc=f"Converting {set} to YOLOv5 format..."):
|
33 |
+
img_id = annot['image_id']
|
34 |
+
img_name = a['images'][img_id]['name']
|
35 |
+
img_label_name = f'{img_name[:-3]}txt'
|
36 |
+
|
37 |
+
cls = annot['category_id'] # instance class id
|
38 |
+
x_center, y_center, width, height = annot['bbox']
|
39 |
+
x_center = (x_center + width / 2) / 1920.0 # offset and scale
|
40 |
+
y_center = (y_center + height / 2) / 1200.0 # offset and scale
|
41 |
+
width /= 1920.0 # scale
|
42 |
+
height /= 1200.0 # scale
|
43 |
+
|
44 |
+
img_dir = set.parents[2] / 'Argoverse-1.1' / 'labels' / a['seq_dirs'][a['images'][annot['image_id']]['sid']]
|
45 |
+
if not img_dir.exists():
|
46 |
+
img_dir.mkdir(parents=True, exist_ok=True)
|
47 |
+
|
48 |
+
k = str(img_dir / img_label_name)
|
49 |
+
if k not in labels:
|
50 |
+
labels[k] = []
|
51 |
+
labels[k].append(f"{cls} {x_center} {y_center} {width} {height}\n")
|
52 |
+
|
53 |
+
for k in labels:
|
54 |
+
with open(k, "w") as f:
|
55 |
+
f.writelines(labels[k])
|
56 |
+
|
57 |
+
|
58 |
+
# Download
|
59 |
+
dir = Path('../datasets/Argoverse') # dataset root dir
|
60 |
+
urls = ['https://argoverse-hd.s3.us-east-2.amazonaws.com/Argoverse-HD-Full.zip']
|
61 |
+
download(urls, dir=dir, delete=False)
|
62 |
+
|
63 |
+
# Convert
|
64 |
+
annotations_dir = 'Argoverse-HD/annotations/'
|
65 |
+
(dir / 'Argoverse-1.1' / 'tracking').rename(dir / 'Argoverse-1.1' / 'images') # rename 'tracking' to 'images'
|
66 |
+
for d in "train.json", "val.json":
|
67 |
+
argoverse2yolo(dir / annotations_dir / d) # convert VisDrone annotations to YOLO labels
|
data/GlobalWheat2020.yaml
ADDED
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# YOLOv5 🚀 by Ultralytics, GPL-3.0 license
|
2 |
+
# Global Wheat 2020 dataset http://www.global-wheat.com/ by University of Saskatchewan
|
3 |
+
# Example usage: python train.py --data GlobalWheat2020.yaml
|
4 |
+
# parent
|
5 |
+
# ├── yolov5
|
6 |
+
# └── datasets
|
7 |
+
# └── GlobalWheat2020 ← downloads here (7.0 GB)
|
8 |
+
|
9 |
+
|
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/GlobalWheat2020 # dataset root dir
|
12 |
+
train: # train images (relative to 'path') 3422 images
|
13 |
+
- images/arvalis_1
|
14 |
+
- images/arvalis_2
|
15 |
+
- images/arvalis_3
|
16 |
+
- images/ethz_1
|
17 |
+
- images/rres_1
|
18 |
+
- images/inrae_1
|
19 |
+
- images/usask_1
|
20 |
+
val: # val images (relative to 'path') 748 images (WARNING: train set contains ethz_1)
|
21 |
+
- images/ethz_1
|
22 |
+
test: # test images (optional) 1276 images
|
23 |
+
- images/utokyo_1
|
24 |
+
- images/utokyo_2
|
25 |
+
- images/nau_1
|
26 |
+
- images/uq_1
|
27 |
+
|
28 |
+
# Classes
|
29 |
+
nc: 1 # number of classes
|
30 |
+
names: ['wheat_head'] # class names
|
31 |
+
|
32 |
+
|
33 |
+
# Download script/URL (optional) ---------------------------------------------------------------------------------------
|
34 |
+
download: |
|
35 |
+
from utils.general import download, Path
|
36 |
+
|
37 |
+
|
38 |
+
# Download
|
39 |
+
dir = Path(yaml['path']) # dataset root dir
|
40 |
+
urls = ['https://zenodo.org/record/4298502/files/global-wheat-codalab-official.zip',
|
41 |
+
'https://github.com/ultralytics/yolov5/releases/download/v1.0/GlobalWheat2020_labels.zip']
|
42 |
+
download(urls, dir=dir)
|
43 |
+
|
44 |
+
# Make Directories
|
45 |
+
for p in 'annotations', 'images', 'labels':
|
46 |
+
(dir / p).mkdir(parents=True, exist_ok=True)
|
47 |
+
|
48 |
+
# Move
|
49 |
+
for p in 'arvalis_1', 'arvalis_2', 'arvalis_3', 'ethz_1', 'rres_1', 'inrae_1', 'usask_1', \
|
50 |
+
'utokyo_1', 'utokyo_2', 'nau_1', 'uq_1':
|
51 |
+
(dir / p).rename(dir / 'images' / p) # move to /images
|
52 |
+
f = (dir / p).with_suffix('.json') # json file
|
53 |
+
if f.exists():
|
54 |
+
f.rename((dir / 'annotations' / p).with_suffix('.json')) # move to /annotations
|
data/Objects365.yaml
ADDED
@@ -0,0 +1,114 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# YOLOv5 🚀 by Ultralytics, GPL-3.0 license
|
2 |
+
# Objects365 dataset https://www.objects365.org/ by Megvii
|
3 |
+
# Example usage: python train.py --data Objects365.yaml
|
4 |
+
# parent
|
5 |
+
# ├── yolov5
|
6 |
+
# └── datasets
|
7 |
+
# └── Objects365 ← downloads here (712 GB = 367G data + 345G zips)
|
8 |
+
|
9 |
+
|
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/Objects365 # dataset root dir
|
12 |
+
train: images/train # train images (relative to 'path') 1742289 images
|
13 |
+
val: images/val # val images (relative to 'path') 80000 images
|
14 |
+
test: # test images (optional)
|
15 |
+
|
16 |
+
# Classes
|
17 |
+
nc: 365 # number of classes
|
18 |
+
names: ['Person', 'Sneakers', 'Chair', 'Other Shoes', 'Hat', 'Car', 'Lamp', 'Glasses', 'Bottle', 'Desk', 'Cup',
|
19 |
+
'Street Lights', 'Cabinet/shelf', 'Handbag/Satchel', 'Bracelet', 'Plate', 'Picture/Frame', 'Helmet', 'Book',
|
20 |
+
'Gloves', 'Storage box', 'Boat', 'Leather Shoes', 'Flower', 'Bench', 'Potted Plant', 'Bowl/Basin', 'Flag',
|
21 |
+
'Pillow', 'Boots', 'Vase', 'Microphone', 'Necklace', 'Ring', 'SUV', 'Wine Glass', 'Belt', 'Monitor/TV',
|
22 |
+
'Backpack', 'Umbrella', 'Traffic Light', 'Speaker', 'Watch', 'Tie', 'Trash bin Can', 'Slippers', 'Bicycle',
|
23 |
+
'Stool', 'Barrel/bucket', 'Van', 'Couch', 'Sandals', 'Basket', 'Drum', 'Pen/Pencil', 'Bus', 'Wild Bird',
|
24 |
+
'High Heels', 'Motorcycle', 'Guitar', 'Carpet', 'Cell Phone', 'Bread', 'Camera', 'Canned', 'Truck',
|
25 |
+
'Traffic cone', 'Cymbal', 'Lifesaver', 'Towel', 'Stuffed Toy', 'Candle', 'Sailboat', 'Laptop', 'Awning',
|
26 |
+
'Bed', 'Faucet', 'Tent', 'Horse', 'Mirror', 'Power outlet', 'Sink', 'Apple', 'Air Conditioner', 'Knife',
|
27 |
+
'Hockey Stick', 'Paddle', 'Pickup Truck', 'Fork', 'Traffic Sign', 'Balloon', 'Tripod', 'Dog', 'Spoon', 'Clock',
|
28 |
+
'Pot', 'Cow', 'Cake', 'Dinning Table', 'Sheep', 'Hanger', 'Blackboard/Whiteboard', 'Napkin', 'Other Fish',
|
29 |
+
'Orange/Tangerine', 'Toiletry', 'Keyboard', 'Tomato', 'Lantern', 'Machinery Vehicle', 'Fan',
|
30 |
+
'Green Vegetables', 'Banana', 'Baseball Glove', 'Airplane', 'Mouse', 'Train', 'Pumpkin', 'Soccer', 'Skiboard',
|
31 |
+
'Luggage', 'Nightstand', 'Tea pot', 'Telephone', 'Trolley', 'Head Phone', 'Sports Car', 'Stop Sign',
|
32 |
+
'Dessert', 'Scooter', 'Stroller', 'Crane', 'Remote', 'Refrigerator', 'Oven', 'Lemon', 'Duck', 'Baseball Bat',
|
33 |
+
'Surveillance Camera', 'Cat', 'Jug', 'Broccoli', 'Piano', 'Pizza', 'Elephant', 'Skateboard', 'Surfboard',
|
34 |
+
'Gun', 'Skating and Skiing shoes', 'Gas stove', 'Donut', 'Bow Tie', 'Carrot', 'Toilet', 'Kite', 'Strawberry',
|
35 |
+
'Other Balls', 'Shovel', 'Pepper', 'Computer Box', 'Toilet Paper', 'Cleaning Products', 'Chopsticks',
|
36 |
+
'Microwave', 'Pigeon', 'Baseball', 'Cutting/chopping Board', 'Coffee Table', 'Side Table', 'Scissors',
|
37 |
+
'Marker', 'Pie', 'Ladder', 'Snowboard', 'Cookies', 'Radiator', 'Fire Hydrant', 'Basketball', 'Zebra', 'Grape',
|
38 |
+
'Giraffe', 'Potato', 'Sausage', 'Tricycle', 'Violin', 'Egg', 'Fire Extinguisher', 'Candy', 'Fire Truck',
|
39 |
+
'Billiards', 'Converter', 'Bathtub', 'Wheelchair', 'Golf Club', 'Briefcase', 'Cucumber', 'Cigar/Cigarette',
|
40 |
+
'Paint Brush', 'Pear', 'Heavy Truck', 'Hamburger', 'Extractor', 'Extension Cord', 'Tong', 'Tennis Racket',
|
41 |
+
'Folder', 'American Football', 'earphone', 'Mask', 'Kettle', 'Tennis', 'Ship', 'Swing', 'Coffee Machine',
|
42 |
+
'Slide', 'Carriage', 'Onion', 'Green beans', 'Projector', 'Frisbee', 'Washing Machine/Drying Machine',
|
43 |
+
'Chicken', 'Printer', 'Watermelon', 'Saxophone', 'Tissue', 'Toothbrush', 'Ice cream', 'Hot-air balloon',
|
44 |
+
'Cello', 'French Fries', 'Scale', 'Trophy', 'Cabbage', 'Hot dog', 'Blender', 'Peach', 'Rice', 'Wallet/Purse',
|
45 |
+
'Volleyball', 'Deer', 'Goose', 'Tape', 'Tablet', 'Cosmetics', 'Trumpet', 'Pineapple', 'Golf Ball',
|
46 |
+
'Ambulance', 'Parking meter', 'Mango', 'Key', 'Hurdle', 'Fishing Rod', 'Medal', 'Flute', 'Brush', 'Penguin',
|
47 |
+
'Megaphone', 'Corn', 'Lettuce', 'Garlic', 'Swan', 'Helicopter', 'Green Onion', 'Sandwich', 'Nuts',
|
48 |
+
'Speed Limit Sign', 'Induction Cooker', 'Broom', 'Trombone', 'Plum', 'Rickshaw', 'Goldfish', 'Kiwi fruit',
|
49 |
+
'Router/modem', 'Poker Card', 'Toaster', 'Shrimp', 'Sushi', 'Cheese', 'Notepaper', 'Cherry', 'Pliers', 'CD',
|
50 |
+
'Pasta', 'Hammer', 'Cue', 'Avocado', 'Hamimelon', 'Flask', 'Mushroom', 'Screwdriver', 'Soap', 'Recorder',
|
51 |
+
'Bear', 'Eggplant', 'Board Eraser', 'Coconut', 'Tape Measure/Ruler', 'Pig', 'Showerhead', 'Globe', 'Chips',
|
52 |
+
'Steak', 'Crosswalk Sign', 'Stapler', 'Camel', 'Formula 1', 'Pomegranate', 'Dishwasher', 'Crab',
|
53 |
+
'Hoverboard', 'Meat ball', 'Rice Cooker', 'Tuba', 'Calculator', 'Papaya', 'Antelope', 'Parrot', 'Seal',
|
54 |
+
'Butterfly', 'Dumbbell', 'Donkey', 'Lion', 'Urinal', 'Dolphin', 'Electric Drill', 'Hair Dryer', 'Egg tart',
|
55 |
+
'Jellyfish', 'Treadmill', 'Lighter', 'Grapefruit', 'Game board', 'Mop', 'Radish', 'Baozi', 'Target', 'French',
|
56 |
+
'Spring Rolls', 'Monkey', 'Rabbit', 'Pencil Case', 'Yak', 'Red Cabbage', 'Binoculars', 'Asparagus', 'Barbell',
|
57 |
+
'Scallop', 'Noddles', 'Comb', 'Dumpling', 'Oyster', 'Table Tennis paddle', 'Cosmetics Brush/Eyeliner Pencil',
|
58 |
+
'Chainsaw', 'Eraser', 'Lobster', 'Durian', 'Okra', 'Lipstick', 'Cosmetics Mirror', 'Curling', 'Table Tennis']
|
59 |
+
|
60 |
+
|
61 |
+
# Download script/URL (optional) ---------------------------------------------------------------------------------------
|
62 |
+
download: |
|
63 |
+
from tqdm import tqdm
|
64 |
+
|
65 |
+
from utils.general import Path, check_requirements, download, np, xyxy2xywhn
|
66 |
+
|
67 |
+
check_requirements(('pycocotools>=2.0',))
|
68 |
+
from pycocotools.coco import COCO
|
69 |
+
|
70 |
+
# Make Directories
|
71 |
+
dir = Path(yaml['path']) # dataset root dir
|
72 |
+
for p in 'images', 'labels':
|
73 |
+
(dir / p).mkdir(parents=True, exist_ok=True)
|
74 |
+
for q in 'train', 'val':
|
75 |
+
(dir / p / q).mkdir(parents=True, exist_ok=True)
|
76 |
+
|
77 |
+
# Train, Val Splits
|
78 |
+
for split, patches in [('train', 50 + 1), ('val', 43 + 1)]:
|
79 |
+
print(f"Processing {split} in {patches} patches ...")
|
80 |
+
images, labels = dir / 'images' / split, dir / 'labels' / split
|
81 |
+
|
82 |
+
# Download
|
83 |
+
url = f"https://dorc.ks3-cn-beijing.ksyun.com/data-set/2020Objects365%E6%95%B0%E6%8D%AE%E9%9B%86/{split}/"
|
84 |
+
if split == 'train':
|
85 |
+
download([f'{url}zhiyuan_objv2_{split}.tar.gz'], dir=dir, delete=False) # annotations json
|
86 |
+
download([f'{url}patch{i}.tar.gz' for i in range(patches)], dir=images, curl=True, delete=False, threads=8)
|
87 |
+
elif split == 'val':
|
88 |
+
download([f'{url}zhiyuan_objv2_{split}.json'], dir=dir, delete=False) # annotations json
|
89 |
+
download([f'{url}images/v1/patch{i}.tar.gz' for i in range(15 + 1)], dir=images, curl=True, delete=False, threads=8)
|
90 |
+
download([f'{url}images/v2/patch{i}.tar.gz' for i in range(16, patches)], dir=images, curl=True, delete=False, threads=8)
|
91 |
+
|
92 |
+
# Move
|
93 |
+
for f in tqdm(images.rglob('*.jpg'), desc=f'Moving {split} images'):
|
94 |
+
f.rename(images / f.name) # move to /images/{split}
|
95 |
+
|
96 |
+
# Labels
|
97 |
+
coco = COCO(dir / f'zhiyuan_objv2_{split}.json')
|
98 |
+
names = [x["name"] for x in coco.loadCats(coco.getCatIds())]
|
99 |
+
for cid, cat in enumerate(names):
|
100 |
+
catIds = coco.getCatIds(catNms=[cat])
|
101 |
+
imgIds = coco.getImgIds(catIds=catIds)
|
102 |
+
for im in tqdm(coco.loadImgs(imgIds), desc=f'Class {cid + 1}/{len(names)} {cat}'):
|
103 |
+
width, height = im["width"], im["height"]
|
104 |
+
path = Path(im["file_name"]) # image filename
|
105 |
+
try:
|
106 |
+
with open(labels / path.with_suffix('.txt').name, 'a') as file:
|
107 |
+
annIds = coco.getAnnIds(imgIds=im["id"], catIds=catIds, iscrowd=None)
|
108 |
+
for a in coco.loadAnns(annIds):
|
109 |
+
x, y, w, h = a['bbox'] # bounding box in xywh (xy top-left corner)
|
110 |
+
xyxy = np.array([x, y, x + w, y + h])[None] # pixels(1,4)
|
111 |
+
x, y, w, h = xyxy2xywhn(xyxy, w=width, h=height, clip=True)[0] # normalized and clipped
|
112 |
+
file.write(f"{cid} {x:.5f} {y:.5f} {w:.5f} {h:.5f}\n")
|
113 |
+
except Exception as e:
|
114 |
+
print(e)
|
data/README.dataset.txt
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# My Valorant > 2023-08-16 8:06pm
|
2 |
+
https://universe.roboflow.com/notsam-jqwtl/my-valorant
|
3 |
+
|
4 |
+
Provided by a Roboflow user
|
5 |
+
License: CC BY 4.0
|
6 |
+
|
data/README.roboflow.txt
ADDED
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
My Valorant - v5 2023-08-16 8:06pm
|
3 |
+
==============================
|
4 |
+
|
5 |
+
This dataset was exported via roboflow.com on August 17, 2023 at 12:09 AM GMT
|
6 |
+
|
7 |
+
Roboflow is an end-to-end computer vision platform that helps you
|
8 |
+
* collaborate with your team on computer vision projects
|
9 |
+
* collect & organize images
|
10 |
+
* understand and search unstructured image data
|
11 |
+
* annotate, and create datasets
|
12 |
+
* export, train, and deploy computer vision models
|
13 |
+
* use active learning to improve your dataset over time
|
14 |
+
|
15 |
+
For state of the art Computer Vision training notebooks you can use with this dataset,
|
16 |
+
visit https://github.com/roboflow/notebooks
|
17 |
+
|
18 |
+
To find over 100k other datasets and pre-trained models, visit https://universe.roboflow.com
|
19 |
+
|
20 |
+
The dataset includes 7633 images.
|
21 |
+
Enemies-Friends-Smokes-Spike are annotated in YOLO v5 PyTorch format.
|
22 |
+
|
23 |
+
The following pre-processing was applied to each image:
|
24 |
+
* Auto-orientation of pixel data (with EXIF-orientation stripping)
|
25 |
+
* Resize to 960x540 (Stretch)
|
26 |
+
|
27 |
+
No image augmentation techniques were applied.
|
28 |
+
|
29 |
+
|
data/SKU-110K.yaml
ADDED
@@ -0,0 +1,53 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# YOLOv5 🚀 by Ultralytics, GPL-3.0 license
|
2 |
+
# SKU-110K retail items dataset https://github.com/eg4000/SKU110K_CVPR19 by Trax Retail
|
3 |
+
# Example usage: python train.py --data SKU-110K.yaml
|
4 |
+
# parent
|
5 |
+
# ├── yolov5
|
6 |
+
# └── datasets
|
7 |
+
# └── SKU-110K ← downloads here (13.6 GB)
|
8 |
+
|
9 |
+
|
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/SKU-110K # dataset root dir
|
12 |
+
train: train.txt # train images (relative to 'path') 8219 images
|
13 |
+
val: val.txt # val images (relative to 'path') 588 images
|
14 |
+
test: test.txt # test images (optional) 2936 images
|
15 |
+
|
16 |
+
# Classes
|
17 |
+
nc: 1 # number of classes
|
18 |
+
names: ['object'] # class names
|
19 |
+
|
20 |
+
|
21 |
+
# Download script/URL (optional) ---------------------------------------------------------------------------------------
|
22 |
+
download: |
|
23 |
+
import shutil
|
24 |
+
from tqdm import tqdm
|
25 |
+
from utils.general import np, pd, Path, download, xyxy2xywh
|
26 |
+
|
27 |
+
|
28 |
+
# Download
|
29 |
+
dir = Path(yaml['path']) # dataset root dir
|
30 |
+
parent = Path(dir.parent) # download dir
|
31 |
+
urls = ['http://trax-geometry.s3.amazonaws.com/cvpr_challenge/SKU110K_fixed.tar.gz']
|
32 |
+
download(urls, dir=parent, delete=False)
|
33 |
+
|
34 |
+
# Rename directories
|
35 |
+
if dir.exists():
|
36 |
+
shutil.rmtree(dir)
|
37 |
+
(parent / 'SKU110K_fixed').rename(dir) # rename dir
|
38 |
+
(dir / 'labels').mkdir(parents=True, exist_ok=True) # create labels dir
|
39 |
+
|
40 |
+
# Convert labels
|
41 |
+
names = 'image', 'x1', 'y1', 'x2', 'y2', 'class', 'image_width', 'image_height' # column names
|
42 |
+
for d in 'annotations_train.csv', 'annotations_val.csv', 'annotations_test.csv':
|
43 |
+
x = pd.read_csv(dir / 'annotations' / d, names=names).values # annotations
|
44 |
+
images, unique_images = x[:, 0], np.unique(x[:, 0])
|
45 |
+
with open((dir / d).with_suffix('.txt').__str__().replace('annotations_', ''), 'w') as f:
|
46 |
+
f.writelines(f'./images/{s}\n' for s in unique_images)
|
47 |
+
for im in tqdm(unique_images, desc=f'Converting {dir / d}'):
|
48 |
+
cls = 0 # single-class dataset
|
49 |
+
with open((dir / 'labels' / im).with_suffix('.txt'), 'a') as f:
|
50 |
+
for r in x[images == im]:
|
51 |
+
w, h = r[6], r[7] # image width, height
|
52 |
+
xywh = xyxy2xywh(np.array([[r[1] / w, r[2] / h, r[3] / w, r[4] / h]]))[0] # instance
|
53 |
+
f.write(f"{cls} {xywh[0]:.5f} {xywh[1]:.5f} {xywh[2]:.5f} {xywh[3]:.5f}\n") # write label
|
data/VOC.yaml
ADDED
@@ -0,0 +1,81 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# YOLOv5 🚀 by Ultralytics, GPL-3.0 license
|
2 |
+
# PASCAL VOC dataset http://host.robots.ox.ac.uk/pascal/VOC by University of Oxford
|
3 |
+
# Example usage: python train.py --data VOC.yaml
|
4 |
+
# parent
|
5 |
+
# ├── yolov5
|
6 |
+
# └── datasets
|
7 |
+
# └── VOC ← downloads here (2.8 GB)
|
8 |
+
|
9 |
+
|
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/VOC
|
12 |
+
train: # train images (relative to 'path') 16551 images
|
13 |
+
- images/train2012
|
14 |
+
- images/train2007
|
15 |
+
- images/val2012
|
16 |
+
- images/val2007
|
17 |
+
val: # val images (relative to 'path') 4952 images
|
18 |
+
- images/test2007
|
19 |
+
test: # test images (optional)
|
20 |
+
- images/test2007
|
21 |
+
|
22 |
+
# Classes
|
23 |
+
nc: 20 # number of classes
|
24 |
+
names: ['aeroplane', 'bicycle', 'bird', 'boat', 'bottle', 'bus', 'car', 'cat', 'chair', 'cow', 'diningtable', 'dog',
|
25 |
+
'horse', 'motorbike', 'person', 'pottedplant', 'sheep', 'sofa', 'train', 'tvmonitor'] # class names
|
26 |
+
|
27 |
+
|
28 |
+
# Download script/URL (optional) ---------------------------------------------------------------------------------------
|
29 |
+
download: |
|
30 |
+
import xml.etree.ElementTree as ET
|
31 |
+
|
32 |
+
from tqdm import tqdm
|
33 |
+
from utils.general import download, Path
|
34 |
+
|
35 |
+
|
36 |
+
def convert_label(path, lb_path, year, image_id):
|
37 |
+
def convert_box(size, box):
|
38 |
+
dw, dh = 1. / size[0], 1. / size[1]
|
39 |
+
x, y, w, h = (box[0] + box[1]) / 2.0 - 1, (box[2] + box[3]) / 2.0 - 1, box[1] - box[0], box[3] - box[2]
|
40 |
+
return x * dw, y * dh, w * dw, h * dh
|
41 |
+
|
42 |
+
in_file = open(path / f'VOC{year}/Annotations/{image_id}.xml')
|
43 |
+
out_file = open(lb_path, 'w')
|
44 |
+
tree = ET.parse(in_file)
|
45 |
+
root = tree.getroot()
|
46 |
+
size = root.find('size')
|
47 |
+
w = int(size.find('width').text)
|
48 |
+
h = int(size.find('height').text)
|
49 |
+
|
50 |
+
for obj in root.iter('object'):
|
51 |
+
cls = obj.find('name').text
|
52 |
+
if cls in yaml['names'] and not int(obj.find('difficult').text) == 1:
|
53 |
+
xmlbox = obj.find('bndbox')
|
54 |
+
bb = convert_box((w, h), [float(xmlbox.find(x).text) for x in ('xmin', 'xmax', 'ymin', 'ymax')])
|
55 |
+
cls_id = yaml['names'].index(cls) # class id
|
56 |
+
out_file.write(" ".join([str(a) for a in (cls_id, *bb)]) + '\n')
|
57 |
+
|
58 |
+
|
59 |
+
# Download
|
60 |
+
dir = Path(yaml['path']) # dataset root dir
|
61 |
+
url = 'https://github.com/ultralytics/yolov5/releases/download/v1.0/'
|
62 |
+
urls = [f'{url}VOCtrainval_06-Nov-2007.zip', # 446MB, 5012 images
|
63 |
+
f'{url}VOCtest_06-Nov-2007.zip', # 438MB, 4953 images
|
64 |
+
f'{url}VOCtrainval_11-May-2012.zip'] # 1.95GB, 17126 images
|
65 |
+
download(urls, dir=dir / 'images', delete=False, curl=True, threads=3)
|
66 |
+
|
67 |
+
# Convert
|
68 |
+
path = dir / 'images/VOCdevkit'
|
69 |
+
for year, image_set in ('2012', 'train'), ('2012', 'val'), ('2007', 'train'), ('2007', 'val'), ('2007', 'test'):
|
70 |
+
imgs_path = dir / 'images' / f'{image_set}{year}'
|
71 |
+
lbs_path = dir / 'labels' / f'{image_set}{year}'
|
72 |
+
imgs_path.mkdir(exist_ok=True, parents=True)
|
73 |
+
lbs_path.mkdir(exist_ok=True, parents=True)
|
74 |
+
|
75 |
+
with open(path / f'VOC{year}/ImageSets/Main/{image_set}.txt') as f:
|
76 |
+
image_ids = f.read().strip().split()
|
77 |
+
for id in tqdm(image_ids, desc=f'{image_set}{year}'):
|
78 |
+
f = path / f'VOC{year}/JPEGImages/{id}.jpg' # old img path
|
79 |
+
lb_path = (lbs_path / f.name).with_suffix('.txt') # new label path
|
80 |
+
f.rename(imgs_path / f.name) # move image
|
81 |
+
convert_label(path, lb_path, year, id) # convert labels to YOLO format
|
data/VisDrone.yaml
ADDED
@@ -0,0 +1,61 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# YOLOv5 🚀 by Ultralytics, GPL-3.0 license
|
2 |
+
# VisDrone2019-DET dataset https://github.com/VisDrone/VisDrone-Dataset by Tianjin University
|
3 |
+
# Example usage: python train.py --data VisDrone.yaml
|
4 |
+
# parent
|
5 |
+
# ├── yolov5
|
6 |
+
# └── datasets
|
7 |
+
# └── VisDrone ← downloads here (2.3 GB)
|
8 |
+
|
9 |
+
|
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/VisDrone # dataset root dir
|
12 |
+
train: VisDrone2019-DET-train/images # train images (relative to 'path') 6471 images
|
13 |
+
val: VisDrone2019-DET-val/images # val images (relative to 'path') 548 images
|
14 |
+
test: VisDrone2019-DET-test-dev/images # test images (optional) 1610 images
|
15 |
+
|
16 |
+
# Classes
|
17 |
+
nc: 10 # number of classes
|
18 |
+
names: ['pedestrian', 'people', 'bicycle', 'car', 'van', 'truck', 'tricycle', 'awning-tricycle', 'bus', 'motor']
|
19 |
+
|
20 |
+
|
21 |
+
# Download script/URL (optional) ---------------------------------------------------------------------------------------
|
22 |
+
download: |
|
23 |
+
from utils.general import download, os, Path
|
24 |
+
|
25 |
+
def visdrone2yolo(dir):
|
26 |
+
from PIL import Image
|
27 |
+
from tqdm import tqdm
|
28 |
+
|
29 |
+
def convert_box(size, box):
|
30 |
+
# Convert VisDrone box to YOLO xywh box
|
31 |
+
dw = 1. / size[0]
|
32 |
+
dh = 1. / size[1]
|
33 |
+
return (box[0] + box[2] / 2) * dw, (box[1] + box[3] / 2) * dh, box[2] * dw, box[3] * dh
|
34 |
+
|
35 |
+
(dir / 'labels').mkdir(parents=True, exist_ok=True) # make labels directory
|
36 |
+
pbar = tqdm((dir / 'annotations').glob('*.txt'), desc=f'Converting {dir}')
|
37 |
+
for f in pbar:
|
38 |
+
img_size = Image.open((dir / 'images' / f.name).with_suffix('.jpg')).size
|
39 |
+
lines = []
|
40 |
+
with open(f, 'r') as file: # read annotation.txt
|
41 |
+
for row in [x.split(',') for x in file.read().strip().splitlines()]:
|
42 |
+
if row[4] == '0': # VisDrone 'ignored regions' class 0
|
43 |
+
continue
|
44 |
+
cls = int(row[5]) - 1
|
45 |
+
box = convert_box(img_size, tuple(map(int, row[:4])))
|
46 |
+
lines.append(f"{cls} {' '.join(f'{x:.6f}' for x in box)}\n")
|
47 |
+
with open(str(f).replace(os.sep + 'annotations' + os.sep, os.sep + 'labels' + os.sep), 'w') as fl:
|
48 |
+
fl.writelines(lines) # write label.txt
|
49 |
+
|
50 |
+
|
51 |
+
# Download
|
52 |
+
dir = Path(yaml['path']) # dataset root dir
|
53 |
+
urls = ['https://github.com/ultralytics/yolov5/releases/download/v1.0/VisDrone2019-DET-train.zip',
|
54 |
+
'https://github.com/ultralytics/yolov5/releases/download/v1.0/VisDrone2019-DET-val.zip',
|
55 |
+
'https://github.com/ultralytics/yolov5/releases/download/v1.0/VisDrone2019-DET-test-dev.zip',
|
56 |
+
'https://github.com/ultralytics/yolov5/releases/download/v1.0/VisDrone2019-DET-test-challenge.zip']
|
57 |
+
download(urls, dir=dir, curl=True, threads=4)
|
58 |
+
|
59 |
+
# Convert
|
60 |
+
for d in 'VisDrone2019-DET-train', 'VisDrone2019-DET-val', 'VisDrone2019-DET-test-dev':
|
61 |
+
visdrone2yolo(dir / d) # convert VisDrone annotations to YOLO labels
|
data/coco.yaml
ADDED
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# YOLOv5 🚀 by Ultralytics, GPL-3.0 license
|
2 |
+
# COCO 2017 dataset http://cocodataset.org by Microsoft
|
3 |
+
# Example usage: python train.py --data coco.yaml
|
4 |
+
# parent
|
5 |
+
# ├── yolov5
|
6 |
+
# └── datasets
|
7 |
+
# └── coco ← downloads here (20.1 GB)
|
8 |
+
|
9 |
+
|
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/coco # dataset root dir
|
12 |
+
train: train2017.txt # train images (relative to 'path') 118287 images
|
13 |
+
val: val2017.txt # val images (relative to 'path') 5000 images
|
14 |
+
test: test-dev2017.txt # 20288 of 40670 images, submit to https://competitions.codalab.org/competitions/20794
|
15 |
+
|
16 |
+
# Classes
|
17 |
+
nc: 80 # number of classes
|
18 |
+
names: ['person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus', 'train', 'truck', 'boat', 'traffic light',
|
19 |
+
'fire hydrant', 'stop sign', 'parking meter', 'bench', 'bird', 'cat', 'dog', 'horse', 'sheep', 'cow',
|
20 |
+
'elephant', 'bear', 'zebra', 'giraffe', 'backpack', 'umbrella', 'handbag', 'tie', 'suitcase', 'frisbee',
|
21 |
+
'skis', 'snowboard', 'sports ball', 'kite', 'baseball bat', 'baseball glove', 'skateboard', 'surfboard',
|
22 |
+
'tennis racket', 'bottle', 'wine glass', 'cup', 'fork', 'knife', 'spoon', 'bowl', 'banana', 'apple',
|
23 |
+
'sandwich', 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza', 'donut', 'cake', 'chair', 'couch',
|
24 |
+
'potted plant', 'bed', 'dining table', 'toilet', 'tv', 'laptop', 'mouse', 'remote', 'keyboard', 'cell phone',
|
25 |
+
'microwave', 'oven', 'toaster', 'sink', 'refrigerator', 'book', 'clock', 'vase', 'scissors', 'teddy bear',
|
26 |
+
'hair drier', 'toothbrush'] # class names
|
27 |
+
|
28 |
+
|
29 |
+
# Download script/URL (optional)
|
30 |
+
download: |
|
31 |
+
from utils.general import download, Path
|
32 |
+
|
33 |
+
|
34 |
+
# Download labels
|
35 |
+
segments = False # segment or box labels
|
36 |
+
dir = Path(yaml['path']) # dataset root dir
|
37 |
+
url = 'https://github.com/ultralytics/yolov5/releases/download/v1.0/'
|
38 |
+
urls = [url + ('coco2017labels-segments.zip' if segments else 'coco2017labels.zip')] # labels
|
39 |
+
download(urls, dir=dir.parent)
|
40 |
+
|
41 |
+
# Download data
|
42 |
+
urls = ['http://images.cocodataset.org/zips/train2017.zip', # 19G, 118k images
|
43 |
+
'http://images.cocodataset.org/zips/val2017.zip', # 1G, 5k images
|
44 |
+
'http://images.cocodataset.org/zips/test2017.zip'] # 7G, 41k images (optional)
|
45 |
+
download(urls, dir=dir / 'images', threads=3)
|
data/coco128.yaml
ADDED
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# YOLOv5 🚀 by Ultralytics, GPL-3.0 license
|
2 |
+
# COCO128 dataset https://www.kaggle.com/ultralytics/coco128 (first 128 images from COCO train2017) by Ultralytics
|
3 |
+
# Example usage: python train.py --data coco128.yaml
|
4 |
+
# parent
|
5 |
+
# ├── yolov5
|
6 |
+
# └── datasets
|
7 |
+
# └── coco128 ← downloads here (7 MB)
|
8 |
+
|
9 |
+
|
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/coco128 # dataset root dir
|
12 |
+
train: images/train2017 # train images (relative to 'path') 128 images
|
13 |
+
val: images/train2017 # val images (relative to 'path') 128 images
|
14 |
+
test: # test images (optional)
|
15 |
+
|
16 |
+
# Classes
|
17 |
+
nc: 80 # number of classes
|
18 |
+
names: ['person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus', 'train', 'truck', 'boat', 'traffic light',
|
19 |
+
'fire hydrant', 'stop sign', 'parking meter', 'bench', 'bird', 'cat', 'dog', 'horse', 'sheep', 'cow',
|
20 |
+
'elephant', 'bear', 'zebra', 'giraffe', 'backpack', 'umbrella', 'handbag', 'tie', 'suitcase', 'frisbee',
|
21 |
+
'skis', 'snowboard', 'sports ball', 'kite', 'baseball bat', 'baseball glove', 'skateboard', 'surfboard',
|
22 |
+
'tennis racket', 'bottle', 'wine glass', 'cup', 'fork', 'knife', 'spoon', 'bowl', 'banana', 'apple',
|
23 |
+
'sandwich', 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza', 'donut', 'cake', 'chair', 'couch',
|
24 |
+
'potted plant', 'bed', 'dining table', 'toilet', 'tv', 'laptop', 'mouse', 'remote', 'keyboard', 'cell phone',
|
25 |
+
'microwave', 'oven', 'toaster', 'sink', 'refrigerator', 'book', 'clock', 'vase', 'scissors', 'teddy bear',
|
26 |
+
'hair drier', 'toothbrush'] # class names
|
27 |
+
|
28 |
+
|
29 |
+
# Download script/URL (optional)
|
30 |
+
download: https://ultralytics.com/assets/coco128.zip
|
data/data.yaml
ADDED
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
train: ../train/images
|
2 |
+
val: ../valid/images
|
3 |
+
test: ../test/images
|
4 |
+
|
5 |
+
nc: 1
|
6 |
+
names: ['enemy']
|
7 |
+
|
8 |
+
roboflow:
|
9 |
+
workspace: notsam-jqwtl
|
10 |
+
project: my-valorant
|
11 |
+
version: 5
|
12 |
+
license: CC BY 4.0
|
13 |
+
url: https://universe.roboflow.com/notsam-jqwtl/my-valorant/dataset/5
|
data/hyps/hyp.Objects365.yaml
ADDED
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# YOLOv5 🚀 by Ultralytics, GPL-3.0 license
|
2 |
+
# Hyperparameters for Objects365 training
|
3 |
+
# python train.py --weights yolov5m.pt --data Objects365.yaml --evolve
|
4 |
+
# See Hyperparameter Evolution tutorial for details https://github.com/ultralytics/yolov5#tutorials
|
5 |
+
|
6 |
+
lr0: 0.00258
|
7 |
+
lrf: 0.17
|
8 |
+
momentum: 0.779
|
9 |
+
weight_decay: 0.00058
|
10 |
+
warmup_epochs: 1.33
|
11 |
+
warmup_momentum: 0.86
|
12 |
+
warmup_bias_lr: 0.0711
|
13 |
+
box: 0.0539
|
14 |
+
cls: 0.299
|
15 |
+
cls_pw: 0.825
|
16 |
+
obj: 0.632
|
17 |
+
obj_pw: 1.0
|
18 |
+
iou_t: 0.2
|
19 |
+
anchor_t: 3.44
|
20 |
+
anchors: 3.2
|
21 |
+
fl_gamma: 0.0
|
22 |
+
hsv_h: 0.0188
|
23 |
+
hsv_s: 0.704
|
24 |
+
hsv_v: 0.36
|
25 |
+
degrees: 0.0
|
26 |
+
translate: 0.0902
|
27 |
+
scale: 0.491
|
28 |
+
shear: 0.0
|
29 |
+
perspective: 0.0
|
30 |
+
flipud: 0.0
|
31 |
+
fliplr: 0.5
|
32 |
+
mosaic: 1.0
|
33 |
+
mixup: 0.0
|
34 |
+
copy_paste: 0.0
|
data/hyps/hyp.VOC.yaml
ADDED
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# YOLOv5 🚀 by Ultralytics, GPL-3.0 license
|
2 |
+
# Hyperparameters for VOC training
|
3 |
+
# python train.py --batch 128 --weights yolov5m6.pt --data VOC.yaml --epochs 50 --img 512 --hyp hyp.scratch-med.yaml --evolve
|
4 |
+
# See Hyperparameter Evolution tutorial for details https://github.com/ultralytics/yolov5#tutorials
|
5 |
+
|
6 |
+
# YOLOv5 Hyperparameter Evolution Results
|
7 |
+
# Best generation: 467
|
8 |
+
# Last generation: 996
|
9 |
+
# metrics/precision, metrics/recall, metrics/mAP_0.5, metrics/mAP_0.5:0.95, val/box_loss, val/obj_loss, val/cls_loss
|
10 |
+
# 0.87729, 0.85125, 0.91286, 0.72664, 0.0076739, 0.0042529, 0.0013865
|
11 |
+
|
12 |
+
lr0: 0.00334
|
13 |
+
lrf: 0.15135
|
14 |
+
momentum: 0.74832
|
15 |
+
weight_decay: 0.00025
|
16 |
+
warmup_epochs: 3.3835
|
17 |
+
warmup_momentum: 0.59462
|
18 |
+
warmup_bias_lr: 0.18657
|
19 |
+
box: 0.02
|
20 |
+
cls: 0.21638
|
21 |
+
cls_pw: 0.5
|
22 |
+
obj: 0.51728
|
23 |
+
obj_pw: 0.67198
|
24 |
+
iou_t: 0.2
|
25 |
+
anchor_t: 3.3744
|
26 |
+
fl_gamma: 0.0
|
27 |
+
hsv_h: 0.01041
|
28 |
+
hsv_s: 0.54703
|
29 |
+
hsv_v: 0.27739
|
30 |
+
degrees: 0.0
|
31 |
+
translate: 0.04591
|
32 |
+
scale: 0.75544
|
33 |
+
shear: 0.0
|
34 |
+
perspective: 0.0
|
35 |
+
flipud: 0.0
|
36 |
+
fliplr: 0.5
|
37 |
+
mosaic: 0.85834
|
38 |
+
mixup: 0.04266
|
39 |
+
copy_paste: 0.0
|
40 |
+
anchors: 3.412
|
data/hyps/hyp.scratch-high.yaml
ADDED
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# YOLOv5 🚀 by Ultralytics, GPL-3.0 license
|
2 |
+
# Hyperparameters for high-augmentation COCO training from scratch
|
3 |
+
# python train.py --batch 32 --cfg yolov5m6.yaml --weights '' --data coco.yaml --img 1280 --epochs 300
|
4 |
+
# See tutorials for hyperparameter evolution https://github.com/ultralytics/yolov5#tutorials
|
5 |
+
|
6 |
+
lr0: 0.01 # initial learning rate (SGD=1E-2, Adam=1E-3)
|
7 |
+
lrf: 0.1 # final OneCycleLR learning rate (lr0 * lrf)
|
8 |
+
momentum: 0.937 # SGD momentum/Adam beta1
|
9 |
+
weight_decay: 0.0005 # optimizer weight decay 5e-4
|
10 |
+
warmup_epochs: 3.0 # warmup epochs (fractions ok)
|
11 |
+
warmup_momentum: 0.8 # warmup initial momentum
|
12 |
+
warmup_bias_lr: 0.1 # warmup initial bias lr
|
13 |
+
box: 0.05 # box loss gain
|
14 |
+
cls: 0.3 # cls loss gain
|
15 |
+
cls_pw: 1.0 # cls BCELoss positive_weight
|
16 |
+
obj: 0.7 # obj loss gain (scale with pixels)
|
17 |
+
obj_pw: 1.0 # obj BCELoss positive_weight
|
18 |
+
iou_t: 0.20 # IoU training threshold
|
19 |
+
anchor_t: 4.0 # anchor-multiple threshold
|
20 |
+
# anchors: 3 # anchors per output layer (0 to ignore)
|
21 |
+
fl_gamma: 0.0 # focal loss gamma (efficientDet default gamma=1.5)
|
22 |
+
hsv_h: 0.015 # image HSV-Hue augmentation (fraction)
|
23 |
+
hsv_s: 0.7 # image HSV-Saturation augmentation (fraction)
|
24 |
+
hsv_v: 0.4 # image HSV-Value augmentation (fraction)
|
25 |
+
degrees: 0.0 # image rotation (+/- deg)
|
26 |
+
translate: 0.1 # image translation (+/- fraction)
|
27 |
+
scale: 0.9 # image scale (+/- gain)
|
28 |
+
shear: 0.0 # image shear (+/- deg)
|
29 |
+
perspective: 0.0 # image perspective (+/- fraction), range 0-0.001
|
30 |
+
flipud: 0.0 # image flip up-down (probability)
|
31 |
+
fliplr: 0.5 # image flip left-right (probability)
|
32 |
+
mosaic: 1.0 # image mosaic (probability)
|
33 |
+
mixup: 0.1 # image mixup (probability)
|
34 |
+
copy_paste: 0.1 # segment copy-paste (probability)
|
data/hyps/hyp.scratch-low.yaml
ADDED
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# YOLOv5 🚀 by Ultralytics, GPL-3.0 license
|
2 |
+
# Hyperparameters for low-augmentation COCO training from scratch
|
3 |
+
# python train.py --batch 64 --cfg yolov5n6.yaml --weights '' --data coco.yaml --img 640 --epochs 300 --linear
|
4 |
+
# See tutorials for hyperparameter evolution https://github.com/ultralytics/yolov5#tutorials
|
5 |
+
|
6 |
+
lr0: 0.01 # initial learning rate (SGD=1E-2, Adam=1E-3)
|
7 |
+
lrf: 0.01 # final OneCycleLR learning rate (lr0 * lrf)
|
8 |
+
momentum: 0.937 # SGD momentum/Adam beta1
|
9 |
+
weight_decay: 0.0005 # optimizer weight decay 5e-4
|
10 |
+
warmup_epochs: 3.0 # warmup epochs (fractions ok)
|
11 |
+
warmup_momentum: 0.8 # warmup initial momentum
|
12 |
+
warmup_bias_lr: 0.1 # warmup initial bias lr
|
13 |
+
box: 0.05 # box loss gain
|
14 |
+
cls: 0.5 # cls loss gain
|
15 |
+
cls_pw: 1.0 # cls BCELoss positive_weight
|
16 |
+
obj: 1.0 # obj loss gain (scale with pixels)
|
17 |
+
obj_pw: 1.0 # obj BCELoss positive_weight
|
18 |
+
iou_t: 0.20 # IoU training threshold
|
19 |
+
anchor_t: 4.0 # anchor-multiple threshold
|
20 |
+
# anchors: 3 # anchors per output layer (0 to ignore)
|
21 |
+
fl_gamma: 0.0 # focal loss gamma (efficientDet default gamma=1.5)
|
22 |
+
hsv_h: 0.015 # image HSV-Hue augmentation (fraction)
|
23 |
+
hsv_s: 0.7 # image HSV-Saturation augmentation (fraction)
|
24 |
+
hsv_v: 0.4 # image HSV-Value augmentation (fraction)
|
25 |
+
degrees: 0.0 # image rotation (+/- deg)
|
26 |
+
translate: 0.1 # image translation (+/- fraction)
|
27 |
+
scale: 0.5 # image scale (+/- gain)
|
28 |
+
shear: 0.0 # image shear (+/- deg)
|
29 |
+
perspective: 0.0 # image perspective (+/- fraction), range 0-0.001
|
30 |
+
flipud: 0.0 # image flip up-down (probability)
|
31 |
+
fliplr: 0.5 # image flip left-right (probability)
|
32 |
+
mosaic: 1.0 # image mosaic (probability)
|
33 |
+
mixup: 0.0 # image mixup (probability)
|
34 |
+
copy_paste: 0.0 # segment copy-paste (probability)
|
data/hyps/hyp.scratch-med.yaml
ADDED
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# YOLOv5 🚀 by Ultralytics, GPL-3.0 license
|
2 |
+
# Hyperparameters for medium-augmentation COCO training from scratch
|
3 |
+
# python train.py --batch 32 --cfg yolov5m6.yaml --weights '' --data coco.yaml --img 1280 --epochs 300
|
4 |
+
# See tutorials for hyperparameter evolution https://github.com/ultralytics/yolov5#tutorials
|
5 |
+
|
6 |
+
lr0: 0.01 # initial learning rate (SGD=1E-2, Adam=1E-3)
|
7 |
+
lrf: 0.1 # final OneCycleLR learning rate (lr0 * lrf)
|
8 |
+
momentum: 0.937 # SGD momentum/Adam beta1
|
9 |
+
weight_decay: 0.0005 # optimizer weight decay 5e-4
|
10 |
+
warmup_epochs: 3.0 # warmup epochs (fractions ok)
|
11 |
+
warmup_momentum: 0.8 # warmup initial momentum
|
12 |
+
warmup_bias_lr: 0.1 # warmup initial bias lr
|
13 |
+
box: 0.05 # box loss gain
|
14 |
+
cls: 0.3 # cls loss gain
|
15 |
+
cls_pw: 1.0 # cls BCELoss positive_weight
|
16 |
+
obj: 0.7 # obj loss gain (scale with pixels)
|
17 |
+
obj_pw: 1.0 # obj BCELoss positive_weight
|
18 |
+
iou_t: 0.20 # IoU training threshold
|
19 |
+
anchor_t: 4.0 # anchor-multiple threshold
|
20 |
+
# anchors: 3 # anchors per output layer (0 to ignore)
|
21 |
+
fl_gamma: 0.0 # focal loss gamma (efficientDet default gamma=1.5)
|
22 |
+
hsv_h: 0.015 # image HSV-Hue augmentation (fraction)
|
23 |
+
hsv_s: 0.7 # image HSV-Saturation augmentation (fraction)
|
24 |
+
hsv_v: 0.4 # image HSV-Value augmentation (fraction)
|
25 |
+
degrees: 0.0 # image rotation (+/- deg)
|
26 |
+
translate: 0.1 # image translation (+/- fraction)
|
27 |
+
scale: 0.9 # image scale (+/- gain)
|
28 |
+
shear: 0.0 # image shear (+/- deg)
|
29 |
+
perspective: 0.0 # image perspective (+/- fraction), range 0-0.001
|
30 |
+
flipud: 0.0 # image flip up-down (probability)
|
31 |
+
fliplr: 0.5 # image flip left-right (probability)
|
32 |
+
mosaic: 1.0 # image mosaic (probability)
|
33 |
+
mixup: 0.1 # image mixup (probability)
|
34 |
+
copy_paste: 0.0 # segment copy-paste (probability)
|
data/images/bus.jpg
ADDED
![]() |
Git LFS Details
|
data/images/zidane.jpg
ADDED
![]() |
Git LFS Details
|
data/scripts/download_weights.sh
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/bin/bash
|
2 |
+
# YOLOv5 🚀 by Ultralytics, GPL-3.0 license
|
3 |
+
# Download latest models from https://github.com/ultralytics/yolov5/releases
|
4 |
+
# Example usage: bash path/to/download_weights.sh
|
5 |
+
# parent
|
6 |
+
# └── yolov5
|
7 |
+
# ├── yolov5s.pt ← downloads here
|
8 |
+
# ├── yolov5m.pt
|
9 |
+
# └── ...
|
10 |
+
|
11 |
+
python - <<EOF
|
12 |
+
from utils.downloads import attempt_download
|
13 |
+
|
14 |
+
models = ['n', 's', 'm', 'l', 'x']
|
15 |
+
models.extend([x + '6' for x in models]) # add P6 models
|
16 |
+
|
17 |
+
for x in models:
|
18 |
+
attempt_download(f'yolov5{x}.pt')
|
19 |
+
|
20 |
+
EOF
|
data/scripts/get_coco.sh
ADDED
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/bin/bash
|
2 |
+
# YOLOv5 🚀 by Ultralytics, GPL-3.0 license
|
3 |
+
# Download COCO 2017 dataset http://cocodataset.org
|
4 |
+
# Example usage: bash data/scripts/get_coco.sh
|
5 |
+
# parent
|
6 |
+
# ├── yolov5
|
7 |
+
# └── datasets
|
8 |
+
# └── coco ← downloads here
|
9 |
+
|
10 |
+
# Download/unzip labels
|
11 |
+
d='../datasets' # unzip directory
|
12 |
+
url=https://github.com/ultralytics/yolov5/releases/download/v1.0/
|
13 |
+
f='coco2017labels.zip' # or 'coco2017labels-segments.zip', 68 MB
|
14 |
+
echo 'Downloading' $url$f ' ...'
|
15 |
+
curl -L $url$f -o $f && unzip -q $f -d $d && rm $f &
|
16 |
+
|
17 |
+
# Download/unzip images
|
18 |
+
d='../datasets/coco/images' # unzip directory
|
19 |
+
url=http://images.cocodataset.org/zips/
|
20 |
+
f1='train2017.zip' # 19G, 118k images
|
21 |
+
f2='val2017.zip' # 1G, 5k images
|
22 |
+
f3='test2017.zip' # 7G, 41k images (optional)
|
23 |
+
for f in $f1 $f2; do
|
24 |
+
echo 'Downloading' $url$f '...'
|
25 |
+
curl -L $url$f -o $f && unzip -q $f -d $d && rm $f &
|
26 |
+
done
|
27 |
+
wait # finish background tasks
|
data/scripts/get_coco128.sh
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/bin/bash
|
2 |
+
# YOLOv5 🚀 by Ultralytics, GPL-3.0 license
|
3 |
+
# Download COCO128 dataset https://www.kaggle.com/ultralytics/coco128 (first 128 images from COCO train2017)
|
4 |
+
# Example usage: bash data/scripts/get_coco128.sh
|
5 |
+
# parent
|
6 |
+
# ├── yolov5
|
7 |
+
# └── datasets
|
8 |
+
# └── coco128 ← downloads here
|
9 |
+
|
10 |
+
# Download/unzip images and labels
|
11 |
+
d='../datasets' # unzip directory
|
12 |
+
url=https://github.com/ultralytics/yolov5/releases/download/v1.0/
|
13 |
+
f='coco128.zip' # or 'coco128-segments.zip', 68 MB
|
14 |
+
echo 'Downloading' $url$f ' ...'
|
15 |
+
curl -L $url$f -o $f && unzip -q $f -d $d && rm $f &
|
16 |
+
|
17 |
+
wait # finish background tasks
|
data/xView.yaml
ADDED
@@ -0,0 +1,102 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# YOLOv5 🚀 by Ultralytics, GPL-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: python train.py --data xView.yaml
|
5 |
+
# parent
|
6 |
+
# ├── yolov5
|
7 |
+
# └── datasets
|
8 |
+
# └── xView ← downloads here (20.7 GB)
|
9 |
+
|
10 |
+
|
11 |
+
# 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, ..]
|
12 |
+
path: ../datasets/xView # dataset root dir
|
13 |
+
train: images/autosplit_train.txt # train images (relative to 'path') 90% of 847 train images
|
14 |
+
val: images/autosplit_val.txt # train images (relative to 'path') 10% of 847 train images
|
15 |
+
|
16 |
+
# Classes
|
17 |
+
nc: 60 # number of classes
|
18 |
+
names: ['Fixed-wing Aircraft', 'Small Aircraft', 'Cargo Plane', 'Helicopter', 'Passenger Vehicle', 'Small Car', 'Bus',
|
19 |
+
'Pickup Truck', 'Utility Truck', 'Truck', 'Cargo Truck', 'Truck w/Box', 'Truck Tractor', 'Trailer',
|
20 |
+
'Truck w/Flatbed', 'Truck w/Liquid', 'Crane Truck', 'Railway Vehicle', 'Passenger Car', 'Cargo Car',
|
21 |
+
'Flat Car', 'Tank car', 'Locomotive', 'Maritime Vessel', 'Motorboat', 'Sailboat', 'Tugboat', 'Barge',
|
22 |
+
'Fishing Vessel', 'Ferry', 'Yacht', 'Container Ship', 'Oil Tanker', 'Engineering Vehicle', 'Tower crane',
|
23 |
+
'Container Crane', 'Reach Stacker', 'Straddle Carrier', 'Mobile Crane', 'Dump Truck', 'Haul Truck',
|
24 |
+
'Scraper/Tractor', 'Front loader/Bulldozer', 'Excavator', 'Cement Mixer', 'Ground Grader', 'Hut/Tent', 'Shed',
|
25 |
+
'Building', 'Aircraft Hangar', 'Damaged Building', 'Facility', 'Construction Site', 'Vehicle Lot', 'Helipad',
|
26 |
+
'Storage Tank', 'Shipping container lot', 'Shipping Container', 'Pylon', 'Tower'] # class names
|
27 |
+
|
28 |
+
|
29 |
+
# Download script/URL (optional) ---------------------------------------------------------------------------------------
|
30 |
+
download: |
|
31 |
+
import json
|
32 |
+
import os
|
33 |
+
from pathlib import Path
|
34 |
+
|
35 |
+
import numpy as np
|
36 |
+
from PIL import Image
|
37 |
+
from tqdm import tqdm
|
38 |
+
|
39 |
+
from utils.datasets import autosplit
|
40 |
+
from utils.general import download, xyxy2xywhn
|
41 |
+
|
42 |
+
|
43 |
+
def convert_labels(fname=Path('xView/xView_train.geojson')):
|
44 |
+
# Convert xView geoJSON labels to YOLO format
|
45 |
+
path = fname.parent
|
46 |
+
with open(fname) as f:
|
47 |
+
print(f'Loading {fname}...')
|
48 |
+
data = json.load(f)
|
49 |
+
|
50 |
+
# Make dirs
|
51 |
+
labels = Path(path / 'labels' / 'train')
|
52 |
+
os.system(f'rm -rf {labels}')
|
53 |
+
labels.mkdir(parents=True, exist_ok=True)
|
54 |
+
|
55 |
+
# xView classes 11-94 to 0-59
|
56 |
+
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,
|
57 |
+
12, 13, 14, 15, -1, -1, 16, 17, 18, 19, 20, 21, 22, -1, 23, 24, 25, -1, 26, 27, -1, 28, -1,
|
58 |
+
29, 30, 31, 32, 33, 34, 35, 36, 37, -1, 38, 39, 40, 41, 42, 43, 44, 45, -1, -1, -1, -1, 46,
|
59 |
+
47, 48, 49, -1, 50, 51, -1, 52, -1, -1, -1, 53, 54, -1, 55, -1, -1, 56, -1, 57, -1, 58, 59]
|
60 |
+
|
61 |
+
shapes = {}
|
62 |
+
for feature in tqdm(data['features'], desc=f'Converting {fname}'):
|
63 |
+
p = feature['properties']
|
64 |
+
if p['bounds_imcoords']:
|
65 |
+
id = p['image_id']
|
66 |
+
file = path / 'train_images' / id
|
67 |
+
if file.exists(): # 1395.tif missing
|
68 |
+
try:
|
69 |
+
box = np.array([int(num) for num in p['bounds_imcoords'].split(",")])
|
70 |
+
assert box.shape[0] == 4, f'incorrect box shape {box.shape[0]}'
|
71 |
+
cls = p['type_id']
|
72 |
+
cls = xview_class2index[int(cls)] # xView class to 0-60
|
73 |
+
assert 59 >= cls >= 0, f'incorrect class index {cls}'
|
74 |
+
|
75 |
+
# Write YOLO label
|
76 |
+
if id not in shapes:
|
77 |
+
shapes[id] = Image.open(file).size
|
78 |
+
box = xyxy2xywhn(box[None].astype(np.float), w=shapes[id][0], h=shapes[id][1], clip=True)
|
79 |
+
with open((labels / id).with_suffix('.txt'), 'a') as f:
|
80 |
+
f.write(f"{cls} {' '.join(f'{x:.6f}' for x in box[0])}\n") # write label.txt
|
81 |
+
except Exception as e:
|
82 |
+
print(f'WARNING: skipping one label for {file}: {e}')
|
83 |
+
|
84 |
+
|
85 |
+
# Download manually from https://challenge.xviewdataset.org
|
86 |
+
dir = Path(yaml['path']) # dataset root dir
|
87 |
+
# urls = ['https://d307kc0mrhucc3.cloudfront.net/train_labels.zip', # train labels
|
88 |
+
# 'https://d307kc0mrhucc3.cloudfront.net/train_images.zip', # 15G, 847 train images
|
89 |
+
# 'https://d307kc0mrhucc3.cloudfront.net/val_images.zip'] # 5G, 282 val images (no labels)
|
90 |
+
# download(urls, dir=dir, delete=False)
|
91 |
+
|
92 |
+
# Convert labels
|
93 |
+
convert_labels(dir / 'xView_train.geojson')
|
94 |
+
|
95 |
+
# Move images
|
96 |
+
images = Path(dir / 'images')
|
97 |
+
images.mkdir(parents=True, exist_ok=True)
|
98 |
+
Path(dir / 'train_images').rename(dir / 'images' / 'train')
|
99 |
+
Path(dir / 'val_images').rename(dir / 'images' / 'val')
|
100 |
+
|
101 |
+
# Split
|
102 |
+
autosplit(dir / 'images' / 'train')
|
utils/__init__.py
ADDED
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# YOLOv5 🚀 by Ultralytics, GPL-3.0 license
|
2 |
+
"""
|
3 |
+
utils/initialization
|
4 |
+
"""
|
5 |
+
|
6 |
+
|
7 |
+
def notebook_init(verbose=True):
|
8 |
+
# Check system software and hardware
|
9 |
+
print('Checking setup...')
|
10 |
+
|
11 |
+
import os
|
12 |
+
import shutil
|
13 |
+
|
14 |
+
from utils.general import check_requirements, emojis, is_colab
|
15 |
+
from utils.torch_utils import select_device # imports
|
16 |
+
|
17 |
+
check_requirements(('psutil', 'IPython'))
|
18 |
+
import psutil
|
19 |
+
from IPython import display # to display images and clear console output
|
20 |
+
|
21 |
+
if is_colab():
|
22 |
+
shutil.rmtree('/content/sample_data', ignore_errors=True) # remove colab /sample_data directory
|
23 |
+
|
24 |
+
# System info
|
25 |
+
if verbose:
|
26 |
+
gb = 1 << 30 # bytes to GiB (1024 ** 3)
|
27 |
+
ram = psutil.virtual_memory().total
|
28 |
+
total, used, free = shutil.disk_usage("/")
|
29 |
+
display.clear_output()
|
30 |
+
s = f'({os.cpu_count()} CPUs, {ram / gb:.1f} GB RAM, {(total - free) / gb:.1f}/{total / gb:.1f} GB disk)'
|
31 |
+
else:
|
32 |
+
s = ''
|
33 |
+
|
34 |
+
select_device(newline=False)
|
35 |
+
print(emojis(f'Setup complete ✅ {s}'))
|
36 |
+
return display
|
utils/__pycache__/__init__.cpython-310.pyc
ADDED
Binary file (1.03 kB). View file
|
|
utils/__pycache__/__init__.cpython-311.pyc
ADDED
Binary file (1.71 kB). View file
|
|
utils/__pycache__/augmentations.cpython-310.pyc
ADDED
Binary file (9.13 kB). View file
|
|
utils/__pycache__/augmentations.cpython-311.pyc
ADDED
Binary file (19.5 kB). View file
|
|
utils/__pycache__/autoanchor.cpython-310.pyc
ADDED
Binary file (6.5 kB). View file
|
|
utils/__pycache__/autoanchor.cpython-311.pyc
ADDED
Binary file (13.4 kB). View file
|
|
utils/__pycache__/autobatch.cpython-310.pyc
ADDED
Binary file (2.26 kB). View file
|
|
utils/__pycache__/autobatch.cpython-311.pyc
ADDED
Binary file (4.36 kB). View file
|
|
utils/__pycache__/callbacks.cpython-310.pyc
ADDED
Binary file (2.51 kB). View file
|
|
utils/__pycache__/callbacks.cpython-311.pyc
ADDED
Binary file (3.33 kB). View file
|
|
utils/__pycache__/dataloaders.cpython-310.pyc
ADDED
Binary file (37.6 kB). View file
|
|
utils/__pycache__/dataloaders.cpython-311.pyc
ADDED
Binary file (79.1 kB). View file
|
|
utils/__pycache__/downloads.cpython-310.pyc
ADDED
Binary file (4.96 kB). View file
|
|
utils/__pycache__/downloads.cpython-311.pyc
ADDED
Binary file (9.95 kB). View file
|
|
utils/__pycache__/general.cpython-310.pyc
ADDED
Binary file (35.5 kB). View file
|
|
utils/__pycache__/general.cpython-311.pyc
ADDED
Binary file (71.8 kB). View file
|
|
utils/__pycache__/loss.cpython-310.pyc
ADDED
Binary file (6.25 kB). View file
|
|
utils/__pycache__/loss.cpython-311.pyc
ADDED
Binary file (13.7 kB). View file
|
|
utils/__pycache__/metrics.cpython-310.pyc
ADDED
Binary file (11.4 kB). View file
|
|
utils/__pycache__/metrics.cpython-311.pyc
ADDED
Binary file (23.1 kB). View file
|
|
utils/__pycache__/plots.cpython-310.pyc
ADDED
Binary file (18.5 kB). View file
|
|
utils/__pycache__/plots.cpython-311.pyc
ADDED
Binary file (39.1 kB). View file
|
|
utils/__pycache__/torch_utils.cpython-310.pyc
ADDED
Binary file (13.9 kB). View file
|
|
utils/__pycache__/torch_utils.cpython-311.pyc
ADDED
Binary file (28.4 kB). View file
|
|
utils/activations.py
ADDED
@@ -0,0 +1,103 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# YOLOv5 🚀 by Ultralytics, GPL-3.0 license
|
2 |
+
"""
|
3 |
+
Activation functions
|
4 |
+
"""
|
5 |
+
|
6 |
+
import torch
|
7 |
+
import torch.nn as nn
|
8 |
+
import torch.nn.functional as F
|
9 |
+
|
10 |
+
|
11 |
+
class SiLU(nn.Module):
|
12 |
+
# SiLU activation https://arxiv.org/pdf/1606.08415.pdf
|
13 |
+
@staticmethod
|
14 |
+
def forward(x):
|
15 |
+
return x * torch.sigmoid(x)
|
16 |
+
|
17 |
+
|
18 |
+
class Hardswish(nn.Module):
|
19 |
+
# Hard-SiLU activation
|
20 |
+
@staticmethod
|
21 |
+
def forward(x):
|
22 |
+
# return x * F.hardsigmoid(x) # for TorchScript and CoreML
|
23 |
+
return x * F.hardtanh(x + 3, 0.0, 6.0) / 6.0 # for TorchScript, CoreML and ONNX
|
24 |
+
|
25 |
+
|
26 |
+
class Mish(nn.Module):
|
27 |
+
# Mish activation https://github.com/digantamisra98/Mish
|
28 |
+
@staticmethod
|
29 |
+
def forward(x):
|
30 |
+
return x * F.softplus(x).tanh()
|
31 |
+
|
32 |
+
|
33 |
+
class MemoryEfficientMish(nn.Module):
|
34 |
+
# Mish activation memory-efficient
|
35 |
+
class F(torch.autograd.Function):
|
36 |
+
|
37 |
+
@staticmethod
|
38 |
+
def forward(ctx, x):
|
39 |
+
ctx.save_for_backward(x)
|
40 |
+
return x.mul(torch.tanh(F.softplus(x))) # x * tanh(ln(1 + exp(x)))
|
41 |
+
|
42 |
+
@staticmethod
|
43 |
+
def backward(ctx, grad_output):
|
44 |
+
x = ctx.saved_tensors[0]
|
45 |
+
sx = torch.sigmoid(x)
|
46 |
+
fx = F.softplus(x).tanh()
|
47 |
+
return grad_output * (fx + x * sx * (1 - fx * fx))
|
48 |
+
|
49 |
+
def forward(self, x):
|
50 |
+
return self.F.apply(x)
|
51 |
+
|
52 |
+
|
53 |
+
class FReLU(nn.Module):
|
54 |
+
# FReLU activation https://arxiv.org/abs/2007.11824
|
55 |
+
def __init__(self, c1, k=3): # ch_in, kernel
|
56 |
+
super().__init__()
|
57 |
+
self.conv = nn.Conv2d(c1, c1, k, 1, 1, groups=c1, bias=False)
|
58 |
+
self.bn = nn.BatchNorm2d(c1)
|
59 |
+
|
60 |
+
def forward(self, x):
|
61 |
+
return torch.max(x, self.bn(self.conv(x)))
|
62 |
+
|
63 |
+
|
64 |
+
class AconC(nn.Module):
|
65 |
+
r""" ACON activation (activate or not)
|
66 |
+
AconC: (p1*x-p2*x) * sigmoid(beta*(p1*x-p2*x)) + p2*x, beta is a learnable parameter
|
67 |
+
according to "Activate or Not: Learning Customized Activation" <https://arxiv.org/pdf/2009.04759.pdf>.
|
68 |
+
"""
|
69 |
+
|
70 |
+
def __init__(self, c1):
|
71 |
+
super().__init__()
|
72 |
+
self.p1 = nn.Parameter(torch.randn(1, c1, 1, 1))
|
73 |
+
self.p2 = nn.Parameter(torch.randn(1, c1, 1, 1))
|
74 |
+
self.beta = nn.Parameter(torch.ones(1, c1, 1, 1))
|
75 |
+
|
76 |
+
def forward(self, x):
|
77 |
+
dpx = (self.p1 - self.p2) * x
|
78 |
+
return dpx * torch.sigmoid(self.beta * dpx) + self.p2 * x
|
79 |
+
|
80 |
+
|
81 |
+
class MetaAconC(nn.Module):
|
82 |
+
r""" ACON activation (activate or not)
|
83 |
+
MetaAconC: (p1*x-p2*x) * sigmoid(beta*(p1*x-p2*x)) + p2*x, beta is generated by a small network
|
84 |
+
according to "Activate or Not: Learning Customized Activation" <https://arxiv.org/pdf/2009.04759.pdf>.
|
85 |
+
"""
|
86 |
+
|
87 |
+
def __init__(self, c1, k=1, s=1, r=16): # ch_in, kernel, stride, r
|
88 |
+
super().__init__()
|
89 |
+
c2 = max(r, c1 // r)
|
90 |
+
self.p1 = nn.Parameter(torch.randn(1, c1, 1, 1))
|
91 |
+
self.p2 = nn.Parameter(torch.randn(1, c1, 1, 1))
|
92 |
+
self.fc1 = nn.Conv2d(c1, c2, k, s, bias=True)
|
93 |
+
self.fc2 = nn.Conv2d(c2, c1, k, s, bias=True)
|
94 |
+
# self.bn1 = nn.BatchNorm2d(c2)
|
95 |
+
# self.bn2 = nn.BatchNorm2d(c1)
|
96 |
+
|
97 |
+
def forward(self, x):
|
98 |
+
y = x.mean(dim=2, keepdims=True).mean(dim=3, keepdims=True)
|
99 |
+
# batch-size 1 bug/instabilities https://github.com/ultralytics/yolov5/issues/2891
|
100 |
+
# beta = torch.sigmoid(self.bn2(self.fc2(self.bn1(self.fc1(y))))) # bug/unstable
|
101 |
+
beta = torch.sigmoid(self.fc2(self.fc1(y))) # bug patch BN layers removed
|
102 |
+
dpx = (self.p1 - self.p2) * x
|
103 |
+
return dpx * torch.sigmoid(beta * dpx) + self.p2 * x
|
utils/augmentations.py
ADDED
@@ -0,0 +1,284 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# YOLOv5 🚀 by Ultralytics, GPL-3.0 license
|
2 |
+
"""
|
3 |
+
Image augmentation functions
|
4 |
+
"""
|
5 |
+
|
6 |
+
import math
|
7 |
+
import random
|
8 |
+
|
9 |
+
import cv2
|
10 |
+
import numpy as np
|
11 |
+
|
12 |
+
from utils.general import LOGGER, check_version, colorstr, resample_segments, segment2box
|
13 |
+
from utils.metrics import bbox_ioa
|
14 |
+
|
15 |
+
|
16 |
+
class Albumentations:
|
17 |
+
# YOLOv5 Albumentations class (optional, only used if package is installed)
|
18 |
+
def __init__(self):
|
19 |
+
self.transform = None
|
20 |
+
try:
|
21 |
+
import albumentations as A
|
22 |
+
check_version(A.__version__, '1.0.3', hard=True) # version requirement
|
23 |
+
|
24 |
+
T = [
|
25 |
+
A.Blur(p=0.01),
|
26 |
+
A.MedianBlur(p=0.01),
|
27 |
+
A.ToGray(p=0.01),
|
28 |
+
A.CLAHE(p=0.01),
|
29 |
+
A.RandomBrightnessContrast(p=0.0),
|
30 |
+
A.RandomGamma(p=0.0),
|
31 |
+
A.ImageCompression(quality_lower=75, p=0.0)] # transforms
|
32 |
+
self.transform = A.Compose(T, bbox_params=A.BboxParams(format='yolo', label_fields=['class_labels']))
|
33 |
+
|
34 |
+
LOGGER.info(colorstr('albumentations: ') + ', '.join(f'{x}' for x in self.transform.transforms if x.p))
|
35 |
+
except ImportError: # package not installed, skip
|
36 |
+
pass
|
37 |
+
except Exception as e:
|
38 |
+
LOGGER.info(colorstr('albumentations: ') + f'{e}')
|
39 |
+
|
40 |
+
def __call__(self, im, labels, p=1.0):
|
41 |
+
if self.transform and random.random() < p:
|
42 |
+
new = self.transform(image=im, bboxes=labels[:, 1:], class_labels=labels[:, 0]) # transformed
|
43 |
+
im, labels = new['image'], np.array([[c, *b] for c, b in zip(new['class_labels'], new['bboxes'])])
|
44 |
+
return im, labels
|
45 |
+
|
46 |
+
|
47 |
+
def augment_hsv(im, hgain=0.5, sgain=0.5, vgain=0.5):
|
48 |
+
# HSV color-space augmentation
|
49 |
+
if hgain or sgain or vgain:
|
50 |
+
r = np.random.uniform(-1, 1, 3) * [hgain, sgain, vgain] + 1 # random gains
|
51 |
+
hue, sat, val = cv2.split(cv2.cvtColor(im, cv2.COLOR_BGR2HSV))
|
52 |
+
dtype = im.dtype # uint8
|
53 |
+
|
54 |
+
x = np.arange(0, 256, dtype=r.dtype)
|
55 |
+
lut_hue = ((x * r[0]) % 180).astype(dtype)
|
56 |
+
lut_sat = np.clip(x * r[1], 0, 255).astype(dtype)
|
57 |
+
lut_val = np.clip(x * r[2], 0, 255).astype(dtype)
|
58 |
+
|
59 |
+
im_hsv = cv2.merge((cv2.LUT(hue, lut_hue), cv2.LUT(sat, lut_sat), cv2.LUT(val, lut_val)))
|
60 |
+
cv2.cvtColor(im_hsv, cv2.COLOR_HSV2BGR, dst=im) # no return needed
|
61 |
+
|
62 |
+
|
63 |
+
def hist_equalize(im, clahe=True, bgr=False):
|
64 |
+
# Equalize histogram on BGR image 'im' with im.shape(n,m,3) and range 0-255
|
65 |
+
yuv = cv2.cvtColor(im, cv2.COLOR_BGR2YUV if bgr else cv2.COLOR_RGB2YUV)
|
66 |
+
if clahe:
|
67 |
+
c = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
|
68 |
+
yuv[:, :, 0] = c.apply(yuv[:, :, 0])
|
69 |
+
else:
|
70 |
+
yuv[:, :, 0] = cv2.equalizeHist(yuv[:, :, 0]) # equalize Y channel histogram
|
71 |
+
return cv2.cvtColor(yuv, cv2.COLOR_YUV2BGR if bgr else cv2.COLOR_YUV2RGB) # convert YUV image to RGB
|
72 |
+
|
73 |
+
|
74 |
+
def replicate(im, labels):
|
75 |
+
# Replicate labels
|
76 |
+
h, w = im.shape[:2]
|
77 |
+
boxes = labels[:, 1:].astype(int)
|
78 |
+
x1, y1, x2, y2 = boxes.T
|
79 |
+
s = ((x2 - x1) + (y2 - y1)) / 2 # side length (pixels)
|
80 |
+
for i in s.argsort()[:round(s.size * 0.5)]: # smallest indices
|
81 |
+
x1b, y1b, x2b, y2b = boxes[i]
|
82 |
+
bh, bw = y2b - y1b, x2b - x1b
|
83 |
+
yc, xc = int(random.uniform(0, h - bh)), int(random.uniform(0, w - bw)) # offset x, y
|
84 |
+
x1a, y1a, x2a, y2a = [xc, yc, xc + bw, yc + bh]
|
85 |
+
im[y1a:y2a, x1a:x2a] = im[y1b:y2b, x1b:x2b] # im4[ymin:ymax, xmin:xmax]
|
86 |
+
labels = np.append(labels, [[labels[i, 0], x1a, y1a, x2a, y2a]], axis=0)
|
87 |
+
|
88 |
+
return im, labels
|
89 |
+
|
90 |
+
|
91 |
+
def letterbox(im, new_shape=(640, 640), color=(114, 114, 114), auto=True, scaleFill=False, scaleup=True, stride=32):
|
92 |
+
# Resize and pad image while meeting stride-multiple constraints
|
93 |
+
shape = im.shape[:2] # current shape [height, width]
|
94 |
+
if isinstance(new_shape, int):
|
95 |
+
new_shape = (new_shape, new_shape)
|
96 |
+
|
97 |
+
# Scale ratio (new / old)
|
98 |
+
r = min(new_shape[0] / shape[0], new_shape[1] / shape[1])
|
99 |
+
if not scaleup: # only scale down, do not scale up (for better val mAP)
|
100 |
+
r = min(r, 1.0)
|
101 |
+
|
102 |
+
# Compute padding
|
103 |
+
ratio = r, r # width, height ratios
|
104 |
+
new_unpad = int(round(shape[1] * r)), int(round(shape[0] * r))
|
105 |
+
dw, dh = new_shape[1] - new_unpad[0], new_shape[0] - new_unpad[1] # wh padding
|
106 |
+
if auto: # minimum rectangle
|
107 |
+
dw, dh = np.mod(dw, stride), np.mod(dh, stride) # wh padding
|
108 |
+
elif scaleFill: # stretch
|
109 |
+
dw, dh = 0.0, 0.0
|
110 |
+
new_unpad = (new_shape[1], new_shape[0])
|
111 |
+
ratio = new_shape[1] / shape[1], new_shape[0] / shape[0] # width, height ratios
|
112 |
+
|
113 |
+
dw /= 2 # divide padding into 2 sides
|
114 |
+
dh /= 2
|
115 |
+
|
116 |
+
if shape[::-1] != new_unpad: # resize
|
117 |
+
im = cv2.resize(im, new_unpad, interpolation=cv2.INTER_LINEAR)
|
118 |
+
top, bottom = int(round(dh - 0.1)), int(round(dh + 0.1))
|
119 |
+
left, right = int(round(dw - 0.1)), int(round(dw + 0.1))
|
120 |
+
im = cv2.copyMakeBorder(im, top, bottom, left, right, cv2.BORDER_CONSTANT, value=color) # add border
|
121 |
+
return im, ratio, (dw, dh)
|
122 |
+
|
123 |
+
|
124 |
+
def random_perspective(im,
|
125 |
+
targets=(),
|
126 |
+
segments=(),
|
127 |
+
degrees=10,
|
128 |
+
translate=.1,
|
129 |
+
scale=.1,
|
130 |
+
shear=10,
|
131 |
+
perspective=0.0,
|
132 |
+
border=(0, 0)):
|
133 |
+
# torchvision.transforms.RandomAffine(degrees=(-10, 10), translate=(0.1, 0.1), scale=(0.9, 1.1), shear=(-10, 10))
|
134 |
+
# targets = [cls, xyxy]
|
135 |
+
|
136 |
+
height = im.shape[0] + border[0] * 2 # shape(h,w,c)
|
137 |
+
width = im.shape[1] + border[1] * 2
|
138 |
+
|
139 |
+
# Center
|
140 |
+
C = np.eye(3)
|
141 |
+
C[0, 2] = -im.shape[1] / 2 # x translation (pixels)
|
142 |
+
C[1, 2] = -im.shape[0] / 2 # y translation (pixels)
|
143 |
+
|
144 |
+
# Perspective
|
145 |
+
P = np.eye(3)
|
146 |
+
P[2, 0] = random.uniform(-perspective, perspective) # x perspective (about y)
|
147 |
+
P[2, 1] = random.uniform(-perspective, perspective) # y perspective (about x)
|
148 |
+
|
149 |
+
# Rotation and Scale
|
150 |
+
R = np.eye(3)
|
151 |
+
a = random.uniform(-degrees, degrees)
|
152 |
+
# a += random.choice([-180, -90, 0, 90]) # add 90deg rotations to small rotations
|
153 |
+
s = random.uniform(1 - scale, 1 + scale)
|
154 |
+
# s = 2 ** random.uniform(-scale, scale)
|
155 |
+
R[:2] = cv2.getRotationMatrix2D(angle=a, center=(0, 0), scale=s)
|
156 |
+
|
157 |
+
# Shear
|
158 |
+
S = np.eye(3)
|
159 |
+
S[0, 1] = math.tan(random.uniform(-shear, shear) * math.pi / 180) # x shear (deg)
|
160 |
+
S[1, 0] = math.tan(random.uniform(-shear, shear) * math.pi / 180) # y shear (deg)
|
161 |
+
|
162 |
+
# Translation
|
163 |
+
T = np.eye(3)
|
164 |
+
T[0, 2] = random.uniform(0.5 - translate, 0.5 + translate) * width # x translation (pixels)
|
165 |
+
T[1, 2] = random.uniform(0.5 - translate, 0.5 + translate) * height # y translation (pixels)
|
166 |
+
|
167 |
+
# Combined rotation matrix
|
168 |
+
M = T @ S @ R @ P @ C # order of operations (right to left) is IMPORTANT
|
169 |
+
if (border[0] != 0) or (border[1] != 0) or (M != np.eye(3)).any(): # image changed
|
170 |
+
if perspective:
|
171 |
+
im = cv2.warpPerspective(im, M, dsize=(width, height), borderValue=(114, 114, 114))
|
172 |
+
else: # affine
|
173 |
+
im = cv2.warpAffine(im, M[:2], dsize=(width, height), borderValue=(114, 114, 114))
|
174 |
+
|
175 |
+
# Visualize
|
176 |
+
# import matplotlib.pyplot as plt
|
177 |
+
# ax = plt.subplots(1, 2, figsize=(12, 6))[1].ravel()
|
178 |
+
# ax[0].imshow(im[:, :, ::-1]) # base
|
179 |
+
# ax[1].imshow(im2[:, :, ::-1]) # warped
|
180 |
+
|
181 |
+
# Transform label coordinates
|
182 |
+
n = len(targets)
|
183 |
+
if n:
|
184 |
+
use_segments = any(x.any() for x in segments)
|
185 |
+
new = np.zeros((n, 4))
|
186 |
+
if use_segments: # warp segments
|
187 |
+
segments = resample_segments(segments) # upsample
|
188 |
+
for i, segment in enumerate(segments):
|
189 |
+
xy = np.ones((len(segment), 3))
|
190 |
+
xy[:, :2] = segment
|
191 |
+
xy = xy @ M.T # transform
|
192 |
+
xy = xy[:, :2] / xy[:, 2:3] if perspective else xy[:, :2] # perspective rescale or affine
|
193 |
+
|
194 |
+
# clip
|
195 |
+
new[i] = segment2box(xy, width, height)
|
196 |
+
|
197 |
+
else: # warp boxes
|
198 |
+
xy = np.ones((n * 4, 3))
|
199 |
+
xy[:, :2] = targets[:, [1, 2, 3, 4, 1, 4, 3, 2]].reshape(n * 4, 2) # x1y1, x2y2, x1y2, x2y1
|
200 |
+
xy = xy @ M.T # transform
|
201 |
+
xy = (xy[:, :2] / xy[:, 2:3] if perspective else xy[:, :2]).reshape(n, 8) # perspective rescale or affine
|
202 |
+
|
203 |
+
# create new boxes
|
204 |
+
x = xy[:, [0, 2, 4, 6]]
|
205 |
+
y = xy[:, [1, 3, 5, 7]]
|
206 |
+
new = np.concatenate((x.min(1), y.min(1), x.max(1), y.max(1))).reshape(4, n).T
|
207 |
+
|
208 |
+
# clip
|
209 |
+
new[:, [0, 2]] = new[:, [0, 2]].clip(0, width)
|
210 |
+
new[:, [1, 3]] = new[:, [1, 3]].clip(0, height)
|
211 |
+
|
212 |
+
# filter candidates
|
213 |
+
i = box_candidates(box1=targets[:, 1:5].T * s, box2=new.T, area_thr=0.01 if use_segments else 0.10)
|
214 |
+
targets = targets[i]
|
215 |
+
targets[:, 1:5] = new[i]
|
216 |
+
|
217 |
+
return im, targets
|
218 |
+
|
219 |
+
|
220 |
+
def copy_paste(im, labels, segments, p=0.5):
|
221 |
+
# Implement Copy-Paste augmentation https://arxiv.org/abs/2012.07177, labels as nx5 np.array(cls, xyxy)
|
222 |
+
n = len(segments)
|
223 |
+
if p and n:
|
224 |
+
h, w, c = im.shape # height, width, channels
|
225 |
+
im_new = np.zeros(im.shape, np.uint8)
|
226 |
+
for j in random.sample(range(n), k=round(p * n)):
|
227 |
+
l, s = labels[j], segments[j]
|
228 |
+
box = w - l[3], l[2], w - l[1], l[4]
|
229 |
+
ioa = bbox_ioa(box, labels[:, 1:5]) # intersection over area
|
230 |
+
if (ioa < 0.30).all(): # allow 30% obscuration of existing labels
|
231 |
+
labels = np.concatenate((labels, [[l[0], *box]]), 0)
|
232 |
+
segments.append(np.concatenate((w - s[:, 0:1], s[:, 1:2]), 1))
|
233 |
+
cv2.drawContours(im_new, [segments[j].astype(np.int32)], -1, (255, 255, 255), cv2.FILLED)
|
234 |
+
|
235 |
+
result = cv2.bitwise_and(src1=im, src2=im_new)
|
236 |
+
result = cv2.flip(result, 1) # augment segments (flip left-right)
|
237 |
+
i = result > 0 # pixels to replace
|
238 |
+
# i[:, :] = result.max(2).reshape(h, w, 1) # act over ch
|
239 |
+
im[i] = result[i] # cv2.imwrite('debug.jpg', im) # debug
|
240 |
+
|
241 |
+
return im, labels, segments
|
242 |
+
|
243 |
+
|
244 |
+
def cutout(im, labels, p=0.5):
|
245 |
+
# Applies image cutout augmentation https://arxiv.org/abs/1708.04552
|
246 |
+
if random.random() < p:
|
247 |
+
h, w = im.shape[:2]
|
248 |
+
scales = [0.5] * 1 + [0.25] * 2 + [0.125] * 4 + [0.0625] * 8 + [0.03125] * 16 # image size fraction
|
249 |
+
for s in scales:
|
250 |
+
mask_h = random.randint(1, int(h * s)) # create random masks
|
251 |
+
mask_w = random.randint(1, int(w * s))
|
252 |
+
|
253 |
+
# box
|
254 |
+
xmin = max(0, random.randint(0, w) - mask_w // 2)
|
255 |
+
ymin = max(0, random.randint(0, h) - mask_h // 2)
|
256 |
+
xmax = min(w, xmin + mask_w)
|
257 |
+
ymax = min(h, ymin + mask_h)
|
258 |
+
|
259 |
+
# apply random color mask
|
260 |
+
im[ymin:ymax, xmin:xmax] = [random.randint(64, 191) for _ in range(3)]
|
261 |
+
|
262 |
+
# return unobscured labels
|
263 |
+
if len(labels) and s > 0.03:
|
264 |
+
box = np.array([xmin, ymin, xmax, ymax], dtype=np.float32)
|
265 |
+
ioa = bbox_ioa(box, labels[:, 1:5]) # intersection over area
|
266 |
+
labels = labels[ioa < 0.60] # remove >60% obscured labels
|
267 |
+
|
268 |
+
return labels
|
269 |
+
|
270 |
+
|
271 |
+
def mixup(im, labels, im2, labels2):
|
272 |
+
# Applies MixUp augmentation https://arxiv.org/pdf/1710.09412.pdf
|
273 |
+
r = np.random.beta(32.0, 32.0) # mixup ratio, alpha=beta=32.0
|
274 |
+
im = (im * r + im2 * (1 - r)).astype(np.uint8)
|
275 |
+
labels = np.concatenate((labels, labels2), 0)
|
276 |
+
return im, labels
|
277 |
+
|
278 |
+
|
279 |
+
def box_candidates(box1, box2, wh_thr=2, ar_thr=100, area_thr=0.1, eps=1e-16): # box1(4,n), box2(4,n)
|
280 |
+
# Compute candidate boxes: box1 before augment, box2 after augment, wh_thr (pixels), aspect_ratio_thr, area_ratio
|
281 |
+
w1, h1 = box1[2] - box1[0], box1[3] - box1[1]
|
282 |
+
w2, h2 = box2[2] - box2[0], box2[3] - box2[1]
|
283 |
+
ar = np.maximum(w2 / (h2 + eps), h2 / (w2 + eps)) # aspect ratio
|
284 |
+
return (w2 > wh_thr) & (h2 > wh_thr) & (w2 * h2 / (w1 * h1 + eps) > area_thr) & (ar < ar_thr) # candidates
|