{"cells":[{"metadata":{"trusted":true},"cell_type":"code","source":"import numpy as np \nimport pandas as pd\nimport os\nimport sys\nimport json\nimport cv2\nimport time\nimport glob\nimport tensorflow as tf\nfrom tensorflow.keras.optimizers import Adam","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df = pd.read_csv('/kaggle/input/global-wheat-detection/train.csv')\ndf.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df['bbox'] = df['bbox'].apply(lambda x: x[1:-1].split(\",\"))\ndf['x'] = df['bbox'].apply(lambda x: x[0]).astype('float32')\ndf['y'] = df['bbox'].apply(lambda x: x[1]).astype('float32')\ndf['w'] = df['bbox'].apply(lambda x: x[2]).astype('float32')\ndf['h'] = df['bbox'].apply(lambda x: x[3]).astype('float32')\ndf = df[['image_id','x', 'y', 'w', 'h']]\n\ndf.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"image_ids = df['image_id'].unique()\nimage_dict = dict(zip(image_ids, range(len(image_ids))))\nlen(image_dict)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"json_dict = {\"images\": [], \"type\": \"instances\", \"annotations\": [], \"categories\": []}","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for image_id in image_ids:\n    image = {'file_name': image_id + '.jpg', \n             'height': 1024, \n             'width': 1024, \n             'id': image_dict[image_id]}\n    json_dict['images'].append(image)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"categories = {'supercategory': 'wh', 'id': 1, 'name': 'wh'}\njson_dict['categories'].append(categories)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for idx, box_id in df.iterrows(): \n    image_id = image_dict[box_id['image_id']]\n    \n    ann = {'area': box_id['w'] * box_id['h'], \n           'iscrowd': 0, \n           'image_id': image_id,                        \n           'bbox': [box_id['x'], box_id['y'], box_id['w'], box_id['h']],\n           'category_id': 1, \n           'id': idx,\n           'segmentation': []}\n\n    json_dict['annotations'].append(ann)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class NpEncoder(json.JSONEncoder):\n    def default(self, obj):\n        if isinstance(obj, np.integer):\n            return int(obj)\n        elif isinstance(obj, np.floating):\n            return float(obj)\n        elif isinstance(obj, np.ndarray):\n            return obj.tolist()\n        else:\n            return super(NpEncoder, self).default(obj)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"annFile='instances_Images.json'\n\njson_fp = open(annFile, 'w',encoding='utf-8')\njson_str = json.dumps(json_dict,cls=NpEncoder)\njson_fp.write(json_str)\njson_fp.close()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!git clone https://github.com/kamauz/EfficientDet.git","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"cd /kaggle/working/EfficientDet/","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":"from model import efficientdet\nfrom losses import smooth_l1, focal\nfrom efficientnet import BASE_WEIGHTS_PATH, WEIGHTS_HASHES\nfrom generators.common import Generator","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!pip install -U 'git+https://github.com/cocodataset/cocoapi.git#subdirectory=PythonAPI' -q\n\nfrom pycocotools.coco import COCO","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def preprocess_image(image):\n    image = image.astype(np.float32)\n    image /= 255.\n    mean = [0.485, 0.456, 0.406]\n    std = [0.229, 0.224, 0.225]\n    image -= mean\n    image /= std\n\n    return image","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def postprocess_boxes(boxes, height, width):\n    c_boxes = boxes.copy()\n    c_boxes[:, 0] = np.clip(c_boxes[:, 0], 0, width - 1)\n    c_boxes[:, 1] = np.clip(c_boxes[:, 1], 0, height - 1)\n    c_boxes[:, 2] = np.clip(c_boxes[:, 2], 0, width - 1)\n    c_boxes[:, 3] = np.clip(c_boxes[:, 3], 0, height - 1)\n    return c_boxes","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class CocoGenerator(Generator):\n    def __init__(self, data_dir, set_name, **kwargs):                                    \n        self.coco = COCO('/kaggle/working/instances_Images.json')                \n        self.image_ids = self.coco.getImgIds()\n        self.load_classes()\n\n        super(CocoGenerator, self).__init__(**kwargs)\n\n    def load_classes(self): \n        categories = self.coco.loadCats(self.coco.getCatIds())\n        categories.sort(key=lambda x: x['id'])\n\n        self.classes = {}\n        self.coco_labels = {}\n        self.coco_labels_inverse = {}\n        for c in categories:\n            self.coco_labels[len(self.classes)] = c['id']\n            self.coco_labels_inverse[c['id']] = len(self.classes)\n            self.classes[c['name']] = len(self.classes)\n\n        self.labels = {}\n        for key, value in self.classes.items():\n            self.labels[value] = key\n\n    def size(self):\n        return len(self.image_ids)\n\n    def num_classes(self):\n        return 1\n\n    def has_label(self, label):\n        return label in self.labels\n\n    def has_name(self, name):\n        return name in self.classes\n\n    def name_to_label(self, name):\n        return self.classes[name]\n\n    def label_to_name(self, label):\n        return self.labels[label]\n\n    def coco_label_to_label(self, coco_label):\n        return self.coco_labels_inverse[coco_label]\n\n    def coco_label_to_name(self, coco_label):\n        return self.label_to_name(self.coco_label_to_label(coco_label))\n\n    def label_to_coco_label(self, label):\n        return self.coco_labels[label]\n\n    def image_aspect_ratio(self, image_index):\n        image = self.coco.loadImgs(self.image_ids[image_index])[0]\n        return float(image['width']) / float(image['height'])\n\n    def load_image(self, image_index):        \n        image_info = self.coco.loadImgs(self.image_ids[image_index])[0]        \n        path = os.path.join('/kaggle/input/global-wheat-detection/train/', image_info['file_name'])        \n        image = cv2.imread(path)\n        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n        \n        image = preprocess_image(image)\n        \n        return image\n\n    def load_annotations(self, image_index):\n        annotations_ids = self.coco.getAnnIds(imgIds=self.image_ids[image_index], iscrowd=False)\n        annotations = {'labels': np.empty((0,), dtype=np.float32), 'bboxes': np.empty((0, 4), dtype=np.float32)}\n\n        if len(annotations_ids) == 0:\n            return annotations\n\n        coco_annotations = self.coco.loadAnns(annotations_ids)\n        for idx, a in enumerate(coco_annotations):\n            # some annotations have basically no width / height, skip them\n            if a['bbox'][2] < 1 or a['bbox'][3] < 1:\n                continue\n\n            annotations['labels'] = np.concatenate(\n                [annotations['labels'], [a['category_id'] - 1]], axis=0)\n            annotations['bboxes'] = np.concatenate([annotations['bboxes'], [[\n                a['bbox'][0],\n                a['bbox'][1],\n                a['bbox'][0] + a['bbox'][2],\n                a['bbox'][1] + a['bbox'][3],\n            ]]], axis=0)           \n\n        return annotations    ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"phi = 4\nscore_threshold=0.4","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_generator = CocoGenerator(data_dir=None, set_name=None, batch_size = 4, phi = phi)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model, prediction_model = efficientdet(phi,\n                                       num_classes=1,\n                                       weighted_bifpn=True,\n                                       freeze_bn=True,\n                                       score_threshold=score_threshold\n                                       )","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model_name = 'efficientnet-b{}'.format(phi)\nfile_name = '{}_weights_tf_dim_ordering_tf_kernels_autoaugment_notop.h5'.format(model_name)\nfile_hash = WEIGHTS_HASHES[model_name][1]\nweights_path = tf.keras.utils.get_file(file_name,\n                                    BASE_WEIGHTS_PATH + file_name,\n                                    cache_subdir='models',\n                                    file_hash=file_hash)\nmodel.load_weights(weights_path, by_name=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for i in range(1, [227, 329, 329, 374, 464, 566, 656][phi]):\n    model.layers[i].trainable = False","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.compile(optimizer=Adam(lr=1e-3), loss={\n    'regression': smooth_l1(),\n    'classification': focal()\n}, )","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"%%time\n\nmodel.fit_generator(\n        generator=train_generator,\n        epochs=1\n    )","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"cd /kaggle/working/","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.save('model.h5')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### TEST","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"prediction_model.load_weights('/kaggle/working/model.h5', by_name=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"score_threshold = 0.7\nresult_data = []\nfor image_path in glob.glob('/kaggle/input/global-wheat-detection/test/53f253011.jpg'):\n    image_name = image_path.split('/')[-1]\n    image = cv2.imread(image_path)\n    src_image = image.copy()\n    # BGR -> RGB\n    image = image[:, :, ::-1]\n    h, w = image.shape[:2]\n\n    image = preprocess_image(image)               \n    boxes, scores, labels = prediction_model.predict_on_batch([np.expand_dims(image, axis=0)])\n    boxes, scores, labels = np.squeeze(boxes), np.squeeze(scores), np.squeeze(labels)    \n    boxes = postprocess_boxes(boxes=boxes, height=h, width=w)\n\n    indices = np.where(scores[:] > score_threshold)[0]\n    boxes = boxes[indices]    \n    row = [image_name.replace('.jpg','')]\n    r_boxes = \"\"\n    for s,b in zip(scores, boxes):\n        if r_boxes != \"\":\n            r_boxes += \" \"\n        r_boxes += f\"{round(float(s),2)} {int(b[0])} {int(b[1])} {int(b[2]-b[0])} {int(b[3]-b[1])}\"\n    \n    row.append(r_boxes)\n    result_data.append(row)\ntest_df = pd.DataFrame(result_data, columns=['image_id','PredictionString'])\ntest_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from matplotlib import pyplot as plt\n\ndef chunks(lst, n):\n    for i in range(0, len(lst), n):\n        yield lst[i:i + n]\n\nname = '53f253011'        \n        \ntest_df['PredictionString'] = test_df['PredictionString'].apply(lambda a: a.split(' ')).apply(lambda myList: [x for i, x in enumerate(myList) if i%5 !=0])\nlst1 = test_df[test_df['image_id'] == name]['PredictionString'].values[0]\nlst1 = list(map(int, lst1))     \nlst1_n = list(chunks(lst1, 4))\n\nsample = plt.imread('/kaggle/input/global-wheat-detection/test/' + name + '.jpg')\n\nfig, ax = plt.subplots(1, 1, figsize=(16, 8))\nfor box in lst1_n:\n    cv2.rectangle(sample,\n                  (box[0], box[1]),\n                  (box[2] + box[0], box[3] + box[1]),\n                  (0, 0, 100), 2)\n  \nax.set_axis_off()\nax.imshow(sample)\n","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}