{"cells":[{"metadata":{},"cell_type":"markdown","source":"# Introduction\n\nIn this competition, you’ll detect wheat heads from outdoor images of wheat plants, including wheat datasets from around the globe. If successful, researchers can accurately estimate the density and size of wheat heads in different varieties. With improved detection farmers can better assess their crops, ultimately bringing cereal, toast, and other favorite dishes to your table.\n\nTo get large and accurate data about wheat fields worldwide, plant scientists use image detection of \"wheat heads\"—spikes atop the plant containing grain. These images are used to estimate the density and size of wheat heads in different varieties. \n\nModels developed for wheat phenotyping need to generalize between different growing environments. Current detection methods involve one- and two-stage detectors (Yolo-V3 and Faster-RCNN), but even when trained with a large dataset, a bias to the training region remains.\n\n![https://storage.googleapis.com/kaggle-media/competitions/UofS-Wheat/descriptionimage.png](https://storage.googleapis.com/kaggle-media/competitions/UofS-Wheat/descriptionimage.png)\n\n\n***N.B. Object detection is a computer technology related to computer vision and image processing that deals with detecting instances of semantic objects of a certain class (such as humans, buildings, or cars) in digital images and videos.***\n[https://en.wikipedia.org/wiki/Object_detection](https://en.wikipedia.org/wiki/Object_detection)\n\n***Example of Object detection:***\n![https://upload.wikimedia.org/wikipedia/commons/thumb/3/38/Detected-with-YOLO--Schreibtisch-mit-Objekten.jpg/1024px-Detected-with-YOLO--Schreibtisch-mit-Objekten.jpg](https://upload.wikimedia.org/wikipedia/commons/thumb/3/38/Detected-with-YOLO--Schreibtisch-mit-Objekten.jpg/1024px-Detected-with-YOLO--Schreibtisch-mit-Objekten.jpg)","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"# Data\n\nThe data is images of wheat fields, with bounding boxes for each identified wheat head. **Not all images include wheat heads / bounding boxes.** The images were recorded in many locations around the world.\n\nThe CSV data is simple - the image ID matches up with the filename of a given image, and the width and height of the image are included, along with a bounding box (see below). There is a row in train.csv for each bounding box. Not all images have bounding boxes.\n\n**Files**\n\n    train.csv - the training data\n    sample_submission.csv - a sample submission file in the correct format\n    train.zip - training images\n    test.zip - test images\n\n1. train.zip consists of 3422 images\n2. test.zip consists of 10 images\n3. train.csv has 3373 images (98% of training images) and unique 117761 bounding boxes\n\n**Columns**\n\n    image_id - the unique image ID\n    width, height - the width and height of the images\n    bbox - a bounding box, formatted as a Python-style list of [xmin, ymin, width, height]\n    \n1. All the images are of 1024 * 1024 pixels","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"# Evaluation Metric\nhis competition is evaluated on the mean average precision at different intersection over union (IoU) thresholds. The IoU of a set of predicted bounding boxes and ground truth bounding boxes is calculated as:\nIoU(A,B)=A∩BA∪B.\n\n![https://storage.googleapis.com/kaggle-media/competitions/rsna/IoU.jpg](https://storage.googleapis.com/kaggle-media/competitions/rsna/IoU.jpg)\n\nThe metric sweeps over a range of IoU thresholds, at each point calculating an average precision value. The threshold values range from 0.5 to 0.75 with a step size of 0.05. In other words, at a threshold of 0.5, a predicted object is considered a \"hit\" if its intersection over union with a ground truth object is greater than 0.5.\n\nAt each threshold value t\n, a precision value is calculated based on the number of true positives (TP), false negatives (FN), and false positives (FP) resulting from comparing the predicted object to all ground truth objects:\nTP(t)/TP(t)+FP(t)+FN(t)\n\nThe average precision of a single image is calculated as the mean of the above precision values at each IoU threshold:\n$$ \\frac{1}{|thresholds|} \\sum_t \\frac{TP(t)}{TP(t) + FP(t) + FN(t)}.$$\n\nLastly, the score returned by the competition metric is the mean taken over the individual average precisions of each image in the test dataset.","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"# Importing Libraries","execution_count":null},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n\nimport matplotlib.pyplot as plt\n\nimport cv2\n\nimport os","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Reading the Dataset","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"BASE_DIR = '/kaggle/input/global-wheat-detection/'\ntrain_data = pd.read_csv(BASE_DIR+\"train.csv\")\nsubmission_file = pd.read_csv(BASE_DIR+\"sample_submission.csv\")\ntrain_images_dir = BASE_DIR + \"train/\"","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Basic Statistics","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"train_data.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission_file.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(\"The training data has {} rows and {} columns\".format(train_data.shape[0],train_data.shape[1]))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_data.isna().sum()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_data.nunique()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_data.source.unique()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_data.groupby(\"source\")[\"image_id\"].nunique()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Submission file doesn't have source column so it will be difficult to use it ","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"all_images = set(x.split(\".\")[0] for x in os.listdir(train_images_dir))\nimages_with_bb = set(train_data.image_id.unique())\nimages_without_bb = all_images^ images_with_bb","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_images_without_bb=pd.DataFrame(images_without_bb,columns = [\"image_id\"])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_data.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_data[[\"x_start\",\"y_start\",\"width\",\"height\"]] = pd.DataFrame([i[1:-1].split(',') for i in train_data.bbox.to_list()],index=train_data.index)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_data = train_data.astype({\"x_start\":float,\"y_start\":float,\"width\":float,\"height\":float})\ntrain_data = train_data.astype({\"x_start\":int,\"y_start\":int,\"width\":int,\"height\":int})","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_data.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Looking at the images","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"def plot_images(image_list,rows,cols,title):\n    fig,ax = plt.subplots(rows,cols,figsize = (25,5))\n    ax = ax.flatten()\n    for i, image_id in enumerate(image_list):\n        image = cv2.imread(train_images_dir+'{}.jpg'.format(image_id))\n        image = cv2.cvtColor(image,cv2.COLOR_BGR2RGB)\n        ax[i].imshow(image)\n        ax[i].set_axis_off()\n        ax[i].set_title(image_id)\n    plt.suptitle(title)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plot_images(train_data[train_data.source == 'arvalis_1'].sample(5)[\"image_id\"].values,1,5,\"Images with wheat\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plot_images(train_data[train_data.source == 'arvalis_2'].sample(5)[\"image_id\"].values,1,5,\"Images with wheat\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plot_images(train_data[train_data.source == 'arvalis_3'].sample(5)[\"image_id\"].values,1,5,\"Images with wheat\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plot_images(train_data[train_data.source == 'ethz_1'].sample(5)[\"image_id\"].values,1,5,\"Images with wheat\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plot_images(train_data[train_data.source == 'inrae_1'].sample(5)[\"image_id\"].values,1,5,\"Images with wheat\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plot_images(train_data[train_data.source == 'rres_1'].sample(5)[\"image_id\"].values,1,5,\"Images with wheat\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plot_images(train_data[train_data.source == 'usask_1'].sample(5)[\"image_id\"].values,1,5,\"Images with wheat\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plot_images(df_images_without_bb.sample(10)[\"image_id\"].values,2,5,\"Images without wheat\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def plot_images_with_bb(imageId):\n    plt.rcParams[\"figure.figsize\"] = (10,10)\n    bboxes = train_data[train_data.image_id == imageId]\n    image = cv2.imread(train_images_dir+'{}.jpg'.format(imageId))\n    image = cv2.cvtColor(image,cv2.COLOR_BGR2RGB)\n    for row in bboxes.iterrows():\n        image = cv2.rectangle(image,(row[1][\"x_start\"],row[1][\"y_start\"]),(row[1][\"x_start\"]+row[1][\"width\"],row[1][\"y_start\"]+row[1][\"height\"]),(255,0,0),5)\n        fig = plt.imshow(image)\n    plt.axis(\"off\")\n    plt.title(imageId)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plot_images_with_bb(\"2ae9c276f\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"***Please upvote my kernel if you like it***","execution_count":null}],"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}