{"cells":[{"metadata":{},"cell_type":"markdown","source":"<a class=\"anchor\" id=\"ToC\"></a>\n# Table of Contents\n1. [Import modules](#import_modules)\n1. [Configure parameters](#configure_parameters)\n1. [Get annotations](#get_annotations)\n1. [Get all model-types](#get_all_model_types)\n1. [Plot some figures](#plot_some_figures)\n1. [Plot all 3D car models](#plot_all_3d_car_models)\n1. [Visualize some images](#visualize_some_images)\n1. [Conclusion](#conclusion)"},{"metadata":{},"cell_type":"markdown","source":"<a class=\"anchor\" id=\"import_modules\"></a>\n# Import modules\n[Back to Table of Contents](#ToC)"},{"metadata":{"trusted":true},"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport cv2\nimport json\nimport os\nimport matplotlib\nimport matplotlib.pyplot as plt\nfrom matplotlib.patches import Polygon\nfrom matplotlib.collections import PatchCollection\nfrom mpl_toolkits.mplot3d import Axes3D","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<a class=\"anchor\" id=\"configure_parameters\"></a>\n# Configure parameters\n[Back to Table of Contents](#ToC)"},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"DATASET_DIR = '/kaggle/input/pku-autonomous-driving/'\nJSON_DIR = os.path.join(DATASET_DIR, 'car_models_json')\nNUM_IMG_SAMPLES = 10 # The number of image samples used for visualization","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<a class=\"anchor\" id=\"get_annotations\"></a>\n# Get annotations\n[Back to Table of Contents](#ToC)"},{"metadata":{"trusted":true},"cell_type":"code","source":"df = pd.read_csv(os.path.join(DATASET_DIR, 'train.csv'))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"image_ids = np.array(df['ImageId'])\nprediction_strings = np.array(df['PredictionString'])\nprediction_strings = [\n    np.array(prediction_string.split(' ')).astype(np.float32).reshape(-1, 7) \\\n    for prediction_string in prediction_strings\n]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"print('Image ID:', image_ids[0])\nprint('Annotations:\\n', prediction_strings[0])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<a class=\"anchor\" id=\"get_all_model_types\"></a>\n# Get all model-types\n[Back to Table of Contents](#ToC)"},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"# https://raw.githubusercontent.com/ApolloScapeAuto/dataset-api/master/car_instance/car_models.py\nmodels = {\n    #           name                id\n         'baojun-310-2017':          0,\n            'biaozhi-3008':          1,\n      'biaozhi-liangxiang':          2,\n       'bieke-yinglang-XT':          3,\n            'biyadi-2x-F0':          4,\n           'changanbenben':          5,\n            'dongfeng-DS5':          6,\n                 'feiyate':          7,\n     'fengtian-liangxiang':          8,\n            'fengtian-MPV':          9,\n       'jilixiongmao-2015':         10,\n       'lingmu-aotuo-2009':         11,\n            'lingmu-swift':         12,\n         'lingmu-SX4-2012':         13,\n          'sikeda-jingrui':         14,\n    'fengtian-weichi-2006':         15,\n               '037-CAR02':         16,\n                 'aodi-a6':         17,\n               'baoma-330':         18,\n               'baoma-530':         19,\n        'baoshijie-paoche':         20,\n         'bentian-fengfan':         21,\n             'biaozhi-408':         22,\n             'biaozhi-508':         23,\n            'bieke-kaiyue':         24,\n                    'fute':         25,\n                 'haima-3':         26,\n           'kaidilake-CTS':         27,\n               'leikesasi':         28,\n           'mazida-6-2015':         29,\n              'MG-GT-2015':         30,\n                   'oubao':         31,\n                    'qiya':         32,\n             'rongwei-750':         33,\n              'supai-2016':         34,\n         'xiandai-suonata':         35,\n        'yiqi-benteng-b50':         36,\n                   'bieke':         37,\n               'biyadi-F3':         38,\n              'biyadi-qin':         39,\n                 'dazhong':         40,\n          'dazhongmaiteng':         41,\n                'dihao-EV':         42,\n  'dongfeng-xuetielong-C6':         43,\n 'dongnan-V3-lingyue-2011':         44,\n'dongfeng-yulong-naruijie':         45,\n                 '019-SUV':         46,\n               '036-CAR01':         47,\n             'aodi-Q7-SUV':         48,\n              'baojun-510':         49,\n                'baoma-X5':         50,\n         'baoshijie-kayan':         51,\n         'beiqi-huansu-H3':         52,\n          'benchi-GLK-300':         53,\n            'benchi-ML500':         54,\n     'fengtian-puladuo-06':         55,\n        'fengtian-SUV-gai':         56,\n'guangqi-chuanqi-GS4-2015':         57,\n    'jianghuai-ruifeng-S3':         58,\n              'jili-boyue':         59,\n                  'jipu-3':         60,\n              'linken-SUV':         61,\n               'lufeng-X8':         62,\n             'qirui-ruihu':         63,\n             'rongwei-RX5':         64,\n         'sanling-oulande':         65,\n              'sikeda-SUV':         66,\n        'Skoda_Fabia-2011':         67,\n        'xiandai-i25-2016':         68,\n        'yingfeinidi-qx80':         69,\n         'yingfeinidi-SUV':         70,\n              'benchi-SUR':         71,\n             'biyadi-tang':         72,\n       'changan-CS35-2012':         73,\n             'changan-cs5':         74,\n      'changcheng-H6-2016':         75,\n             'dazhong-SUV':         76,\n 'dongfeng-fengguang-S560':         77,\n   'dongfeng-fengxing-SX6':         78\n}","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"models_map = dict((y, x) for x, y in models.items())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"cars = []\nfor prediction_string in prediction_strings:\n    for car in prediction_string:\n        cars.append(car)\ncars = np.array(cars)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"unique, counts = np.unique(cars[..., 0].astype(np.uint8), return_counts=True)\nall_model_types = zip(unique, counts)\n\nfor i, model_type in enumerate(all_model_types):\n    print('{}.\\t Model type: {:<22} | {} cars'.format(i, models_map[model_type[0]], model_type[1]))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<a class=\"anchor\" id=\"plot_some_figures\"></a>\n# Plot some figures\n[Back to Table of Contents](#ToC)"},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"def plot_figures(\n    sizes,\n    pie_title,\n    start_angle,\n    bar_title,\n    bar_ylabel,\n    labels,\n    explode,\n    colors=None,\n):\n    fig, ax = plt.subplots(figsize=(14, 14))\n\n    y_pos = np.arange(len(labels))\n    barlist = ax.bar(y_pos, sizes, align='center')\n    ax.set_xticks(y_pos, labels)\n    ax.set_ylabel(bar_ylabel)\n    ax.set_title(bar_title)\n    if colors is not None:\n        for idx, item in enumerate(barlist):\n            item.set_color(colors[idx])\n\n    def autolabel(rects):\n        \"\"\"\n        Attach a text label above each bar displaying its height\n        \"\"\"\n        for rect in rects:\n            height = rect.get_height()\n            ax.text(\n                rect.get_x() + rect.get_width()/2., height,\n                '%d' % int(height),\n                ha='center', va='bottom', fontweight='bold'\n            )\n\n    autolabel(barlist)\n    \n    fig, ax = plt.subplots(figsize=(14, 14))\n    \n    pielist = ax.pie(sizes, explode=explode, labels=labels, autopct='%1.1f%%', shadow=False, startangle=start_angle, counterclock=False)\n    ax.axis('equal')\n    ax.set_title(pie_title)\n    if colors is not None:\n        for idx, item in enumerate(pielist[0]):\n            item.set_color(colors[idx])\n\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"plot_figures(\n    counts,\n    pie_title='The percentage of the number of cars of each model type',\n    start_angle=170,\n    bar_title='Distribution of cars of each model type',\n    bar_ylabel='Frequency',\n    labels=[label for label in unique],\n    explode=np.zeros(len(unique))\n)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<a class=\"anchor\" id=\"plot_all_3d_car_models\"></a>\n# Plot all 3D car models\n### Plotting logic for car models is based on this awesome [kernel](https://www.kaggle.com/ebouteillon/load-a-3d-car-model) created by Eric Bouteillon (@ebouteillon)\n### Also, let's check out [3D Interactive Car with Plotly](https://www.kaggle.com/subinium/3d-interactive-car-with-plotly) created by Subin An (@subinium), the visualization of car models in this kernel is absolutely wonderful!!!\n\n[Back to Table of Contents](#ToC)"},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"# Get all json files\nfiles = [file for file in os.listdir(JSON_DIR) if os.path.isfile(os.path.join(JSON_DIR, file))]\n\n# For each json file, plot figure\nfor file in files:\n    model_path = os.path.join(JSON_DIR, file)\n    with open(model_path) as src:\n        data = json.load(src)\n        car_type = data['car_type']\n        faces = data['faces']\n        vertices = np.array(data['vertices'])\n        triangles = np.array(faces) - 1\n\n        fig = plt.figure(figsize=(16, 5))\n        ax11 = fig.add_subplot(1, 2, 1, projection='3d')\n        ax11.set_title('Model: {} | Type: {}'.format(file.split('.')[0], car_type))\n        ax11.set_xlim([-2, 3])\n        ax11.set_ylim([-3, 2])\n        ax11.set_zlim([0, 3])\n        ax11.view_init(30, -50)\n        ax11.plot_trisurf(vertices[:,0], vertices[:,2], triangles, -vertices[:,1], shade=True, color='lime')\n        \n        ax12 = fig.add_subplot(1, 2, 2, projection='3d')\n        ax12.set_title('Model: {} | Type: {}'.format(file.split('.')[0], car_type))\n        ax12.set_xlim([-2, 3])\n        ax12.set_ylim([-3, 2])\n        ax12.set_zlim([0, 3])\n        ax12.view_init(30, 40)\n        ax12.plot_trisurf(vertices[:,0], vertices[:,2], triangles, -vertices[:,1], shade=True, color='lime')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<a class=\"anchor\" id=\"visualize_some_images\"></a>\n# Visualize some images\n[Back to Table of Contents](#ToC)"},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"def show_samples(samples):\n    for sample in samples:\n        fig, ax = plt.subplots(figsize=(18, 16))\n        \n        # Get image\n        img_path = os.path.join(DATASET_DIR, 'train_images', '{}.{}'.format(sample, 'jpg'))\n        img = cv2.imread(img_path, 1)\n        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n\n        # Get corresponding mask\n        mask_path = os.path.join(DATASET_DIR, 'train_masks', '{}.{}'.format(sample, 'jpg'))\n        mask = cv2.imread(mask_path, 0)\n\n        patches = []\n        contours, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)\n        for contour in contours:\n            poly_patch = Polygon(contour.reshape(-1, 2), closed=True, linewidth=2, edgecolor='r', facecolor='r', fill=True)\n            patches.append(poly_patch)\n        p = PatchCollection(patches, match_original=True, cmap=matplotlib.cm.jet, alpha=0.3)\n\n        ax.imshow(img/255)\n        ax.set_title(sample)\n        ax.add_collection(p)\n        ax.set_xticklabels([])\n        ax.set_yticklabels([])\n        plt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Randomly select samples\nsamples = image_ids[np.random.choice(image_ids.shape[0], NUM_IMG_SAMPLES, replace=False)]\n\n# Show images and corresponding masks of too-far-away (not of interest) cars\nshow_samples(samples)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"markdown","source":"<a class=\"anchor\" id=\"conclusion\"></a>\n# Conclusion\n### I will gradually update this kernel and keep it as simple as possible for everyone can understand the logic behind.\n### If you find this kernel useful to you, please give it an *upvote*, this will motivate me much :3 . Thanks!\n\n[Back to Table of Contents](#ToC)"}],"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat":4,"nbformat_minor":1}