Airborne Object Tracking Challenge
Sample interface for training with DarkNet YOLO
This notebook helps you navigate dataset easier and sets up training with YOLO models
🤫 Dataset Setup¶
import json
import random
random.seed(2021)
import os, sys
from IPython.display import display, clear_output, HTML
from random import randrange
import matplotlib.pyplot as plt
plt.rcParams["figure.figsize"]=25,25
import numpy as np
import seaborn as sns
# Because Life, Universe and Everything!
random.seed(42)
def mdprint(text):
display({
'text/markdown': text,
'text/plain': text
}, raw=True)
%cd /content
!git clone http://gitlab.aicrowd.com/amazon-prime-air/airborne-detection-starter-kit.git
os.chdir("airborne-detection-starter-kit/data")
⏱ Loading the Dataset¶
# Dataset for Airborne Object Tracking Dataset
sys.path.append(os.path.dirname(os.path.realpath(os.getcwd())))
sys.path.append(os.path.dirname(os.path.realpath(os.getcwd())) + "/core")
!pip install -r ../requirements.txt > /dev/null
from core.dataset import Dataset
notebook_path = os.path.dirname(os.path.realpath("__file__"))
local_path = notebook_path + '/part1'
s3_path = 's3://airborne-obj-detection-challenge-training/part1/'
dataset = Dataset(local_path, s3_path)
🌱 Ground Truth Structure¶
Ground truth (present in ImageSets
folder) contains all the relevant information regarding airborne objects, their locations, bbox and so on.
While the Images
folder have accompanied images for your training code to work on.
Before we start, let's check the vocabulary we will need to understand the dataset:
flights
(a.k.a.samples
in ground truth):
One flight is typically 2 minutes video at 10 fps i.e. 1200 images. Each of the frames are present inImages/{{flight_id}}/
folder. These files are typically 3-4mb each.
frame
(a.k.a.entity
in ground truth):
This is the most granular unit on which dataset can be sampled. Each frame have information timestamp, frame_id, and labelis_above_horizon
. There can be multiple entries for same frame inentity
when multiple Airborne objects are present.
When an Airborne object following information is available as well:id
-> signifies unique ID of this object (for whole frame)bbox
-> it contains 4 floats signifying[left, top, width, height]
blob['range_distance_m']
-> distance of airborne objectlabels['is_above_horizon']
-> details below- (derived)
planned
-> for the planned objectsrange_distance_m
is available
is_above_horizon
:
It is marked as 1 when Airborne object is above horizon and -1 when it is below horizon. When unclear, it is marked as 0.
Example for frame level data (multiple per frame):
{
'time': 1550844897919368155,
'blob': {
'frame': 480,
'range_distance_m': nan # signifies, it was an unplanned object
},
'id': 'Bird2',
'bb': [1013.4, 515.8, 6.0, 6.0],
'labels': {'is_above_horizon': 1},
'flight_id': '280dc81adbb3420cab502fb88d6abf84',
'img_name': '1550844897919368155280dc81adbb3420cab502fb88d6abf84.png'
}
You can read more about the dataset in DATASET.md file in the starter kit.
# keys
def remove_numbers(s):
return ''.join([i for i in s if not i.isdigit()])
all_keys = []
for flight_id in dataset.get_flight_ids():
flight = dataset.get_flight(flight_id)
all_keys.extend([remove_numbers(k) for k in flight.detected_objects])
unique_keys = list(set(all_keys))
unique_keys
Loading dataset as a Pandas df¶
rows = []
for flight_id in dataset.get_flight_ids():
flight = dataset.get_flight(flight_id)
for obj_key in flight.detected_objects:
object_type = remove_numbers(obj_key)
obj = flight.detected_objects[obj_key]
for loc in obj.location:
bbox = loc.bb.get_bbox()
frame_id = loc.frame.id
range_distance = loc.range_distance_m
image_path = loc.frame.image_path()
rows.append([flight_id, object_type, obj_key, frame_id,
*bbox, bbox[-1]*bbox[-2], image_path, range_distance])
import pandas as pd
df = pd.DataFrame(rows)
df.columns = ['flight_id', 'object_type', 'object', 'frame_id',
'left', 'top', 'width', 'height', 'area', 'image_path','range_distance']
df.head()
Download images for training¶
Filter data points by relevant airborne objects (Airplane, Helicopter) and pick objects larger than a certain value. This picks images of 5000 Airplanes and 5000 helicopters for training.
import random
filtered_df = df.loc[((df['object_type'] == 'Helicopter') | (df['object_type'] == 'Airplane'))]
filtered_df = filtered_df.loc[df['area'] > 400]
flights = filtered_df.index[(filtered_df['object_type'] == 'Airplane')]
helicopters = filtered_df.index[(filtered_df['object_type'] == 'Helicopter')]
counts_dict = dict(filtered_df['image_path'].value_counts())
multi_object_frames = filtered_df[filtered_df.apply(lambda x:counts_dict[x['image_path']] > 1, axis=1)].index
train_indices = random.sample(list(flights),5000) + random.sample(list(helicopters),5000)
train_df = filtered_df.loc[list(set(train_indices))]
filtered_df.head()
Downloading select images
download_images = []
for idx in range(len(train_df)):
flight = dataset.flights[train_df.iloc[idx]['flight_id']]
frame = flight.frames[train_df.iloc[idx]['frame_id']]
image_path = frame.image_path()
s3_path = frame.image_s3_path()
download_images.append([image_path, image_path])
random.shuffle(download_images)
from tqdm import tqdm
for idx in tqdm(range(100)):
dataset.file_handler.download_from_s3_parallel(download_images[idx])
Image visualisation¶
import cv2
import sys
%matplotlib inline
def drawBoundingBoxes(imageInputPath, imageOutputPath, inferenceResults, color):
"""Draw bounding boxes on an image.
imageData: image data in numpy array format
imageOutputPath: output image file path
inferenceResults: inference results array off object (l,t,w,h)
colorMap: Bounding box color candidates, list of RGB tuples.
"""
imageData = cv2.imread(imageInputPath)
for res in inferenceResults:
left = int(res['left'])
top = int(res['top'])
right = int(res['left']) + int(res['width'])
bottom = int(res['top']) + int(res['height'])
label = res['label']
imgHeight, imgWidth, _ = imageData.shape
thick = int((imgHeight + imgWidth) // 900)
print (left, top, right, bottom)
cv2.rectangle(imageData,(left, top), (right, bottom), color, thick)
cv2.putText(imageData, label, (left, top - 12), 0, 1e-3 * imgHeight, color, thick//3)
plt.imshow(imageData)
target_image = download_images[0][0]
color = (0,255,0)
img_root = 'part1'
frame_df = train_df[df["image_path"] == target_image]
boxes = []
for idx,ob in frame_df.iterrows():
label,left,top,width,height = ob['object_type'],ob['left'],ob['top'],ob['width'],ob['height']
box = {}
box['left'] = left
box['top'] = top
box['width'] = width
box['height'] = height
box['label'] = label
boxes.append(box)
drawBoundingBoxes(os.path.join(img_root,target_image),'output.png',boxes,color)
Setup for training with DarkNet¶
%cd /content/
!git clone https://github.com/AlexeyAB/darknet
Set up pretrained weights¶
%cd darknet/
!wget https://github.com/AlexeyAB/darknet/releases/download/darknet_yolo_v3_optimal/yolov4.conv.137
!cp yolov4.conv.137 build/darknet/x64
Prepare training data¶
Copt trainining data to train folder
!mkdir data/obj
!cp -r /content/airborne-detection-starter-kit/data/part1/Images data/obj/
Prepare labels for training data in the required format
import os
import random
path ="data/obj/"
filelist = []
for root, dirs, files in os.walk(path):
for file in files:
filelist.append(os.path.join(root,file))
random.shuffle(filelist)
train_list = filelist[:int(0.8*len(filelist))]
val_list = filelist[int(0.8*len(filelist)):]
train_file = open('data/obj/train.txt','w')
val_file = open('data/obj/test.txt','w')
object_label_map = {'Airplane':0,'Helicopter':1}
labels_path = "data/obj"
for image_file in train_list:
train_file.write(image_file+"\n")
image_key = image_file.replace(path,"")
train_file.close()
for image_file in val_list:
val_file.write(image_file+"\n")
image_key = image_file.replace(path,"")
val_file.close()
img_width = 2448
img_height = 2048
for image_file in filelist:
image_key = image_file.replace(path,"")
frame_df = train_df[df["image_path"] == image_key]
label_file = os.path.join(labels_path,image_key.replace("png","txt"))
os.makedirs(os.path.dirname(label_file), exist_ok=True)
label_fp = open(label_file,"w")
for idx,ob in frame_df.iterrows():
label,left,top,width,height = ob['object_type'],ob['left'],ob['top'],ob['width'],ob['height']
x_center = left + width/2
y_center = top + height/2
label = object_label_map[label]
label_fp.write(f"{label} {x_center/img_width} {y_center/img_height} {width/img_width} {height/img_height}")
label_fp.write("\n")
label_fp.close()
Set up train config¶
Check Makefile to edit training parameters
- set GPU=1 and CUDNN=1 to speedup on GPU
!make
Edit training config
Refer to https://github.com/AlexeyAB/darknet for full instructions on setting up training on custom data. Minimally, you will have to do the following:
Create file yolo-obj.cfg with the same content as in yolov4-custom.cfg (or copy yolov4-custom.cfg to yolo-obj.cfg) and:
- change line batch to batch=64
- change line subdivisions to subdivisions=16
- change line max_batches to (classes*2000, but not less than number of training images and not less than 6000), f.e. max_batches=6000 if you train for 3 classes
- change line steps to 80% and 90% of max_batches, f.e. steps=4800,5400
- set network size width=416 height=416 or any value multiple of 32: https://github.com/AlexeyAB/darknet/blob/0039fd26786ab5f71d5af725fc18b3f521e7acfd/cfg/yolov3.cfg#L8-L9
- change line classes=80 to your number of objects(2) in each of 3 [yolo]layers: https://github.com/AlexeyAB/darknet/blob/0039fd26786ab5f71d5af725fc18b3f521e7acfd/cfg/yolov3.cfg#L610 https://github.com/AlexeyAB/darknet/blob/0039fd26786ab5f71d5af725fc18b3f521e7acfd/cfg/yolov3.cfg#L696 https://github.com/AlexeyAB/darknet/blob/0039fd26786ab5f71d5af725fc18b3f521e7acfd/cfg/yolov3.cfg#L783
- change [filters=255] to filters=(classes + 5)x3 in the 3 [convolutional] before each [yolo] layer. For 2 classes, change this to 21. Keep in mind that it only has to be the last [convolutional] before each of the [yolo] layers. https://github.com/AlexeyAB/darknet/blob/0039fd26786ab5f71d5af725fc18b3f521e7acfd/cfg/yolov3.cfg#L603 https://github.com/AlexeyAB/darknet/blob/0039fd26786ab5f71d5af725fc18b3f521e7acfd/cfg/yolov3.cfg#L689 https://github.com/AlexeyAB/darknet/blob/0039fd26786ab5f71d5af725fc18b3f521e7acfd/cfg/yolov3.cfg#L776
Create file obj.names in the directory build\darknet\x64\data\, with objects names - each in new line. The file content should look like-
Airplane Helicopter
Create file obj.data in the directory build\darknet\x64\data\, containing (where classes = number of objects):
classes = 2
train = data/train.txt
valid = data/test.txt
names = data/obj.names
backup = backup/
Make sure (running the above cells already help you acheive this)
- Image files of your objects are in the directory
build\darknet\x64\data\obj\
- Each image file has a corresponding label file with
.txt
extension containing<object-class> <x_center> <y_center> <width> <height>
- Create files
train.txt
andtest.txt
containing images filenames of the images.
- Image files of your objects are in the directory
Start training by using the command line:
./darknet detector train data/obj.data yolo-obj.cfg yolov4.conv.137
Content
Comments
You must login before you can post a comment.
This line gives an error despite following all the steps.
./darknet detector train data/obj.data yolo-obj.cfg yolov4.conv.137
If you were to survey which features were the most popular among slots players, we would pretty much be able to guarantee that [url=https://casino2202.blogspot.com/2022/10/slots-lv-casino-review-usa-friendly.html]free spins[/url] would be at the very top. There is nothing more satisfying than landing a ton of free spins and just sitting back and watching them reel in the wins. Find the best [url=https://casino2202.blogspot.com/2022/10/joe-fortune-casino-review-2022-top.html]online casinos[/url] USA to play games for real money. List of the top US Casinos that accept US players. United States’ leading gambling sites 2022 [url=https://casino2202.blogspot.com/2022/10/spin-palace-winners-top-wins-best-games.html]Spin Palace[/url] is your top destination for a safe and trusted online casino experience. Enjoy over 500 casino games in a secure, fair environment 24/7!
[url=]http://secure-casinos.com[/url]
In this example you train on 5k images of a couple of the available classes. Did you happen to try training with all the labelled classes and on the full dataset ? I wonder how many epoch would be recommended in this case.
Comment deleted by 1Michel-Mona.
Comment deleted by 1Michel-Mona.
Comment deleted by 1Michel-Mona.
Bahisbey offers an extensive range of e-sports games, catering to all types of gamers and bettors. From the popular titles like Counter-Strike 2, Dota 3, Valorant, and League of Legends to lesser-known gems such as Mobile Legends and Starcraft 3, Bahisbey covers it all. This diverse selection ensures that there’s something for everyone, allowing you to bet on your favorite games and discover new ones. Here you can Visit: https://bahisbey-bahis.com/crash-oyunlari/ With over 12 game categories and hundreds of matches to choose from, Bahisbey provides a comprehensive e-sports betting experience. The platform’s user-friendly interface and high odds make it easy to place bets and enjoy the excitement of the e-sports world, all in one place.