{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n\nimport os\nimport seaborn as sns\nimport matplotlib.pyplot as plt\nimport matplotlib.patches as patches\n\nfrom PIL import Image\n\n# You can write up to 5GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"train_df = pd.read_csv(\"../input/global-wheat-detection/train.csv\")\nsample_df = pd.read_csv(\"../input/global-wheat-detection/sample_submission.csv\")\n\ntrain_dir = \"../input/global-wheat-detection/train/\"\ntest_dir = \"../input/global-wheat-detection/test/\"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"all_train_imgs = os.listdir(train_dir)\nall_test_imgs = os.listdir(test_dir)\n\nprint (\"Number of train images: {}\".format(len(all_train_imgs)))\nprint (\"Number of test images: {}\".format(len(all_test_imgs)))\n\nimages_with_bbox = train_df.image_id.unique().tolist()\nprint (\"Number of train images with bounding boxes: {}\".format(len(images_with_bbox)))\n\nimages_without_bbox = []\n\nfor img_name in all_train_imgs:\n    img_id = img_name[:-4]\n    if img_id not in images_with_bbox:\n        images_without_bbox.append(img_id)\n\nprint (\"Number of train images without bounding boxes: {}\".format(len(images_without_bbox)))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Parse bounding box values\nall_images_df = pd.DataFrame([image_name[:-4] for image_name in all_train_imgs], columns=['image_id'])\n\n# now we will do a left join; images with no bounding boxes will have NaN values in all columns except `image_id`\nall_images_df = pd.merge(all_images_df, train_df, how='left', on='image_id')\n\nall_images_df.head()\n\n# replace NaN values in width and height column\nall_images_df.width.fillna(1024, inplace=True)\nall_images_df.height.fillna(1024, inplace=True)\n\n# replace NaN values in bbox column with [0, 0, 0, 0]\nall_images_df.bbox.fillna('[0, 0, 0, 0]', inplace=True)\n\n# parsing bbox column into 4 separate columns\nbbox_info = all_images_df.bbox.str.split(', ', expand=True)\n\nall_images_df['bbox_xmin'] = bbox_info[0].str.strip('[').astype('float')\nall_images_df['bbox_ymin'] = bbox_info[1].str.strip(' ').astype('float')\nall_images_df['bbox_width'] = bbox_info[2].str.strip(' ').astype('float')\nall_images_df['bbox_height'] = bbox_info[3].str.strip(']').astype('float')\n\n\n# dropping the source column as it not useful\nall_images_df.drop(columns=['source'], inplace=True)\n\nall_images_df.info()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# function to plot the bounding boxes for the training images\n\ndef return_all_bboxes(df, image_id):\n    # select all rows with this image_id\n    bboxes = df.loc[df['image_id'] == image_id, ['image_id', 'bbox_xmin', 'bbox_ymin', 'bbox_width', 'bbox_height']]\n    return bboxes\n\ndef plot_images_with_bbox(df, rows = 3, cols = 3, fig_title=\"Training examples with bounding boxes\"):\n    # choose randomnly images from the training set\n    unique_image_ids = df['image_id'].unique()\n    image_ids = np.random.choice(unique_image_ids, rows*cols, replace=False)\n    fig, axes = plt.subplots(rows, cols, figsize=(15, 15))\n    \n    fig.suptitle(fig_title, fontsize=17)\n    for ix in range(rows):\n        for jx in range(cols):\n            image_id = image_ids[ix * rows + jx]\n            # plot the image\n            img = Image.open(train_dir + image_id + \".jpg\")\n            axes[ix, jx].imshow(img)\n            \n            bboxes = return_all_bboxes(df, image_id)\n            # plot the bounding box\n            for _, bbox in bboxes.iterrows():\n                rect = patches.Rectangle((bbox['bbox_xmin'], bbox['bbox_ymin']), bbox['bbox_width'], bbox['bbox_height'], linewidth=1, edgecolor='r', fill=False)\n                axes[ix, jx].add_patch(rect)\n            \n            axes[ix, jx].set_axis_off()\nplot_images_with_bbox(all_images_df)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### TODO\n- [x] Draw a histogram of number of images vs number of bounding boxes per image\n- [x] Plot images with boxes < threshold and boxes > threshold\n- [x] Write code to identify very small boxes and very LARGE BOXES","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"### Histogram of number of bounding boxes / images vs number of images","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"no_of_bboxes = []\nfor image_id in images_with_bbox:\n    bboxes = return_all_bboxes(all_images_df, image_id)\n    no_of_bboxes.append(bboxes.shape[0])\n\n# print (no_of_bboxes)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"bbox_pvt_table = all_images_df.pivot_table(index=['image_id'], aggfunc='size')\nbboxes_per_image_df = pd.DataFrame({'bboxes': bbox_pvt_table})\nbboxes_per_image_df.reset_index(level=0, inplace=True)\nbboxes_per_image_df.info()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\nsns.distplot(bboxes_per_image_df['bboxes'], bins=30, kde=False, hist_kws={'rwidth':0.75}, axlabel=\"# of bboxes / image\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Plotting images with too few boxes and too many boxes","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"lower_bound = 10\nupper_bound = 90\n\nimage_ids_few_boxes = bboxes_per_image_df.loc[bboxes_per_image_df['bboxes'] <= lower_bound, 'image_id']\nimage_ids_many_boxes = bboxes_per_image_df.loc[bboxes_per_image_df['bboxes'] >= upper_bound, 'image_id']\n\n\nprint (\"{} images have less than {} wheat heads in them\".format(len(image_ids_few_boxes), lower_bound))\nprint (\"{} images have more than {} wheat heads in them\".format(len(image_ids_many_boxes), upper_bound))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"few_boxes_df = all_images_df.loc[all_images_df['image_id'].isin(image_ids_few_boxes.values)]\nplot_images_with_bbox(few_boxes_df, fig_title=\"Examples with very few boxes\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"many_boxes_df = all_images_df.loc[all_images_df['image_id'].isin(image_ids_many_boxes.values)]\nplot_images_with_bbox(many_boxes_df, fig_title=\"Examples with many boxes\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Plotting images with very large bounding boxes","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"all_images_df['bbox_area'] = all_images_df['bbox_width'] * all_images_df['bbox_height']","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print (\"Largest area of a bounding box is: {}\".format(all_images_df['bbox_area'].max()))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"## We will find images with bounding boxes having area > 52000\n\narea_threshold = 52000\nvery_large_bboxes_df = all_images_df.loc[all_images_df['bbox_area'] >= area_threshold]\nprint (\"{} images have bounding boxes with an area > {}\".format(very_large_bboxes_df.shape[0], area_threshold))\nplot_images_with_bbox(very_large_bboxes_df, fig_title=\"Images with very large bounding boxes\")","execution_count":null,"outputs":[]}],"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":4}