{"cells":[{"metadata":{},"cell_type":"markdown","source":"### This Kernel is a starter EDA for Global Wheat Prediction. It aims to generate insight into Global Wheat Prediction dataset. ","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"## Import the required Libraries","execution_count":null},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport cv2\nimport os\nimport re\nfrom glob import glob\nimport seaborn as sns\nimport matplotlib.pyplot as plt\nimport matplotlib.patches as patches\n\n#plotly\n!pip install chart_studio\nimport plotly.express as px\nimport chart_studio.plotly as py\nimport plotly.graph_objs as go\nimport plotly.express as px\nimport plotly.figure_factory as ff\nfrom plotly.offline import iplot\nimport cufflinks\ncufflinks.go_offline()\ncufflinks.set_config_file(world_readable=True, theme='pearl')\n\n\nfrom PIL import Image\n\nimport albumentations as A\nfrom albumentations.pytorch.transforms import ToTensorV2\n\n\n\nINPUT_PATH = '/kaggle/input/global-wheat-detection'\nTRAIN_DIR = '/kaggle/input/global-wheat-detection/train/'\nTEST_DIR = '/kaggle/input/global-wheat-detection/test/'","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_PATH + '/train.csv')\ntrain_df.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Splitting the bboxes into x, y, w and h\nbboxs = np.stack(train_df['bbox'].apply(lambda x: np.fromstring(x[1:-1], sep=',')))\nfor i, column in enumerate(['x', 'y', 'w', 'h']):\n    train_df[column] = bboxs[:,i]\n\ntrain_df['x1'] = train_df['x'] + train_df['w']\ntrain_df['y1'] = train_df['y'] + train_df['h']\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Glob the directories and get the lists of train and test images\ntrain_dir = glob(INPUT_PATH + '/train/' + '*')\ntest_dir = glob(INPUT_PATH + '/test/'+'*')\n\nprint('Number of Train images :', len(train_dir))\nprint('Number of Test images :', len(test_dir))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print('Number of Training images in the labelled csv file:', len(train_df.groupby('image_id')))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"* Not all the input images in the train directory are part of the train.csv\n* Total count of input images is 3422 where as the labelled dataset has only 3373 image_ids \n* Let's analyze those images not on training directory","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"### Percentage of images from various sources through PieChart","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"src_dtls = train_df.source.value_counts(normalize=True).sort_values()\n\nnew = pd.DataFrame({\n    'source': src_dtls.index,\n    'percentage': src_dtls.values \n})\n\nfig = go.Figure(\n    data=[go.Pie(\n        labels=new['source'],\n        values=new['percentage'])\n    ])\nfig.show()\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Arvalis_1 and rres_1 has more number of bounding boxes than other sources of the images","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"# Create a dataframe with all train images\nall_train_images = pd.DataFrame([i.split('/')[-1][:-4] for i in train_dir])\nall_train_images.columns=['image_id']\n\n\n# Merge all train images with the bounding boxes dataframe\nall_train_images = all_train_images.merge(train_df, on='image_id', how='left')\n\n# replace nan values with zeros\nall_train_images['bbox'] = all_train_images.bbox.fillna('[0,0,0,0]')\n\n# split bbox column\nbbox_items = all_train_images.bbox.str.split(',', expand=True)\nall_train_images['bbox_xmin'] = bbox_items[0].str.strip('[ ').astype(float)\nall_train_images['bbox_ymin'] = bbox_items[1].str.strip(' ').astype(float)\nall_train_images['bbox_width'] = bbox_items[2].str.strip(' ').astype(float)\nall_train_images['bbox_height'] = bbox_items[3].str.strip(' ]').astype(float)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"nobboxes_images = all_train_images[~all_train_images.image_id.isin(train_df.image_id)]\nprint('Number of images with no bounding boxes:', len(nobboxes_images))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"#### Plotting the Histogram plot for Number of bounding boxes per image Ids","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"all_train_images['image_id'].value_counts().iplot(kind='hist',bins=30,color='blue',xTitle='No. of bboxes per Image Id',yTitle='No. of Images')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"#### In order to know the distribution of images from various sources, lets plot the distribution plot for various sources. Distribution plot is combination of histogram plot fitted with Kernel Density Estimate funciton (KDE)[](http://)","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"# Group data together\ninrae_1 = all_train_images.loc[all_train_images['source'] =='inrae_1']['image_id'].value_counts()\narvalis_2 = all_train_images.loc[all_train_images['source'] =='arvalis_2']['image_id'].value_counts()\nusask_1 = all_train_images.loc[all_train_images['source'] =='usask_1']['image_id'].value_counts()\narvalis_3 = all_train_images.loc[all_train_images['source'] =='arvalis_3']['image_id'].value_counts()\nrres_1 = all_train_images.loc[all_train_images['source'] =='rres_1']['image_id'].value_counts()\nethz_1 = all_train_images.loc[all_train_images['source'] =='ethz_1']['image_id'].value_counts()\n\nhist_data = [inrae_1, arvalis_2, usask_1, arvalis_3, rres_1, ethz_1]\n\nlabels = src_dtls.index\n\nplt.figure(figsize=(12,8))\n\nsns.distplot(inrae_1)\nsns.distplot(arvalis_2)\nsns.distplot(usask_1)\nsns.distplot(arvalis_3)\nsns.distplot(rres_1)\nsns.distplot(ethz_1)\nplt.figlegend(labels, loc='upper right')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Common Utility function to plot various samples of input images.","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"def get_all_bboxes(df, image_id):\n    image_bboxes = df[df.image_id == image_id]\n    \n    bboxes = []\n    for _,row in image_bboxes.iterrows():\n        bboxes.append((row.bbox_xmin, row.bbox_ymin, row.bbox_width, row.bbox_height))\n        \n    return bboxes\n\ndef plot_image_examples(df, rows=3, cols=3, title='Image examples'):\n    fig, axs = plt.subplots(rows, cols, figsize=(10,10))\n    for row in range(rows):\n        for col in range(cols):\n            idx = np.random.randint(len(df), size=1)[0]\n            img_id = df.iloc[idx].image_id\n            \n            img = Image.open(TRAIN_DIR + img_id + '.jpg')\n            axs[row, col].imshow(img)\n            \n            bboxes = get_all_bboxes(df, img_id)\n            \n            for bbox in bboxes:\n                rect = patches.Rectangle((bbox[0],bbox[1]),bbox[2],bbox[3],linewidth=1,edgecolor='r',facecolor='none')\n                axs[row, col].add_patch(rect)\n            \n            axs[row, col].axis('off')\n            \n    plt.suptitle(title)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Images with No Bounding Boxes ","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"plot_image_examples(all_train_images[all_train_images.image_id.isin(nobboxes_images.image_id)], title='Images with no bounding boxes')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plot_image_examples(all_train_images.loc[all_train_images['source'] =='inrae_1'], title='Random samples for source INRAE_1')\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plot_image_examples(all_train_images.loc[all_train_images['source'] =='arvalis_2'], title='Random samples for source arvalis_2')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plot_image_examples(all_train_images.loc[all_train_images['source'] =='usask_1'], title='Random samples for source usask_1')\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plot_image_examples(all_train_images.loc[all_train_images['source'] =='ethz_1'], title='Random samples for source ethz_1')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Test Image Samples to be predicted ","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"images = test_dir\n\n# Extract 9 random images from it\nrandom_images = [np.random.choice(images) for i in range(9)]\n\nprint('Display Test Images')\n\n# Adjust the size of your images\nplt.figure(figsize=(10,8))\n\n# Iterate and plot random images\nfor i in range(9):\n    plt.subplot(3, 3, i + 1)\n    img = plt.imread(os.path.join(TEST_DIR, random_images[i]))\n    plt.imshow(img, cmap='gray')\n    plt.axis('off')\n    \n# Adjust subplot parameters to give specified padding\nplt.tight_layout()   ","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Data Visualization with albumentations for Wheat detection","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"# Select a randome image for albumentation \n\nidx = np.random.randint(len(all_train_images), size=1)[0]\nimg_id = all_train_images.iloc[idx].image_id \n\nimg= cv2.imread(os.path.join(TRAIN_DIR, img_id + '.jpg'))[:,:,::-1]\nplt.imshow(img)\n\nbboxes = get_all_bboxes(all_train_images, img_id)\n# All the bboxes are labelled to default 1 value as these belongs to single class\nlabels = np.ones((len(bboxes),))\n# Original Annotations to apply Albumentations\norig_annotations = {'image': img, 'bboxes': bboxes, 'category_id': labels}","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Plots the images as per the annotations format and applied augmentations\ndef plot_image_list(annotations_list, subtitle_list, cols=2, title='Image Examples'):\n    fig, axs = plt.subplots(nrows=1, ncols=cols, figsize=(16,12), squeeze=False)\n    for i, (annotations, title) in enumerate(zip(annotations_list, subtitle_list)):\n        axs[i // cols][i % cols].imshow(annotations['image'])\n        axs[i // cols][i % cols].set_title(title, fontsize=14)\n        for bbox in annotations['bboxes']:\n            rect = patches.Rectangle((bbox[0],bbox[1]),bbox[2],bbox[3],linewidth=1,edgecolor='r',facecolor='none')\n            axs[i // cols][i % cols].add_patch(rect) \n    fig.suptitle(title, fontsize=18)\n    plt.tight_layout()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Funtion to get the Albumentations\ndef get_aug(aug, min_area=0., min_visibility=0.):\n    return A.Compose(aug, bbox_params=A.BboxParams(format='coco', min_area=min_area, \n                                               min_visibility=min_visibility, label_fields=['category_id']))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Applying Vertical Flip on the Original Image\naug = get_aug([A.VerticalFlip(p=1)])\nverticalFlip = aug(**orig_annotations)\nannotations_list=[orig_annotations, verticalFlip]\nsubtitle_list=['Original Image', 'Vertically Flipped Image']\nplot_image_list(annotations_list, subtitle_list, title='Vertical Flip' )","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Applying Horizontal Flip on the Original Image\naug = get_aug([A.HorizontalFlip(p=1)])\nhorizontalFlip = aug(**orig_annotations)\nannotations_list=[orig_annotations, horizontalFlip]\nsubtitle_list=['Original Image', 'Horizontally Flipped Image']\nplot_image_list(annotations_list, subtitle_list, title='Horizontal Flip' )","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Applying Center Cropping the Original Image\naug = get_aug([A.CenterCrop(p=1, height=512, width=512)])\nCropped = aug(**orig_annotations)\nannotations_list=[orig_annotations, Cropped]\nsubtitle_list=['Original Image', 'Centre Cropped Image']\nplot_image_list(annotations_list, subtitle_list, title='Image Cropping' )","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Changing the Brightness of the image randomly\naug = get_aug([A.RandomBrightness(p=0.4)])\nbrightness = aug(**orig_annotations)\nannotations_list=[orig_annotations, brightness]\nsubtitle_list=['Original Image', 'Random Brightness']\nplot_image_list(annotations_list, subtitle_list, title='Change in Brightness' )\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Applying Random SunFlare\n\naug = get_aug([A.RandomSunFlare(p=1)])\nshadow = aug(**orig_annotations)\nannotations_list=[orig_annotations, shadow]\nsubtitle_list=['Original Image', 'Random Sun Flare']\nplot_image_list(annotations_list, subtitle_list, title='Random Sun Flare Results' )","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","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}