{"cells":[{"metadata":{},"cell_type":"markdown","source":"# This is my first kaggle notebook !\n# In this notebook i will use the RetinaNet with https://github.com/fizyr/keras-retinanet API and TensorFlow backend","execution_count":null},{"metadata":{"trusted":true,"scrolled":false},"cell_type":"code","source":"# First imports and paths\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\npath = '/kaggle/input/global-wheat-detection'\ntrainDir = path + '/train.csv'\ntrainDataDir = path + '/train/'\ntestDataDir = path + '/test/'\ntestDir = path + '/sample_submission.csv'\nnames = ['ImageID', 'Width', 'Height', 'bbox', 'Source']\ndata = pd.read_csv(trainDir, skiprows=1,names=names)\nprint(data.shape)\ndata","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Data management & Preparations","execution_count":null},{"metadata":{"trusted":true,"scrolled":false},"cell_type":"code","source":"# Seperate bboxs to path/to/image.jpg,x1,y1,x2,y2,class_name\ndataDF=pd.DataFrame()\ndataDF['ImageID']=data['ImageID'].apply(lambda x: f'{trainDataDir}{x}.jpg')\n\n# Fields exteraction\nbbox = data.bbox.str.split(\",\",expand=True)\ndataDF['x1'] = bbox[0].str.strip('[').astype(float).apply(np.int)\ndataDF['y1'] = bbox[1].str.strip(' ').astype(float).apply(np.int)\ndataDF['x2'] = bbox[2].str.strip(' ').astype(float).apply(np.int)+dataDF['x1']\ndataDF['y2'] = bbox[3].str.strip(']').astype(float).apply(np.int)+dataDF['y1']\ndataDF['class_name'] = 'wheat'\ndataDF , dataDF.dtypes","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Visualize the data randomly","execution_count":null},{"metadata":{"trusted":true,"scrolled":false},"cell_type":"code","source":"# Viusualise the data with bboxes\nimport matplotlib.pyplot as plt\nimport cv2\n\nndar = np.random.RandomState(50)\ndef show_images_with_box(df):\n    nrows=3\n    ncols=3\n    fig, axs = plt.subplots(nrows, ncols, figsize=(25, 25), sharex=True, sharey=True)\n\n    for r in range(nrows):\n        for c in range(ncols):\n            ridx = ndar.choice(range(df.shape[0])) # Random row selection\n            img_name = df.iloc[ridx]['ImageID'] # index based data selection\n      \n            image = plt.imread(img_name) \n                        \n            # find all the records of the provided image and draw box on the wheat heads\n            chosen_image = df.loc[df[\"ImageID\"]==img_name,[\"x1\",\"y1\",\"x2\",\"y2\"]] # Grabbing the bbox info by label bassed selection\n            class_name = 'wheat'\n            bbox_array   = np.array(chosen_image.values.tolist())\n\n            for bbox in bbox_array:\n                image = cv2.rectangle(image, (int(bbox[0]), int(bbox[1])), (int(bbox[2]), int(bbox[3])), color = (255,255,255), thickness=3) \n\n            axs[r, c].imshow(image)\n            axs[r, c].axis('off')\n            axs[r, c].set_title(f'#{class_name} marked = {bbox_array.shape[0]}',size='xx-large')\n            \n              \n    plt.suptitle(f'{nrows*ncols} Random images',size='xx-large')\n    plt.show() \n    \n\nshow_images_with_box(dataDF)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Clone keras-retinanet ripo & install","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"cd /kaggle/input/","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#!git clone https://github.com/fizyr/keras-retinanet.git\n!cp -r kerasresnet1/keras-resnet /kaggle/working\n!cp -r kerasretinanet1/keras-retinanet /kaggle/working","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"%cd /kaggle/working/keras-resnet/","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!pip install . --user --no-deps","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":"%cd /kaggle/working/keras-retinanet/","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!pip install . --user --no-deps","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":"# Importing necessary libs and functions\nimport tensorflow as tf\nfrom 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":"# Creating the annotations and class files for a valid training as required by RetinaNet \nANNOTATIONS_FILE = 'annotations.csv'\nCLASSES_FILE = 'classes.csv'\ndataDF.to_csv(ANNOTATIONS_FILE, index=False, header=None)\n\nclasses = set(['wheat'])\nwith open(CLASSES_FILE, 'w') as f: # Open file in 'write' mode\n  for i, line in enumerate(sorted(classes)):\n    f.write('{},{}\\n'.format(line,i))\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":"import urllib\nimport os\n\nos.makedirs(\"snapshots\", exist_ok=True) # Creation of snapshots folder if is not exist\nPRETRAINED_MODEL = \"./snapshots/_pretrained_model.h5\" # Pretrained model name in keras-retinanet ripo\nURL_MODEL = \"https://github.com/fizyr/keras-retinanet/releases/download/0.5.1/resnet50_coco_best_v2.1.0.h5\"\n\n#urllib.request.urlretrieve(URL_MODEL, PRETRAINED_MODEL) # Download the model\n\nprint('Downloaded pretrained model to ' + PRETRAINED_MODEL) # Notify when done.\n!cp -r /kaggle/input/pre-trained-model/ /snapshots","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Train the model OR import a pre-trained one (Training process is long)","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"train_preTrain = False # if you want to train switch to 'True' else, False\nif train_preTrain:\n    !keras_retinanet/bin/train.py \\\n    --freeze-backbone \\\n    --random-transform \\\n    --weights {PRETRAINED_MODEL} \\\n    --batch-size 16 \\\n    --steps 500 \\\n    --epochs 10 \\\n    csv annotations.csv classes.csv","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!ls snapshots\nif train_preTrain:\n    model_path = os.path.join('snapshots', sorted(os.listdir('snapshots'), reverse=True)[0])\nelse:\n    model_path = os.path.join('/kaggle/input/pre-trained-model', sorted(os.listdir('/kaggle/input/pre-trained-model'), reverse=True)[0])\n    #model_path = os.path.join('snapshots', sorted(os.listdir('snapshots'), reverse=True)[0])\n\n        \n\nprint(model_path) # Import a pre-saved trained model\n\nmodel = models.load_model(model_path, backbone_name='resnet50')\nmodel = models.convert_model(model)\n\nlabels_to_names = pd.read_csv(CLASSES_FILE, header=None).T.loc[0].to_dict()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Prediction functiom, run images through the model and get the [boxes, scores, labels]\ndef predict(image):\n  image = preprocess_image(image.copy())\n  image, scale = resize_image(image)\n\n  boxes, scores, labels = model.predict_on_batch(np.expand_dims(image, axis=0)) # exporting predictions on batch\n\n  boxes /= scale # rescale boxes\n\n  return boxes, scores, labels","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Threshold definition and drawing the rect boxes around the preds\nTHRES_SCORE = 0.457\n\ndef draw_detections(image, boxes, scores, labels):\n  for box, score, label in zip(boxes[0], scores[0], labels[0]): # zipping boxes,scores,labels as one iterator\n    if score < THRES_SCORE:\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":"# Plot the detected bboxes over the image\ndef show_detected_objects(imgName):\n  img_path = testDataDir+imgName\n  \n  image = read_image_bgr(img_path)\n\n  boxes, scores, labels = predict(image)\n\n  draw = image.copy()\n  draw = cv2.cvtColor(draw, cv2.COLOR_BGR2RGB)\n\n  draw_detections(draw, boxes, scores, labels)\n  plt.figure(figsize=(15,10))\n  plt.axis('on')\n  plt.imshow(draw)\n  plt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Run over the test images and get the scores and plot them\nimgs=os.listdir(testDataDir) # Get a list with the image's names\nfor idx in imgs:\n    show_detected_objects(idx)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Preparation for submission","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"# Append the predictions by the submission request \nfrom tqdm.notebook import tqdm # Progress bar for nested loops\n\npreds=[]\nimgid=[]\nfor img in tqdm(imgs,total=len(imgs)):\n    pred = ''\n    img_id = ''\n    img_path = testDataDir+img\n    image = read_image_bgr(img_path)\n    boxes, scores, labels = predict(image)\n    boxes=boxes[0]\n    scores=scores[0]\n    img_id += (img.split(\".\")[0])\n    for idx in range(boxes.shape[0]):\n        if scores[idx]>THRES_SCORE:\n            box,score=boxes[idx],scores[idx]\n            pred += f\"{score:.4f} {int(box[0])} {int(box[1])} {int(box[2]-box[0])} {int(box[3]-box[1])} \"\n    preds.append(pred)\n    imgid.append(img_id)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(len(preds))\nprint(len(imgid))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission = {\"image_id\":imgid, \"PredictionString\":preds}\nsubmission = pd.DataFrame(submission)\n#finalsub = submission.groupby([\"image_id\"])['PredictionString'].apply(lambda x: ' '.join(x)).reset_index()\n#finalsub\nsubmission","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission.to_csv('/kaggle/working/submission.csv',index=False)","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}