Skip to content

Commit

Permalink
add bdd100k
Browse files Browse the repository at this point in the history
  • Loading branch information
aimuch committed Sep 1, 2020
1 parent 0560738 commit 2ea25d7
Show file tree
Hide file tree
Showing 27 changed files with 2,893 additions and 0 deletions.
29 changes: 29 additions & 0 deletions bdd/BDD100K_official/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
BSD 3-Clause License

Copyright (c) 2018, Berkeley DeepDrive
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

* Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
71 changes: 71 additions & 0 deletions bdd/BDD100K_official/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# BDD100K

![teaser](doc/teaser.jpg)


We construct BDD100K, the largest open driving video dataset with 100K videos and 10 tasks to evaluate the exciting progress of image recognition algorithms on autonomous driving. Each video has 40 seconds and a high resolution. The dataset represents more than 1000 hours of driving experience with more than 100 million frames. The videos comes with GPU/IMU data for trajectory information. The dataset possesses geographic, environmental, and weather diversity, which is useful for training models that are less likely to be surprised by new conditions. The dynamic outdoor scenes and complicated ego-vehicle motion make the perception tasks even more challenging. The tasks on this dataset include image tagging, lane detection, drivable area segmentation, road object detection, semantic segmentation, instance segmentation, multi-object detection tracking, multi-object segmentation tracking, domain adaptation, and imitation learning. This repo is the supporting code for [BDD100K data](https://arxiv.org/abs/1805.04687) and [Scalabel](https://www.scalabel.ai/). The data downloading is available at [BDD100K data website](https://bdd-data.berkeley.edu/). To cite the dataset in your paper,


```
@InProceedings{bdd100k,
author = {Yu, Fisher and Chen, Haofeng and Wang, Xin and Xian, Wenqi and Chen, Yingying and Liu, Fangchen and Madhavan, Vashisht and Darrell, Trevor},
title = {BDD100K: A Diverse Driving Dataset for Heterogeneous Multitask Learning},
booktitle = {The IEEE Conference on Computer Vision and Pattern Recognition (CVPR)},
month = {June},
year = {2020}
}
```


## Dependency

- Python 3
- `pip3 install -r requirements.txt`

## Understanding the Data

After being unzipped, all the files will reside in a folder named `bdd100k`. All the original videos are in `bdd100k/videos` and labels in `bdd100k/labels`. `bdd100k/images` contains the frame at 10th second in the corresponding video.

`bdd100k/labels` contains two json files based on [our label format](doc/format.md) for training and validation sets. [`bdd100k/show_labels.py`](bdd100k/show_labels.py) provides examples to parse and visualize the labels.

For example, you can view training data one by one

```
python3 -m bdd100k.show_labels --image-dir bdd100k/images/100k/train \
-l bdd100k/labels/bdd100k_labels_images_train.json
```

Or export the drivable area in segmentation maps:

```
python3 -m bdd100k.show_labels --image-dir bdd100k/images/100k/train \
-l bdd100k/labels/bdd100k_labels_images_train.json \
-s 1 -o bdd100k/out_drivable_maps/train --drivable
```

This exporting process will take a while, so we also provide `Drivable Maps` in the downloading page, which will be `bdd100k/drivable_maps` after decompressing. There are 3 possible labels on the maps: 0 for background, 1 for direct drivable area and 2 for alternative drivable area.

### Trajectories

To visualize the GPS trajectories provided in `bdd100k/info`, you can run the command below to produce an html file that displays a single trajectory and output the results in folder `out/`:

```
python3 -m bdd100k.show_gps_trajectory \
-i bdd100k/info/train/0000f77c-6257be58.json -o out/ -k {YOUR_API_KEY}
```

Or create html file for each GPS trajectory in a directory, for example:

```
python3 -m bdd100k.show_gps_trajectory \
-i bdd100k/info/train -o out/ -k {YOUR_API_KEY}
```

To create a Google Map API key, please follow the instruction [here](https://developers.google.com/maps/documentation/embed/get-api-key). The generated maps will look like

![gps_trajectory](doc/trajectory_gmap.jpg)


### Semantic Segmentation

At present time, instance segmentation is provided as semantic segmentation maps and polygons in json will be provided in the future. The encoding of labels should still be `train_id` defined in [`bdd100k/label.py`](bdd100k/label.py), thus car should be 13.
Empty file.
112 changes: 112 additions & 0 deletions bdd/BDD100K_official/bdd100k/bdd2coco.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import os
import json
import argparse
from tqdm import tqdm


def parse_arguments():
parser = argparse.ArgumentParser(description='BDD100K to COCO format')
parser.add_argument(
"-l", "--label_dir",
default="/path/to/bdd/label/",
help="root directory of BDD label Json files",
)
parser.add_argument(
"-s", "--save_path",
default="/save/path",
help="path to save coco formatted label file",
)
return parser.parse_args()


def bdd2coco_detection(id_dict, labeled_images, fn):

images = list()
annotations = list()

counter = 0
for i in tqdm(labeled_images):
counter += 1
image = dict()
image['file_name'] = i['name']
image['height'] = 720
image['width'] = 1280

image['id'] = counter

empty_image = True

for label in i['labels']:
annotation = dict()
if label['category'] in id_dict.keys():
empty_image = False
annotation["iscrowd"] = 0
annotation["image_id"] = image['id']
x1 = label['box2d']['x1']
y1 = label['box2d']['y1']
x2 = label['box2d']['x2']
y2 = label['box2d']['y2']
annotation['bbox'] = [x1, y1, x2-x1, y2-y1]
annotation['area'] = float((x2 - x1) * (y2 - y1))
annotation['category_id'] = id_dict[label['category']]
annotation['ignore'] = 0
annotation['id'] = label['id']
annotation['segmentation'] = [[x1, y1, x1, y2, x2, y2, x2, y1]]
annotations.append(annotation)

if empty_image:
continue

images.append(image)

attr_dict["images"] = images
attr_dict["annotations"] = annotations
attr_dict["type"] = "instances"

print('saving...')
json_string = json.dumps(attr_dict)
with open(fn, "w") as file:
file.write(json_string)


if __name__ == '__main__':

args = parse_arguments()

attr_dict = dict()
attr_dict["categories"] = [
{"supercategory": "none", "id": 1, "name": "person"},
{"supercategory": "none", "id": 2, "name": "rider"},
{"supercategory": "none", "id": 3, "name": "car"},
{"supercategory": "none", "id": 4, "name": "bus"},
{"supercategory": "none", "id": 5, "name": "truck"},
{"supercategory": "none", "id": 6, "name": "bike"},
{"supercategory": "none", "id": 7, "name": "motor"},
{"supercategory": "none", "id": 8, "name": "traffic light"},
{"supercategory": "none", "id": 9, "name": "traffic sign"},
{"supercategory": "none", "id": 10, "name": "train"}
]

attr_id_dict = {i['name']: i['id'] for i in attr_dict['categories']}

# create BDD training set detections in COCO format
print('Loading training set...')
with open(os.path.join(args.label_dir,
'bdd100k_labels_images_train.json')) as f:
train_labels = json.load(f)
print('Converting training set...')

out_fn = os.path.join(args.save_path,
'bdd100k_labels_images_det_coco_train.json')
bdd2coco_detection(attr_id_dict, train_labels, out_fn)

print('Loading validation set...')
# create BDD validation set detections in COCO format
with open(os.path.join(args.label_dir,
'bdd100k_labels_images_val.json')) as f:
val_labels = json.load(f)
print('Converting validation set...')

out_fn = os.path.join(args.save_path,
'bdd100k_labels_images_det_coco_val.json')
bdd2coco_detection(attr_id_dict, val_labels, out_fn)
67 changes: 67 additions & 0 deletions bdd/BDD100K_official/bdd100k/coco2bdd.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import json
from pycocotools.coco import COCO
import argparse


def parse_arguments():
# parse the arguments
parser = argparse.ArgumentParser(description='coco to bdd')
parser.add_argument(
"--annFile", "-a",
default="/path/to/coco/label/file",
help="path to coco label file",
)
parser.add_argument(
"--save_path", "-s",
default="/save/path",
help="path to save bdd formatted label file",
)
return parser.parse_args()


def transform(annFile):
# transform to bdd format
coco = COCO(annFile)
imgIds = coco.getImgIds()
imgIds = sorted(imgIds)
catsIds = coco.getCatIds()
cats = coco.loadCats(catsIds)
nms = [cat['name'] for cat in cats]
catsMap = dict(zip(coco.getCatIds(), nms))
bdd_label = []
for imgId in imgIds:
img = coco.loadImgs(imgId)[0]
annIds = coco.getAnnIds(imgIds=img['id'])
anns = coco.loadAnns(annIds)
det_dict = {}
det_dict["name"] = img["file_name"]
det_dict["url"] = img["coco_url"]
det_dict["attributes"] = {"weather": "undefined",
"scene": "undefined",
"timeofday": "undefined"}
det_dict["labels"] = []
for ann in anns:
label = {"id": ann["id"],
"category": catsMap[ann["category_id"]],
"manualShape": True,
"manualAttributes": True,
"box2d": {
"x1": ann["bbox"][0],
"y1": ann["bbox"][1],
"x2": ann["bbox"][0] + ann["bbox"][2] - 1,
"y2": ann["bbox"][1] + ann["bbox"][3] - 1,
}}
det_dict["labels"].append(label)
bdd_label.append(det_dict)
return bdd_label


def main():
args = parse_arguments()
bdd_label = transform(args.annFile)
with open(args.save_path, 'w') as outfile:
json.dump(bdd_label, outfile)


if __name__ == '__main__':
main()
Loading

0 comments on commit 2ea25d7

Please sign in to comment.