{"cells":[{"metadata":{},"cell_type":"markdown","source":"# Global Wheat Head Detection (GWHD) dataset \n### A large and diverse dataset of high resolution RGB labelled images to develop and benchmark wheat head detection methods.\n* Detection of wheat heads is an important task allowing to estimate pertinent traits including head population density and head characteristics such as sanitary state, size, maturity stage and the presence of awns\n* Several studies developed methods for wheat head detection from high-resolution RGB imagery. They are based on computer vision and machine learning and are generally calibrated and validated on limited datasets. \n![](https://media2.giphy.com/media/ubktuhEHhnb5C/200.gif)\n\n* The 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\n* The 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. There is a row in '*train.csv*' for each bounding box. Not all images have bounding boxes.\n* More details on the data acquisition and processes are available at https://arxiv.org/abs/2005.02162\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]**.","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"## Importing libraries","execution_count":null},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"import numpy as np # linear algebra\nimport pandas as pd\nimport ast \n\nfrom tqdm.notebook import tqdm\n\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nimport plotly.graph_objects as go\nimport plotly.figure_factory as ff\n\nimport os\nimport math\nimport cv2","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Data loading & Per-processing","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"df= pd.read_csv('../input/global-wheat-detection/train.csv')\nprint(df.shape)\ndf.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df.bbox=df.bbox.apply(lambda x: ast.literal_eval(x))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"uni_imgs=df.image_id.unique()\nuni_imgs","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"img_box_dict={}\nfor u_id in tqdm(uni_imgs):\n    arr= df[df.image_id== u_id ]['bbox'].values\n    img_box_dict[str(u_id)]= [box for box in arr]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df2=df.drop_duplicates(['image_id'], ignore_index=True)\ndf2","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df2['boxes']= df2.image_id.apply(lambda x: img_box_dict[str(x)])\n\ndf2['box_count']= df2.boxes.apply(lambda x: len(x))\ndf2.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def cal_area(boxes):\n    area_list=[]\n    for box in boxes:\n        x,y,w,h= box\n        area_list.append(w*h)\n    per= np.sum(np.array(area_list))/(1024.0*1024.0)\n    return per*100.0\n\ndef max_area(boxes):\n    area_list=[]\n    for box in boxes:\n        x,y,w,h= box\n        area_list.append(w*h)\n    per= max(area_list)/(1024.0*1024.0)\n    return per*100.0\n    ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df2['per_area']= df2.boxes.apply(lambda x: cal_area(x))\ndf2['max_area']= df2.boxes.apply(lambda x: max_area(x))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df2.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def load(path, resize=False, gray=False):\n    img= cv2.imread(path)\n    if resize:\n        img= cv2.resize(img, (500,500))\n    if gray:\n        img= cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)\n    else:\n        img= cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n    return img\n\ndef draw_rec(img, boxes):\n    for box in boxes:\n        x,y,w,h= box\n        x=int(x); y=int(y); w=int(w); h= int(h)\n        img= cv2.rectangle(img, (x,y), (x+w, y+h), color=(255, 153, 0), thickness=3)\n    return img","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def bright(label):\n    path= '../input/global-wheat-detection/train'\n    path= path+'/' +label+'.jpg'\n    img= load(path, gray=True, resize=True)\n    img= img/255.0\n    return np.sum(img)/(500.0*500.0)*100","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df2['brightness']= df2.image_id.apply(lambda x: bright(x))\ndf2.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df2.drop(['bbox'], 1, inplace=True)\ndf2.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Distribution Analysis","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"# Use `hole` to create a donut-like pie chart\nlabels= df2.source.value_counts().index\nvalues= df2.source.value_counts().values\nfig = go.Figure(data=[go.Pie(labels=labels, values=values, hole=.3)])\nfig.update_layout(\n    title_text=\"Source Distribution\",\n    # Add annotations in the center of the donut pies.\n    annotations=[dict(text='Source', x=0.50, y=0.5, font_size=20, showarrow=False)])\n    \nfig.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"#### TOP data Contributers (Sources)\n* arvalis_1\n* ethz_1\n* arvalis\n* rres_1","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"def hist_channel(df2):\n    red, blue, green= [],[],[]\n    for img_id in tqdm(df2.image_id.values):\n        path= '../input/global-wheat-detection/train'\n        img_path= os.path.join(path, img_id)\n        img_path= img_path + '.jpg'\n        img= load(img_path)\n        red.append(np.mean(img[:,:,0]))\n        blue.append(np.mean(img[:,:,2]))\n        green.append(np.mean(img[:,:,1]))\n    return red, green, blue\n\nred, green, blur= hist_channel(df2)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Group data together\nhist_data = [red, green, blur]\n\ngroup_labels = ['red', 'green', 'blue']\ncolors = ['rgb(255, 51, 51)', 'rgb(0, 153, 0)', 'rgb(77, 148, 255)']\n\n# Create distplot with custom bin_size\nfig = ff.create_distplot(hist_data, group_labels, bin_size=.4, colors=colors)\nfig.update_layout(\n    title_text=\"RGB color Distribution\",\n    xaxis=dict(title='Pixel Value'))\nfig.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"![](https://s3.amazonaws.com/libapps/accounts/73082/images/Skeweness.jpg)","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"# Add histogram data\ngroup_labels=[]\nhist_data = []\nfor label in df2.source.unique():\n    group_labels.append(label)\n    # Group data together\n    hist_data.append(df2[df2.source== label].brightness.values )\n\n\n\n# Create distplot with custom bin_size\nfig = ff.create_distplot(hist_data, group_labels)\n\nfig.update_layout(\n    title_text=\"Image Source Brightness Distribution\",\n    xaxis=dict(title='Brightness Percentage'))\nfig.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"#### Bright image contributers\n* arvalis_1\n* arvalis_2\n\n#### Non-Bright image contributers\n* rres_1\n* inrae_1","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"# Add histogram data\ngroup_labels=[]\nhist_data = []\nfor label in df2.source.unique():\n    group_labels.append(label)\n    # Group data together\n    hist_data.append(df2[df2.source== label].per_area.values )\n\n\n\n# Create distplot with custom bin_size\nfig = ff.create_distplot(hist_data, group_labels)\n\nfig.update_layout(\n    title_text=\"Bounding box Area per image Distribution\",\n    xaxis=dict(title='Percent Area'))\nfig.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"hist_data = [df2.box_count.values]\ngroup_labels = ['Boxes'] # name of the dataset\n\nfig = ff.create_distplot(hist_data, group_labels)\nfig.update_layout(\n    title_text=\"Bounding box Count per image Distribution\",\n    xaxis=dict(title='Count'))\nfig.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Viewing random images","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"sample= df2.sample(15).image_id.values\npath= '../input/global-wheat-detection/train'\nf, ax= plt.subplots(3, 5, figsize=(30, 15))\ni=0\nfor label in tqdm(sample):\n    img_path= os.path.join(path, label)\n    img_path= img_path + '.jpg'\n    \n    img= load(img_path)\n    ax[i//5][i%5].imshow(img, aspect='auto')\n    ax[i//5][i%5].set_xticks([]); ax[i//5][i%5].set_yticks([])\n    i+=1\nplt.suptitle(\"Random images of Traning set\", size=30)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Images with Bounding Boxes","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"sample= df2.image_id[:15].values\npath= '../input/global-wheat-detection/train'\nf, ax= plt.subplots(3, 5, figsize=(30, 15))\ni=0\nfor label in tqdm(sample):\n    img_path= os.path.join(path, label)\n    img_path= img_path + '.jpg'\n    \n    img= load(img_path)\n    img= draw_rec(img, df2.boxes[i])\n    ax[i//5][i%5].imshow(img, aspect='auto')\n    ax[i//5][i%5].set_xticks([]); ax[i//5][i%5].set_yticks([])\n    i+=1\nplt.suptitle(\"Images from Traning set with bounding boxes \", size=30)\nplt.show()\n    ","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Images with HIGH density bounding boxes","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"sample= df2[df2.box_count>90].image_id[:10].values\nlabel= df2[df2.box_count>90].index\npath= '../input/global-wheat-detection/train'\nf, ax= plt.subplots(2, 5, figsize=(30, 15))\ni=0\nfor label in tqdm(sample):\n    img_path= os.path.join(path, label)\n    img_path= img_path + '.jpg'\n    \n    img= load(img_path)\n    img= draw_rec(img, df2[df2.box_count>90].reset_index().boxes[i])\n    ax[i//5][i%5].imshow(img, aspect='auto')\n    ax[i//5][i%5].set_xticks([]); ax[i//5][i%5].set_yticks([])\n    i+=1\nplt.suptitle(\"Images with high density bounding boxes\", size=30)\nplt.show()\n    ","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Images with LOW density bounding boxes","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"sample= df2[df2.box_count< 5].image_id[:15].values\n\npath= '../input/global-wheat-detection/train'\nf, ax= plt.subplots(3, 5, figsize=(30, 15))\ni=0\nfor label in tqdm(sample):\n    img_path= os.path.join(path, label)\n    img_path= img_path + '.jpg'\n    \n    img= load(img_path)\n    img= draw_rec(img, df2[df2.box_count< 5].reset_index().boxes[i])\n    ax[i//5][i%5].imshow(img, aspect='auto')\n    ax[i//5][i%5].set_xticks([]); ax[i//5][i%5].set_yticks([])\n    i+=1\n    \nplt.suptitle(\"Images with low density bounding boxes\", size=30)\nplt.show()\n    ","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Images with ORDINARY density bounding boxes","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"sample= df2[(df2.box_count<15) & (df2.box_count>8)].image_id[:15].values\n\npath= '../input/global-wheat-detection/train'\nf, ax= plt.subplots(3, 5, figsize=(30, 15))\ni=0\nfor label in tqdm(sample):\n    img_path= os.path.join(path, label)\n    img_path= img_path + '.jpg'\n    \n    img= load(img_path)\n    img= draw_rec(img, df2[(df2.box_count<15) & (df2.box_count>8)].reset_index().boxes[i])\n    ax[i//5][i%5].imshow(img, aspect='auto')\n    ax[i//5][i%5].set_xticks([]); ax[i//5][i%5].set_yticks([])\n    i+=1\nplt.suptitle(\"Images with Moderate density bounding boxes\", size=30)\nplt.show()\n    ","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Images with HIGH AREA Bounding boxes","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"sample= df2.sort_values(by=['max_area'], ascending=False)[:10].reset_index().image_id.values\n\npath= '../input/global-wheat-detection/train'\nf, ax= plt.subplots(2, 5, figsize=(30, 12))\ni=0\nfor label in tqdm(sample):\n    img_path= os.path.join(path, label)\n    img_path= img_path + '.jpg'\n    \n    img= load(img_path)\n    img= draw_rec(img, df2.sort_values(by=['max_area'], ascending=False)[0:10].reset_index().boxes[i])\n    ax[i//5][i%5].imshow(img, aspect='auto')\n    ax[i//5][i%5].set_xticks([]); ax[i//5][i%5].set_yticks([])\n    i+=1\nplt.suptitle(\"Images with High Area Bounding boxes\", size=30)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"#### The problem with *High Area Mismatched Bounding Boxes* needs to be addressed to Model Traning","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"## Images with LOW AREA Bounding boxes","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"sample= df2.sort_values(by=['max_area'], ascending=True)[:10].reset_index().image_id.values\n\npath= '../input/global-wheat-detection/train'\nf, ax= plt.subplots(2, 5, figsize=(30, 12))\ni=0\nfor label in tqdm(sample):\n    img_path= os.path.join(path, label)\n    img_path= img_path + '.jpg'\n    \n    img= load(img_path)\n    img= draw_rec(img, df2.sort_values(by=['max_area'], ascending=True)[:10].reset_index().boxes[i])\n    ax[i//5][i%5].imshow(img, aspect='auto')\n    ax[i//5][i%5].set_xticks([]); ax[i//5][i%5].set_yticks([])\n    i+=1\nplt.suptitle(\"Images with High Area Bounding boxes\", size=30)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Bright images","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"sample= df2.sort_values(by=['brightness'], ascending=False).reset_index()[:10].image_id.values\n\npath= '../input/global-wheat-detection/train'\nf, ax= plt.subplots(2, 5, figsize=(30, 12))\ni=0\nfor label in tqdm(sample):\n    img_path= os.path.join(path, label)\n    img_path= img_path + '.jpg'\n    \n    img= load(img_path)\n    img= draw_rec(img, df2.sort_values(by=['brightness'], ascending=False).reset_index()[:10].boxes[i])\n    ax[i//5][i%5].imshow(img, aspect='auto')\n    ax[i//5][i%5].set_xticks([]); ax[i//5][i%5].set_yticks([])\n    i+=1\nplt.suptitle(\"High Brightness images\", size=30)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Dark images","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"sample= df2.sort_values(by=['brightness'], ascending=True)[10:20].reset_index().image_id.values\n\npath= '../input/global-wheat-detection/train'\nf, ax= plt.subplots(2, 5, figsize=(30, 12))\ni=0\nfor label in tqdm(sample):\n    img_path= os.path.join(path, label)\n    img_path= img_path + '.jpg'\n    \n    img= load(img_path)\n    img= draw_rec(img, df2.sort_values(by=['brightness'], ascending=True)[10:20].reset_index().boxes[i])\n    ax[i//5][i%5].imshow(img, aspect='auto')\n    ax[i//5][i%5].set_xticks([]); ax[i//5][i%5].set_yticks([])\n    i+=1\nplt.suptitle(\"Low Brightness images\", size=30)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"![](https://i.gifer.com/7ImI.gif)","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}