{"cells":[{"metadata":{},"cell_type":"markdown","source":"# Libraries","execution_count":null},{"metadata":{"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)\nimport tensorflow as tf # tensorflow package\nimport matplotlib.pyplot as plt \nimport cv2 # computer vision library\nimport urllib # package which collect several modules for working with URLs\nimport os # operating system modules function\nfrom tqdm.notebook import tqdm # progress bar library to support nested loops\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Data Path","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"pwd","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"cd /kaggle/input/","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"cp-r keras-retinanet /kaggle/working/","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"cd /kaggle/working/keras-retinanet/keras-retinanet-master","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Install: Keras - Retinanet","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"!pip install .","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!ls","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!python setup.py build_ext --inplace","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"path = '/kaggle/input/global-wheat-detection'\ntrainFile = path + '/train.csv'\ntrainDataFile = path + '/train/'\ntestDataFile = path + '/test/'\ntestFile = path + '/sample_submission.csv'\nnames = ['ImgID', 'Width', 'Height', 'bbox', 'Source']\ndata = pd.read_csv(trainFile, skiprows=1,names=names)\nprint(data.shape)\ndata","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"scrolled":false},"cell_type":"code","source":"# Seperate bboxs to x1,y1,x2,y2:\ndata_Frame = pd.DataFrame()\ndata_Frame['ImgID']=data['ImgID'].apply(lambda x: f'{trainDataFile}{x}.jpg')\n\n# Add x1,y1,x2,y2 to data frame representation:\nbbox = data.bbox.str.split(\",\",expand=True)\ndata_Frame['x1'] = bbox[0].str.strip('[').astype(float).apply(np.int64)\ndata_Frame['y1'] = bbox[1].str.strip(' ').astype(float).apply(np.int64)\ndata_Frame['x2'] = bbox[2].str.strip(' ').astype(float).apply(np.int64)+data_Frame['x1']\ndata_Frame['y2'] = bbox[3].str.strip(']').astype(float).apply(np.int64)+data_Frame['y1']\ndata_Frame['class_name'] = 'wheat'\ndata_Frame , data_Frame.dtypes","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Visualizing Images With Bboxes","execution_count":null},{"metadata":{"trusted":true,"scrolled":false},"cell_type":"code","source":"# Viusualise the data with bboxes:\nimgSel = np.random.RandomState(50) # Generate random numbers drawn from variety of probability.\ndef show_images_with_box(df):\n    \"\"\"Subplot wheat images including bbox, based on data frame (df) input.\"\"\"\n    size = 3 # Reperesent the number of rows and colums\n    fig, axs = plt.subplots(size, size, figsize=(25, 25), sharex=True, sharey=True)\n    for row in range(size):\n        for col in range(size):\n            randomIdx = imgSel.choice(range(df.shape[0])) # Random  row index samples.\n            img_name = df.iloc[randomIdx]['ImgID'] # Selecting data based on it's numerical position in the data frame.     \n            image = plt.imread(img_name)                        \n            # Draw boxes on images by label based selection command(loc):\n            selectedImg = df.loc[df[\"ImgID\"]==img_name,[\"x1\",\"y1\",\"x2\",\"y2\"]]\n            class_name = 'wheat'\n            bboxArray = np.array(selectedImg.values.tolist())\n            for bbox in bboxArray:\n                image = cv2.rectangle(image, (int(bbox[0]),\n                                      int(bbox[1])), (int(bbox[2]),\n                                      int(bbox[3])), color = (255,255,255), thickness=3) \n            axs[row, col].imshow(image)\n            axs[row, col].axis('off')\n            axs[row, col].set_title(f'#{class_name} marked = {bboxArray.shape[0]}',size='xx-large')\n            \n              \n    plt.suptitle(f'{size*size} Random images',size='xx-large')\n    plt.show() \n    '\\]}'\nshow_images_with_box(data_Frame)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Import Models and function","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras_retinanet import models\nfrom keras_retinanet.utils.image import read_image_bgr, preprocess_image, resize_image\nfrom keras_retinanet.utils.visualization import draw_box, draw_caption\nfrom keras_retinanet.utils.colors import label_color","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Coverting the data into the required representation :\ndata_Frame.to_csv('annotations.csv', index=False, header=None) # Write object to a separated csv file\nwith open('classes.csv', 'w') as f: # Create a file in writing mode\n    f.write('wheat,0\\n')\n  \n# Visualize the data as required by RetinaNet\n!head classes.csv\n!head annotations.csv","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\nos.makedirs(\"snapshots\", exist_ok=True) # Create a directory\npreTrainModel = \"./snapshots/_pretrained_model.h5\" # Pretrained model name in keras-retinanet ripo\nurlModel = \"https://github.com/fizyr/keras-retinanet/releases/download/0.5.1/resnet50_coco_best_v2.1.0.h5\"\n# urllib.request.urlretrieve(urlModel, preTrainModel) # Copy a network object denoted by a URL to a local file","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Train a model","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"#This section creates the train model and includes all parameters.\n# Use this section if you need to train your model otherwise, if you all ready train data, please download as the follow section.\nflag = False\nif(flag):\n    !keras_retinanet/bin/train.py \\\n    --freeze-backbone \\\n    --random-transform \\\n    --weights {preTrainModel} \\\n    --batch-size 16 \\\n    --steps 500 \\\n    --epochs 10 \\\n    csv annotations.csv classes.csv\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\n!ls snapshots # Replicate snapshots\nmodel_path = os.path.join('/kaggle/input/pre-trained-model', sorted(os.listdir('/kaggle/input/pre-trained-model'), reverse=True)[0])\nprint(model_path)\n# Load the model\nmodel = models.load_model(model_path, backbone_name='resnet50')\nmodel = models.convert_model(model)\n\nlabels_to_names = pd.read_csv('classes.csv', header=None).T.loc[0].to_dict()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Pre - detection","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"def pred(image):\n#Retruns boxes, scores and label prediction by a given image.\n  image = preprocess_image(image.copy())\n#   image, scale = resize_image(image)\n# Create prediction for each parameters on a single batch sample\n  boxes, scores, labels = model.predict_on_batch(np.expand_dims(image, axis=0))\n\n#   boxes /= scale\n\n  return boxes, scores, labels","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"scoreThreshold = 0.34\ndef drawDetections(image, boxes, scores, labels):\n    #The function receive image, boxes, scores and label as input and then draw the detection based on a threshold (scoreThreshold).        \n    \n  for box, score, label in zip(boxes[0], scores[0], labels[0]):#This loop takes 3 iterable inputs and return them as an iterator (single entity).\n    if score < scoreThreshold: #An inner condition in-order to detect wheater the input fit to the threshold.\n        break\n\n    color = (255,0,0)\n    b = box.astype(int)\n    draw_box(image, b, color=color)\n\n    caption = \"{} {:.3f}\".format(labels_to_names[label], score)\n    cv2.putText(image, caption, (b[0], b[1] - 10), cv2.FONT_HERSHEY_PLAIN, 2, (255, 255, 255), 2)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def showDetectedObjects(img_name):\n    #The function receive image name and then plot wheat head detection. \n  img_path = testDataFile+img_name\n  \n  im = read_image_bgr(img_path)\n\n  bx, scr, lb = pred(im)\n\n  imgPlot = im.copy()\n  imgPlot = cv2.cvtColor(imgPlot, cv2.COLOR_BGR2RGB)\n\n  drawDetections(imgPlot, bx, scr, lb)\n  plt.figure(figsize=(15,10))\n  plt.axis('off')\n  plt.imshow(imgPlot)\n  plt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Detection","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"imgs = os.listdir(testDataFile) # Create a list which contain the names of the entries given by the testDataFile.\nfor idx in imgs:\n    showDetectedObjects(idx)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Pre - Submission","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"preds = []\nimgid =  []\nfor img in tqdm(imgs,total = len(imgs)):\n    predStr = ''\n    img_path = testDataFile+img\n    im = read_image_bgr(img_path)\n    bx, scr, lb = pred(im)\n    bx = bx[0]\n    scr = scr[0]\n    imgid.append(img.split(\".\")[0])\n    for idx in range(bx.shape[0]):\n        if scr[idx] > scoreThreshold:\n            box,score = bx[idx],scr[idx]            \n            predStr += (f'{score:.4} {int(box[0])} {int(box[1])} {int(box[2]-box[0])} {int(box[3]-box[1])} ') # Reshape coordinate to submssion format\n    preds.append(predStr)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sub = {\"image_id\":imgid, \"PredictionString\":preds} # Submition format.\nsub = pd.DataFrame(sub)\nsub","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Submission","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"sub.to_csv('/kaggle/working/submission.csv',index=False)","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}