{"cells":[{"metadata":{},"cell_type":"markdown","source":"# Install Packages"},{"metadata":{"trusted":true},"cell_type":"code","source":"!ls ../input/global-wheat-detection/test","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!pip install '../input/detectron2-wheat/pycocotools-2.0.0-cp37-cp37m-linux_x86_64.whl'\n!pip install '../input/detectron2-wheat/yacs-0.1.7-py3-none-any.whl'\n!pip install '../input/detectron2-wheat/fvcore-0.1.1.post200513-py3-none-any.whl'\n!pip install '../input/detectron2-wheat/detectron2-0.1.2cu101-cp37-cp37m-linux_x86_64.whl'","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# import common utilities\nfrom contextlib import contextmanager\nimport cv2\nimport glob\nfrom itertools import groupby\nimport json\nimport matplotlib.pyplot as plt\nimport random\nimport numpy as np\nimport os\nimport pandas as pd\nimport re\nimport sys","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import detectron2\nfrom detectron2.utils.logger import setup_logger\nsetup_logger()\nfrom detectron2.structures import BoxMode\nfrom detectron2.engine import DefaultPredictor\nfrom detectron2.config import get_cfg\nfrom detectron2.utils.visualizer import Visualizer\nfrom detectron2.data import MetadataCatalog\nfrom detectron2.data import MetadataCatalog, DatasetCatalog","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Prepare Kaggle Wheat Competition Dataset"},{"metadata":{"trusted":true},"cell_type":"code","source":"i = glob.glob('/kaggle/input/global-wheat-detection/train/*.jpg')\nprint('number of train images: {}'.format(len(i)))\n# print('train images: {}'.format(i))\n\ni = glob.glob('/kaggle/input/global-wheat-detection/test/*.jpg')\nprint('number of test images: {}'.format(len(i)))\n# print('test images: {}'.format(i))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df = pd.read_csv('/kaggle/input/global-wheat-detection/train.csv')\n# print(df)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"wheat_list = df.to_dict('records')\nprint('number of label records: {}'.format(len(wheat_list)))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"images = [wheat['image_id'] for wheat in wheat_list]\nimages = list(dict.fromkeys(images))\nprint('number of wheat images: {}'.format(len(images)))\n\nimage_name2id = {}\nfor i, img in enumerate(images):\n    # print(i, img)\n    image_name2id[img] = i + 1\n# print('Image Name to ID mapping: {}'.format(image_name2id))\n\nimage_id2name = {}\nfor i, img in enumerate(images):\n    # print(i, img)\n    image_id2name[i+1] = img\n# print('Classes ID to Name mapping: {}'.format(image_id2name))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"wheat_classes = [wheat['source'] for wheat in wheat_list]\nwheat_classes = list(dict.fromkeys(wheat_classes))\nwheat_classes.sort()\nprint('wheat classes: {}'.format(wheat_classes))\n\nnum_classes = len(wheat_classes)\nprint('num of classes: {}'.format(num_classes))\n\nclass_name2id = {}\nfor i, c in enumerate(wheat_classes):\n    # print(i, c)\n    class_name2id[c] = i + 1\nprint('Classes Name to ID mapping: {}'.format(class_name2id))\n\nclass_id2name = {}\nfor i, c in enumerate(wheat_classes):\n    # print(i, c)\n    class_id2name[i+1] = c\nprint('Classes ID to Name mapping: {}'.format(class_id2name))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"wheat_dicts = {}\nfor idx, wheat in enumerate(wheat_list):\n    if not wheat['image_id'] in wheat_dicts:\n        image_id = wheat['image_id']\n        wheat_dicts[image_id] = {}\n        wheat_dicts[image_id]['file_name'] = os.path.join('./train', wheat['image_id']+'.jpg')\n        wheat_dicts[image_id]['image_id'] = image_name2id[wheat['image_id']]\n        wheat_dicts[image_id]['height'] = wheat['height']\n        wheat_dicts[image_id]['width'] = wheat['width']\n        wheat_dicts[image_id]['annotations'] = []\n        ann = {}\n        regex = re.compile(r'\\[(\\d*\\.?\\d*), (\\d*\\.?\\d*), (\\d*\\.?\\d*), (\\d*\\.?\\d*)\\]')\n        match = regex.search(wheat['bbox'])\n        ann['bbox'] = [float(match.group(1)), float(match.group(2)), float(match.group(3)), float(match.group(4))]\n        ann['bbox_mode'] = BoxMode.XYWH_ABS\n        ann['segmentation'] = []\n        ann['category_id'] = class_name2id[wheat['source']]\n        ann['id'] = idx + 1\n        wheat_dicts[image_id]['annotations'].append(ann)\n    else:\n        ann = {}\n        regex = re.compile(r'\\[(\\d*\\.?\\d*), (\\d*\\.?\\d*), (\\d*\\.?\\d*), (\\d*\\.?\\d*)\\]')\n        match = regex.search(wheat['bbox'])\n        ann['bbox'] = [float(match.group(1)), float(match.group(2)), float(match.group(3)), float(match.group(4))]\n        ann['bbox_mode'] = BoxMode.XYWH_ABS\n        ann['segmentation'] = []\n        ann['category_id'] = class_name2id[wheat['source']]\n        ann['id'] = idx + 1\n        wheat_dicts[image_id]['annotations'].append(ann)\n\nprint(len(wheat_dicts))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"temp_dir = './temp'\nos.makedirs(temp_dir, exist_ok=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# if your dataset is in COCO format, this cell can be replaced by the following three lines:\n# from detectron2.data.datasets import register_coco_instances\n# register_coco_instances(\"my_dataset_train\", {}, \"json_annotation_train.json\", \"path/to/image/dir\")\n# register_coco_instances(\"my_dataset_val\", {}, \"json_annotation_val.json\", \"path/to/image/dir\")\n\ndef get_wheat_dicts(wheat_dicts, mode='train'):\n\n    dataset_dicts = []\n\n    train_valid_split = 5\n    for idx, wheat in enumerate(wheat_dicts):\n        if mode == 'train' and (idx % train_valid_split) == 0:\n            continue\n        if mode == 'valid' and not (idx % train_valid_split) == 0:\n            continue\n\n        dataset_dicts.append(wheat_dicts[wheat])\n\n    print('mode: {}, number of samples: {}'.format(mode, len(dataset_dicts)))\n    return dataset_dicts","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_dataset_dicts = get_wheat_dicts(wheat_dicts, 'train')\n# print(train_dataset_dicts[0:10])\n\ntrain_dataset_coco_dicts = {}\ntrain_dataset_coco_dicts['annotations'] = [{'segmentation':[\n                        [ann['bbox'][0], ann['bbox'][1],\n                        ann['bbox'][0]+ann['bbox'][2], ann['bbox'][1],\n                        ann['bbox'][0]+ann['bbox'][2], ann['bbox'][1]+ann['bbox'][3],\n                        ann['bbox'][0], ann['bbox'][1]+ann['bbox'][3]]\n           ],\n           'area':ann['bbox'][2]*ann['bbox'][3],\n           'iscrowd':0,\n           'image_id':img['image_id'],\n           'bbox':ann['bbox'],\n           'category_id':ann['category_id'],\n           'id': ann['id']}\n           for img in train_dataset_dicts\n           for ann in img['annotations']]\ntrain_dataset_coco_dicts['images'] = [{'file_name':img['file_name'], 'id':img['image_id'], 'height':img['height'], 'width':img['width']} for img in train_dataset_dicts]\ntrain_dataset_coco_dicts['categories'] = [{'supercategory':c, 'name':c, 'id':class_name2id[c]} for c in wheat_classes]\n\nwith open(os.path.join(temp_dir, 'wheat_train_coco.json'), 'w') as outfile:\n    json.dump(train_dataset_coco_dicts, outfile)\noutfile.close()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"valid_dataset_dicts = get_wheat_dicts(wheat_dicts, 'valid')\n# print(valid_dataset_dicts[0:10])\n\nvalid_dataset_coco_dicts = {}\nvalid_dataset_coco_dicts['annotations'] = [{'segmentation':[\n                        [ann['bbox'][0], ann['bbox'][1],\n                        ann['bbox'][0]+ann['bbox'][2], ann['bbox'][1],\n                        ann['bbox'][0]+ann['bbox'][2], ann['bbox'][1]+ann['bbox'][3],\n                        ann['bbox'][0], ann['bbox'][1]+ann['bbox'][3]]\n           ],\n           'area':ann['bbox'][2]*ann['bbox'][3],\n           'iscrowd':0,\n           'image_id':img['image_id'],\n           'bbox':ann['bbox'],\n           'category_id':ann['category_id'],\n           'id': ann['id']}\n           for img in valid_dataset_dicts\n           for ann in img['annotations']]\nvalid_dataset_coco_dicts['images'] = [{'file_name':img['file_name'], 'id':img['image_id'], 'height':img['height'], 'width':img['width']} for img in valid_dataset_dicts]\nvalid_dataset_coco_dicts['categories'] = [{'supercategory':c, 'name':c, 'id':class_name2id[c]} for c in wheat_classes]\n\nwith open(os.path.join(temp_dir, 'wheat_valid_coco.json'), 'w') as outfile:\n    json.dump(valid_dataset_coco_dicts, outfile)\noutfile.close()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"DatasetCatalog.clear()\nfrom detectron2.data.datasets import register_coco_instances\n\nregister_coco_instances('wheat_train', {}, 'wheat_train_coco.json', temp_dir)\nregister_coco_instances('wheat_valid', {}, 'wheat_valid_coco.json', temp_dir)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!rm ./temp/wheat_train_coco.json\n!rm ./temp/wheat_valid_coco.json","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Prepare Config & Model"},{"metadata":{"trusted":true},"cell_type":"code","source":"model_selections = {}\nmodel_selections = {\n    1: {'depth': 50, 'num_classes': 7, 'model': '../input/detectron2-model/model_depth50_0299999.pth'},\n    2: {'depth': 101, 'num_classes': 7,  'model': '../input/detectron2-model/model_depth101_0269999.pth'},\n    3: {'depth': 101, 'num_classes': 1,  'model': '../input/detectron2-model/model_101_preod_1c_0026999.pth'},\n    4: {'depth': 101, 'num_classes': 7,  'model': '../input/detectron2-model/model_101_preod_7c_0096999.pth'},\n    5: {'depth': 101, 'num_classes': 1,  'model': '../input/detectron2-model/depth101_pre_1c_od_0086999.pth'},\n    6: {'depth': 101, 'num_classes': 1,  'model': '../input/detectron2-model/depth101_pre_1c_od_0205999.pth'},\n    7: {'depth': 101, 'num_classes': 1,  'model': '../input/detectron2-model/depth101_pre_1c_od_AdamP_0056999.pth'},\n    60: {'depth': 101, 'num_classes': 1,  'model': '../input/detectron2-model/model_101_preod_1c_0026999_plr0.pth'},\n    61: {'depth': 101, 'num_classes': 1,  'model': '../input/detectron2-model/model_101_preod_1c_0026999_plr1.pth'},\n    62: {'depth': 101, 'num_classes': 1,  'model': '../input/detectron2-model/model_101_preod_1c_0026999_plr2.pth'},\n    63: {'depth': 101, 'num_classes': 1,  'model': '../input/detectron2-model/model_101_preod_1c_0026999_plr3.pth'},\n    64: {'depth': 101, 'num_classes': 1,  'model': '../input/detectron2-model/model_101_preod_1c_0026999_plr4.pth'},\n    65: {'depth': 101, 'num_classes': 1,  'model': '../input/detectron2-model/model_101_preod_1c_0026999_plr5.pth'},\n    66: {'depth': 101, 'num_classes': 1,  'model': '../input/detectron2-model/model_101_preod_1c_0026999_plr6.pth'},\n    67: {'depth': 101, 'num_classes': 1,  'model': '../input/detectron2-model/model_101_preod_1c_0026999_plr7.pth'},\n    68: {'depth': 101, 'num_classes': 1,  'model': '../input/detectron2-model/model_101_preod_1c_0026999_plr8.pth'},\n    69: {'depth': 101, 'num_classes': 1,  'model': '../input/detectron2-model/model_101_preod_1c_0026999_plr9.pth'},\n    601: {'depth': 101, 'num_classes': 1,  'model': '../input/detectron2-model/model_101_preod_1c_0026999_plall_r1.pth'},\n    610: {'depth': 101, 'num_classes': 1,  'model': '../input/detectron2-model/model_101_preod_1c_0026999_plall_r10.pth'},\n    }\nmodel_sel = model_selections[7]\nprint(model_sel)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"cfg = get_cfg()\n# cfg.OUTPUT_DIR = '/content/drive/MyDrive/NCTU/基於深度學習之視覺辨識專論/HW/Final/output1'\n# cfg.MODEL.DEVICE = 'cpu'\ncfg.OUTPUT_DIR = './'\n# cfg.merge_from_file(model_zoo.get_config_file(\"COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_3x.yaml\"))\ncfg.merge_from_file('../input/detectron2-base-yaml/BASE.yaml')\n\ncfg.MODEL.MASK_ON = True\ncfg.MODEL.RESNETS.DEPTH = model_sel['depth']\ncfg.MODEL.WEIGHTS = model_sel['model']  # path to the model we just trained\n\ncfg.DATASETS.TRAIN = ('wheat_train',)\ncfg.DATASETS.TEST = ('wheat_valid',)\ncfg.TEST.EVAL_PERIOD = 2000\ncfg.SOLVER.CHECKPOINT_PERIOD = 1000\ncfg.DATALOADER.NUM_WORKERS = 2\n# cfg.MODEL.WEIGHTS = model_zoo.get_checkpoint_url(\"COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_3x.yaml\")  # Let training initialize from model zoo\ncfg.SOLVER.IMS_PER_BATCH = 2\ncfg.SOLVER.BASE_LR = 0.0000025  # 0.00025: 0~12999; 0.0001: 13000~\ncfg.SOLVER.MAX_ITER = 300000  # 300 iterations seems good enough for this toy dataset; you will need to train longer for a practical dataset\ncfg.SOLVER.GAMMA = 0.5\n# cfg.SOLVER.STEPS = (60000,100000,210000,250000) 0.5 gamma\ncfg.SOLVER.STEPS = (30000,)\n# cfg.SOLVER.LR_SCHEDULER_NAME = WarmupMultiStepLR\ncfg.MODEL.SEM_SEG_HEAD.NUM_CLASSES = 0\ncfg.MODEL.ROI_HEADS.BATCH_SIZE_PER_IMAGE = 512\ncfg.MODEL.ROI_HEADS.NUM_CLASSES = model_sel['num_classes']  # only has one class (ballon). (see https://detectron2.readthedocs.io/tutorials/datasets.html#update-the-config-for-new-datasets)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(cfg)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# 0.7=55, 0.3=60, 0.1=57, 0=26\ncfg.MODEL.ROI_HEADS.SCORE_THRESH_TEST = 0.2   # set a custom testing threshold\ncfg.MODEL.ROI_HEADS.NMS_THRESH_TEST = 0.45\n\npredictor = DefaultPredictor(cfg)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Predict"},{"metadata":{"trusted":true},"cell_type":"code","source":"def bbox_adjust_ddd(bbox, input_format, output_format, adjust_momde, adjust_value):\n    \n    bbox = bbox.tolist()\n    if input_format == 'XYXY':\n        xmin = round(bbox[0])\n        ymin = round(bbox[1])\n        width = round(bbox[2] - bbox[0])\n        height = round(bbox[3] - bbox[1])\n    elif input_format == 'XYWH':\n        xmin = round(bbox[0])\n        ymin = round(bbox[1])\n        width = round(bbox[2])\n        height = round(bbox[3])\n    \n    if adjust_momde == 'PERCENTAGE':\n        xmin += round(width * adjust_value)\n        ymin += round(height * adjust_value)\n        width -= round(width * adjust_value * 2)\n        height -= round(height * adjust_value * 2)\n    elif adjust_momde == 'PIXEL':\n        xmin += adjust_value\n        ymin += adjust_value\n        width -= adjust_value * 2\n        height -= adjust_value * 2\n    elif adjust_momde == 'SHIFT':\n        xmin += adjust_value\n        ymin += adjust_value\n\n    if output_format == 'XYXY':\n        return [xmin, ymin, xmin+width, ymin+height]\n    elif output_format == 'XYWH':\n        return [xmin, ymin, width, height]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def bbox_adjust(bbox, input_format, output_format, adjust_momde, adjust_value):\n    \n    bbox = bbox.tolist()\n    if input_format == 'XYXY':\n        xmin = (bbox[0])\n        ymin = (bbox[1])\n        width = (bbox[2] - bbox[0])\n        height = (bbox[3] - bbox[1])\n    elif input_format == 'XYWH':\n        xmin = (bbox[0])\n        ymin = (bbox[1])\n        width = (bbox[2])\n        height = (bbox[3])\n    \n    if adjust_momde == 'PERCENTAGE':\n        xmin += (width * adjust_value)\n        ymin += (height * adjust_value)\n        width -= (width * adjust_value * 2)\n        height -= (height * adjust_value * 2)\n    elif adjust_momde == 'PIXEL':\n        xmin += adjust_value\n        ymin += adjust_value\n        width -= adjust_value * 2\n        height -= adjust_value * 2\n    elif adjust_momde == 'SHIFT':\n        xmin += adjust_value\n        ymin += adjust_value\n\n    if output_format == 'XYXY':\n        return [xmin, ymin, xmin+width, ymin+height]\n    elif output_format == 'XYWH':\n        return [xmin, ymin, width, height]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"testfiles = [f for f in os.listdir('/kaggle/input/global-wheat-detection/test') if os.path.isfile(os.path.join('/kaggle/input/global-wheat-detection/test', f))]\n# print(testfiles)\n\nfilenames = []\npredicts = []\n\nfor idx, f in enumerate(testfiles):\n    # print('image filename: {}'.format(f))\n    print('{} {}'.format(idx, os.path.join('/kaggle/input/global-wheat-detection/test', f)))\n    image = cv2.imread(os.path.join('/kaggle/input/global-wheat-detection/test', f))\n\n    outputs = predictor(image)\n\n    result = {}\n\n    # result['image_id'] = f['id']\n    result['image_id'] = os.path.splitext(f)[0]\n    # result['score'] = [[round(i.tolist(),2)] for i in outputs['instances'].scores]\n    result['score'] = [[0.9] for i in outputs['instances'].scores]\n    result['category_id'] = [cate_id.numpy()+1 for cate_id in outputs[\"instances\"].pred_classes.to('cpu')]\n    result['bbox'] = [bbox_adjust(bbox, 'XYXY', 'XYWH', '', 0) for bbox in outputs[\"instances\"].pred_boxes]\n    # bbox_adjust(bbox, 'XYXY', 'XYWH', 'PERCENTAGE', 0.05)\n    print(result)\n    \n    pred = []\n    n_instances = len(outputs['instances'].scores)\n    print(n_instances)\n    for i in range(n_instances):  # Loop all instances\n        # save information of the instance in a dictionary then append on coco_dt list\n        pred.extend(result['score'][i])\n        pred.extend(result['bbox'][i])\n\n    filenames.append(result['image_id'])\n    predicts.append(pred)\n    print(pred)\n\nprint('filename list: {}'.format(filenames))\n# print('predict list: {}'.format(predicts))\npredicts = [' '.join(str(p) for p in pred) for pred in predicts]\nprint('predict list: {}'.format(predicts))\n\nsubmission_dict = {\n    'image_id': filenames,\n    'PredictionString': predicts\n}\nsubmission = pd.DataFrame(submission_dict)\n# submission.to_csv(os.path.join(cfg.OUTPUT_DIR, 'submission.csv'), encoding = 'utf-8',index = False)\n\n# submission.to_json(os.path.join('./', 'submission.json'), index = False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission.head","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission.to_csv('submission.csv', index = False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# !cp ../input/test-submission/submission.csv ./","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}