Behavioral Cloning

Here the driving data collected using the driving simulator will be explored and augmented.

Extract Raw Data Archive


In [ ]:
import os
import zipfile

if not (os.path.isdir("data_raw") and os.path.exists("data_raw.csv")):
    zip_ref = zipfile.ZipFile("data_raw.zip", 'r')
    zip_ref.extractall(".")
    zip_ref.close()

Read CSV File for the Recently Extracted Data


In [ ]:
import os
import pandas as pd

data = pd.read_csv("data_raw.csv").to_dict(orient='list')

n_records = len(data['STEERING_ANGLE'])
n_images = n_records * 3  # center, left and right images per record

print("Number of samples:", n_records)
print("Number of images:", n_images)  

# validate that directory number of images in csv file 
# and the number of images in the directory are equal
assert (len(os.listdir("data_raw")) == n_images)

Draw Histogram for Steering Angle for Raw Data


In [ ]:
import matplotlib.pyplot as plt

# visualizations will be shown in the notebook
%matplotlib inline

plt.hist(data['STEERING_ANGLE'], bins=100)
plt.show()

Since the steering was performed using a mouse instead of buttons in the simulator during data collection, there are entries in each bin of the histogram. The results are pretty expected; the most number of the entries is around zero, and there are also many entries in the most left and right angles are of +/- 25 angle degree.

Augment the Data via Images and Steering Measurements Flipping


In [ ]:
import cv2
import os

if os.path.isdir("data_augmented") and os.path.exists("data_augmented.csv"):
    print("data_augmented directory or data_augmented.csv file exists")
else:
    os.mkdir("data_augmented")
    with open("data_augmented.csv", "w") as csv_file:
        csv_file.write("CENTER_IMAGE,LEFT_IMAGE,RIGHT_IMAGE,STEERING_ANGLE,THROTTLE,BRAKE,SPEED\n")
        for i in range(n_records):
            # center image names (old, new)
            center_im_nm = data['CENTER_IMAGE'][i]
            center_im_nm_new = center_im_nm.replace("data_raw", "data_augmented")
            center_im_nm_new_flipped = center_im_nm_new.replace("center", "center_flipped")
            
            # left image names (old,new)
            left_im_nm = data['LEFT_IMAGE'][i]
            left_im_nm_new = left_im_nm.replace("data_raw", "data_augmented")
            left_im_nm_new_flipped = left_im_nm_new.replace("left", "left_flipped")
            
            # right image names (old, new)
            right_im_nm = data['RIGHT_IMAGE'][i]
            right_im_nm_new = right_im_nm.replace("data_raw", "data_augmented")
            right_im_nm_new_flipped = right_im_nm_new.replace("right", "right_flipped")
            
            # steering angle (old, flipped)
            steering_angle = data['STEERING_ANGLE'][i]
            steering_angle_flipped = -1.0 * steering_angle
            
            # create hard links to the original images in new directory 
            os.link(center_im_nm, center_im_nm_new)
            os.link(left_im_nm, left_im_nm_new)
            os.link(right_im_nm, right_im_nm_new)
            
            # write info about old images to new csv file
            csv_file.write("{c_im},{l_im},{r_im},{st_ang},{thr},{br},{sp}\n".format(
                c_im=center_im_nm_new,
                l_im=left_im_nm_new,
                r_im=right_im_nm_new,
                st_ang=data['STEERING_ANGLE'][i],
                thr=data['THROTTLE'][i],
                br=data['BRAKE'][i],
                sp=data['SPEED'][i]))
            
            # flip center image and save
            flipped_center_im = cv2.flip(cv2.imread(center_im_nm), flipCode=1)
            cv2.imwrite(center_im_nm_new_flipped, flipped_center_im)

            # flip left image and save
            flipped_left_im = cv2.flip(cv2.imread(left_im_nm), flipCode=1)
            cv2.imwrite(left_im_nm_new_flipped, flipped_left_im)
            
            # flip right image and save
            flipped_right_im = cv2.flip(cv2.imread(right_im_nm), flipCode=1)
            cv2.imwrite(right_im_nm_new_flipped, flipped_right_im)

            # write info about flipped images to new csv file
            csv_file.write("{c_im},{l_im},{r_im},{st_ang},{thr},{br},{sp}\n".format(
                c_im=center_im_nm_new_flipped,
                l_im=left_im_nm_new_flipped,
                r_im=right_im_nm_new_flipped,
                st_ang=steering_angle_flipped,
                thr=data['THROTTLE'][i],
                br=data['BRAKE'][i],
                sp=data['SPEED'][i]))

Read CSV File for the Augmented Data


In [ ]:
import os
import pandas as pd

data_augmented = pd.read_csv("data_augmented.csv").to_dict(orient='list')

n_records_augmented = len(data_augmented['STEERING_ANGLE'])
n_images_augmented = n_records_augmented * 3  # center, left and right images per record

print("Number of samples:", n_records_augmented)
print("Number of images:", n_images_augmented)  

# validate that directory number of images in csv file 
# and the number of images in the directory are equal
assert (len(os.listdir("data_augmented")) == n_images_augmented)

Draw Histogram for Steering Angle for Augmented Data


In [ ]:
import matplotlib.pyplot as plt

# visualizations will be shown in the notebook
%matplotlib inline

plt.hist(data_augmented['STEERING_ANGLE'], bins=100)
plt.show()

The histogram for the augmented data is symmetric. It is expected and desired state for the data. The augmented data will be used to train neural network predicting steering angle.

Compress Augmented Data


In [ ]:
import os
import zipfile

def zip_dir(path, zip_ref):
    for root, dirs, files in os.walk(path):
        for file in files:
            zip_ref.write(os.path.join(root, file))

if (os.path.isdir("data_augmented") and os.path.exists("data_augmented.csv")):
    zip_ref = zipfile.ZipFile("data_augmented.zip", 'w', zipfile.ZIP_DEFLATED)
    zip_ref.write("data_augmented.csv")
    zip_dir("data_augmented", zip_ref)
    zip_ref.close()