{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"markdown","source":"# Making Dough\nLet's get our hands dirty and make some dough. \n\n\n<p align=\"center\">\n  <img width=\"460\" height=\"300\" src=\"https://cdn-a.william-reed.com/var/wrbm_gb_food_pharma/storage/images/7/0/8/1/491807-1-eng-GB/Freezing-dough-Understand-impact-on-glutenin-protein-say-researchers_wrbm_large.jpg\">\n</p>\n\n- Aim: Detect wheat heads (in form of multiple bounding boxes) of wheat plant images, all of size 1024x1024. \n- Data source: The [Global WHEAT dataset](http://www.global-wheat.com/2020-challenge/).\n- Metric: Mean average precision at different intersection over union (IoU) thresholds. Thresholds vary from 0.5 to 0.75 with a step size of 0.05.\n- Time: We have 3 months for now."},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"import matplotlib.patches as patches\nimport matplotlib.pyplot as plt\nfrom PIL import Image\nimport seaborn as sns\nimport pandas as pd\nimport numpy as np\nimport os\n\nsns.set(style=\"darkgrid\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"DIR = \"../input/global-wheat-detection/\"\nTRAIN = \"train.csv\"\nSUBMISSION = \"sample_submission.csv\"\nTRAIN_IMAGES = \"train\"\nTEST_IMAGES = \"test\"\nWIDTH = 1024\nHEIGHT = 1024\n\nTRAIN_IMAGES = [os.path.join(DIR, \"train\", fname) for fname in os.listdir(os.path.join(DIR, \"train\"))]\nTEST_IMAGES = [os.path.join(DIR, \"test\", fname) for fname in os.listdir(os.path.join(DIR, \"test\"))]\n\ntrain_df = pd.read_csv(os.path.join(DIR, TRAIN))\nsubmission_df = pd.read_csv(os.path.join(DIR, TRAIN))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(train_df.shape)\nprint(f\"Total training images: {len(TRAIN_IMAGES)}\")\nprint(f\"Total test images: {len(TEST_IMAGES)}\")\ntrain_df.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Only 3422 train and 10 test images."},{"metadata":{},"cell_type":"markdown","source":"# DataSource"},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.figure(figsize=(12, 6))\nsns.countplot(train_df.source)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df.source.value_counts()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Number of bounding boxes in images provided by each source"},{"metadata":{"trusted":true},"cell_type":"code","source":"bbox_counts_by_source = train_df.groupby([\"source\"]).apply(lambda x:x[\"image_id\"].value_counts().mean())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.figure(figsize=(10, 6))\nbbox_counts_by_source.plot(kind='bar')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"bbox_counts_by_source","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Wow, not only ethz_1 have given the maximum number of test images, but they also provide more number of bounding boxes per image. I expect their data to be of very high quality. Maybe I should fine tune my model only on their data."},{"metadata":{},"cell_type":"markdown","source":"# Number of boxes per image"},{"metadata":{"trusted":true},"cell_type":"code","source":"box_count = train_df[\"image_id\"].value_counts()\nprint(f\"Min boxes: {box_count.min()}\")\nprint(f\"Max boxes: {box_count.max()}\")\nprint(f\"Mean boxes: {box_count.mean()}\")\nprint(f\"Std boxes: {box_count.std()}\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.figure(figsize=(10, 6))\nsns.distplot(box_count.values)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Area/Location of boxes"},{"metadata":{"trusted":true},"cell_type":"code","source":"bbox = lambda bbox: [float(x) for x in bbox[1:-1].split(\",\")]\ntrain_df.bbox = train_df.bbox.apply(bbox)\ntrain_df['xmin'] = train_df.bbox.apply(lambda x: x[0])\ntrain_df['ymin'] = train_df.bbox.apply(lambda x: x[1])\ntrain_df['width'] = train_df.bbox.apply(lambda x: x[2])\ntrain_df['height'] = train_df.bbox.apply(lambda x: x[3])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"area_percent = train_df['width']*train_df['height'] / (WIDTH*HEIGHT)\nplt.figure(figsize=(10, 6))\nplt.title(\"Area % for whole dataset.\")\nprint(f\"Min area: {area_percent.min()}%\")\nprint(f\"Max area: {area_percent.max()}%\")\nprint(f\"Mean area: {area_percent.mean()}%\")\nprint(f\"Std area: {area_percent.std()}%\")\nsns.distplot(area_percent)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"area_per_image = train_df.groupby(\"image_id\").apply(lambda x: (x[\"width\"]*x[\"height\"]).sum()/(WIDTH*HEIGHT))\nplt.figure(figsize=(10, 6))\nplt.title(\"Area % for each image.\")\nprint(f\"Min area per image: {area_per_image.min()}%\")\nprint(f\"Max area per image: {area_per_image.max()}%\")\nprint(f\"Mean area per image: {area_per_image.mean()}%\")\nprint(f\"Std area per image: {area_per_image.std()}%\")\nsns.distplot(area_per_image)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Height and width distribution of bounding boxes"},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.figure(figsize=(10, 6))\nsns.distplot(train_df.height)\nplt.show()\n\nplt.figure(figsize=(10, 6))\nsns.distplot(train_df.width)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Visualize images and their bounding boxes"},{"metadata":{"trusted":true},"cell_type":"code","source":"def get_boxes(df):\n    xmins, ymins, widths, heights = df['xmin'],df['ymin'], df['width'], df['height']\n    ps = []\n    for i in range(len(xmins)):\n        p = patches.Rectangle((xmins.iloc[i], ymins.iloc[i]),widths.iloc[i], heights.iloc[i], linewidth=2, edgecolor='c', facecolor='none')\n        ps.append(p)\n    return ps  \n\ndef show_img_bbox(rows=2, columns=2, source=None):\n    \"\"\"\n    source: Random selection only from images from `source`. \n    Thanks to https://www.kaggle.com/devvindan/wheat-detection-eda for the idea of this.\n    \"\"\"\n    fig = plt.figure(figsize=(int(8*columns), int(8*rows)))\n    if source is not None:\n        image_names = np.random.choice(train_df[train_df.source==source].image_id.unique(), columns*rows)\n    image_names = np.random.choice(train_df.image_id.unique(), columns*rows)\n    image_paths = [os.path.join(DIR, 'train', img+\".jpg\") for img in image_names]\n    for i in range(1, columns*rows +1):\n        img = Image.open(image_paths[i-1])\n        ax = fig.add_subplot(rows, columns, i)\n        plt.imshow(img)\n        df = train_df[train_df.image_id==image_names[i-1]]\n        bboxes = get_boxes(df)\n        [ax.add_patch(bbox) for bbox in bboxes]\n        plt.axis('off')\n\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"show_img_bbox()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sources = train_df.source.unique()\nfor source in sources:\n    print(f\"Images from: {source}\")\n    show_img_bbox(source=source)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"markdown","source":"# Some thoughts:\n- bbox is used for bounding box \n- I am making dough here, these images shall be the wheat, pytorch dataloader shall be the grinder, convolutions shall be the water, Adam shall be the weather and public kernel tricks/discussions shall be my magic ingredient.\n- I am so glad the data for this competition is under 1GB."},{"metadata":{"trusted":true},"cell_type":"code","source":"!du ../input/global-wheat-detection/ -h","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"621M of total data only <3\n\nBaseline model coming soon. "}],"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}