{"cells":[{"metadata":{"trusted":true},"cell_type":"code","source":"!pip install /kaggle/input/wheatds/pycocotools-2.0.1/","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!pip uninstall -y tensorflow","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!pip uninstall -y keras","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!pip install -U /kaggle/input/wheatds/tensorboard-1.15.0-py3-none-any.whl","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!pip install -U /kaggle/input/wheatds/tensorflow_estimator-1.15.1-py2.py3-none-any.whl","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!pip install -U /kaggle/input/wheatds/gast-0.2.2/gast-0.2.2","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!pip install -U /kaggle/input/wheatds/astor-0.7.1-py2.py3-none-any.whl","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!pip install -U /kaggle/input/wheatds/Keras_Applications-1.0.8-py3-none-any.whl","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!pip install -U /kaggle/input/wheatds/tensorflow_gpu-1.15.0-cp37-cp37m-manylinux2010_x86_64.whl","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!pip install -U /kaggle/input/wheatds/Keras-2.1.3-py2.py3-none-any.whl","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import os\nos.environ[\"CUDA_VISIBLE_DEVICES\"]=\"0\"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport tensorflow as tf\nfrom sklearn.model_selection import train_test_split\ntf.__version__","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import keras\nkeras.__version__","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from tensorflow.python.client import device_lib\nprint(device_lib.list_local_devices())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# !sudo python3.6 -m pip install pycocotools","execution_count":null,"outputs":[]},{"metadata":{"id":"gIvjtLpYEsqc","trusted":true},"cell_type":"code","source":"from IPython.display import clear_output\n# !git clone https://github.com/matterport/Mask_RCNN.git # load Mask R-CNN code implementation\n# !sudo python3.6 -m pip install pycocotools\n#!rm -rf Mask_RCNN/.git/\n\nclear_output()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# !pip install mask-rcnn-12rics","execution_count":null,"outputs":[]},{"metadata":{"id":"9fsoPKnFFAuU","trusted":true},"cell_type":"code","source":"import os \nimport sys\nfrom tqdm import tqdm\nimport cv2\nimport numpy as np\nimport json\nimport skimage.draw\nimport matplotlib\nimport matplotlib.pyplot as plt\nimport random\n\n# Import COCO config\nIN_DIR = '/kaggle/input/'\nOUT_DIR = '/kaggle/working/'\n\n# # Root directory of the project\nROOT_DIR = os.path.join(IN_DIR, 'maskrcnn/')\n# # Import Mask RCNN\nsys.path.append(ROOT_DIR) \nfrom mrcnn.config import Config\nfrom mrcnn import utils\nfrom mrcnn.model import log\nimport mrcnn.model as modellib\nfrom mrcnn import visualize\n\n\nsys.path.append(os.path.join(IN_DIR, 'wheatds'))\nimport coco\n\nplt.rcParams['figure.facecolor'] = 'white'\n\nclear_output()","execution_count":null,"outputs":[]},{"metadata":{"id":"0nVSAKNRFHBb","trusted":true},"cell_type":"code","source":"def get_ax(rows=1, cols=1, size=7):\n    \"\"\"Return a Matplotlib Axes array to be used in\n    all visualizations in the notebook. Provide a\n    central point to control graph sizes.\n    \n    Change the default size attribute to control the size\n    of rendered images\n    \"\"\"\n    _, ax = plt.subplots(rows, cols, figsize=(size*cols, size*rows))\n    return ax","execution_count":null,"outputs":[]},{"metadata":{"id":"q0DM4dQyFLUL","outputId":"4f66f6e4-5646-4556-e328-8e19229c6e21","trusted":true},"cell_type":"code","source":"MODEL_DIR = OUT_DIR # directory to save logs and trained model\n# ANNOTATIONS_DIR = 'brain-tumor/data/new/annotations/' # directory with annotations for train/val sets\n#DATASET_DIR = 'brain-tumor/data_cleaned/' # directory with image data\nDATASET_DIR = os.path.join(IN_DIR, 'global-wheat-detection') # directory with image data\nDEFAULT_LOGS_DIR = OUT_DIR\n\n# Local path to trained weights file\nMODELDATASET_DIR = os.path.join(IN_DIR, 'wheatds')\nCOCO_MODEL_PATH = os.path.join(MODELDATASET_DIR, \"mask_rcnn_coco.h5\")\n# # Download COCO trained weights from Releases if needed\n# if not os.path.exists(COCO_MODEL_PATH):\n#     utils.download_trained_weights(COCO_MODEL_PATH)","execution_count":null,"outputs":[]},{"metadata":{"id":"gkG7Tl1AFdbT","outputId":"7e61de0f-794e-45c3-d32b-310a1d000c55","trusted":true},"cell_type":"code","source":"class WheatConfig(Config):\n    \"\"\"Configuration for training on the wheat heads dataset.\n    \"\"\"\n    # Give the configuration a recognizable name\n    NAME = 'wheat_detector'\n    GPU_COUNT = 1\n    IMAGES_PER_GPU = 1\n    NUM_CLASSES = 1 + 1  # background + wheat\n    DETECTION_MIN_CONFIDENCE = 0.60\n    STEPS_PER_EPOCH = 2\n    VALIDATION_STEPS = 1\n    LEARNING_RATE = 0.001\n    LOSS_WEIGHTS = {'rpn_class_loss': 1.0, 'rpn_bbox_loss': 1.0, 'mrcnn_class_loss': 1.0, 'mrcnn_bbox_loss': 1.0, 'mrcnn_mask_loss': 0.0}\n\nconfig = WheatConfig()\nconfig.display()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# training dataset\nimport pandas as pd\nanns = pd.read_csv(os.path.join(DATASET_DIR, 'train.csv'))\nanns.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import glob\ndef get_image_fps(dicom_dir):\n    dicom_fps = glob.glob(dicom_dir+'/'+'*.jpg')\n    return list(set(dicom_fps))\n\ndef parse_dataset(dicom_dir, anns): \n    image_fps = get_image_fps(dicom_dir)\n    image_annotations = {fp: [] for fp in image_fps}\n    for index, row in anns.iterrows(): \n        fp = os.path.join(dicom_dir, row['image_id']+'.jpg')\n        iannos = eval(row[3])\n        image_annotations[fp].append(iannos)\n    return image_fps, image_annotations ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_dir = os.path.join(DATASET_DIR, 'train')\nimage_fps, image_annotations = parse_dataset(train_dir, anns=anns)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"image_annotations","execution_count":null,"outputs":[]},{"metadata":{"id":"5IU41vpiFeMR","trusted":true},"cell_type":"code","source":"class WheatDataset(utils.Dataset):\n\n    def load_wheat_scan(self, dataset_dir, img_annotations, orig_height, orig_width, is_train=True):\n        \"\"\"Load a subset of the wheat dataset.\n        dataset_dir: Root directory of the dataset.\n        subset: Subset to load: train or val\n        \"\"\"\n        # Add classes. We have only one class to add.\n        self.add_class(\"wheat\", 1, \"wheat\")\n        i = 0\n        for image_path in img_annotations:\n            i = i + 1\n            #print(image_path.rstrip(r'.jpg').lstrip(r'train/'))\n            # skip all images after 150 if we are building the train set\n            if is_train and int(i) >= 3420:\n                continue\n            # skip all images before 150 if we are building the test/val set\n            if not is_train and int(i) < 3000:\n                continue\n                \n            self.add_image(\n                \"wheat\",\n                image_id=image_path.rstrip(r'.jpg').lstrip(r'train/'),  # use file name as a unique image id\n                path=image_path,\n                annotations=img_annotations[image_path],\n                orig_height=orig_height, orig_width=orig_width\n            )\n\n    def load_mask(self, image_id):\n        info = self.image_info[image_id]\n        annotations = info['annotations']\n        count = len(annotations)\n        if count == 0:\n            mask = np.zeros((info['orig_height'], info['orig_width'], 1), dtype=np.uint8)\n            class_ids = np.zeros((1,), dtype=np.int32)\n        else:\n            mask = np.zeros((info['orig_height'], info['orig_width'], count), dtype=np.uint8)\n            class_ids = np.zeros((count,), dtype=np.int32)\n            for i, a in enumerate(annotations):\n                x = int(a[0])\n                y = int(a[1])\n                w = int(a[2])\n                h = int(a[3])\n                mask_instance = mask[:, :, i].copy()\n                cv2.rectangle(mask_instance, (x, y), (x+w, y+h), 255, -1)\n                mask[:, :, i] = mask_instance\n                class_ids[i] = 1\n        return mask.astype(np.bool), class_ids.astype(np.int32)\n\n    def image_reference(self, image_id):\n        \"\"\"Return the path of the image.\"\"\"\n        info = self.image_info[image_id]\n        if info[\"source\"] == \"wheat\":\n            return info[\"path\"]\n        else:\n            super(self.__class__, self).image_reference(image_id)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"DEFAULT_LOGS_DIR","execution_count":null,"outputs":[]},{"metadata":{"id":"ekiVritIGr37","outputId":"7ecf330e-1dc0-43fd-a702-bb826c96566d","trusted":true},"cell_type":"code","source":"model = modellib.MaskRCNN(\n    mode='training', \n    config=config, \n    model_dir=MODEL_DIR\n)\n\nmodel.load_weights(\n    COCO_MODEL_PATH, \n    by_name=True, \n    exclude=[\"mrcnn_class_logits\", \"mrcnn_bbox_fc\", \"mrcnn_bbox\", \"mrcnn_mask\"]\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import glob\ndef get_image_fps(dicom_dir):\n    dicom_fps = glob.glob(dicom_dir+'/'+'*.jpg')\n    return list(set(dicom_fps))\n\ndef parse_val_dataset(dicom_dir, anns): \n    image_fps = get_image_fps(dicom_dir)\n    image_annotations = {fp: [] for fp in image_fps}\n    for index, row in anns.iterrows(): \n        fp = os.path.join(dicom_dir, row['image_id']+'.jpg')\n        iannos = eval(row[3])\n        if fp in image_annotations:\n            image_annotations[fp].append(iannos)\n    return image_fps, image_annotations ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"val_dir = os.path.join(DATASET_DIR, 'val')\n\nimage_val_fps, image_val_annotations = parse_val_dataset(val_dir, anns=anns)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import warnings\nwarnings.filterwarnings(action='ignore')","execution_count":null,"outputs":[]},{"metadata":{"id":"YSF03kXZGv4h","outputId":"e7c2a3c2-628c-4f92-c66e-09a84d278da3","trusted":true},"cell_type":"code","source":"# Training dataset.\nORIG_SIZE = 1024\ndataset_train = WheatDataset()\ndataset_train.load_wheat_scan('train', image_annotations, ORIG_SIZE, ORIG_SIZE, is_train=True)\ndataset_train.prepare()\n\n# Validation dataset\ndataset_val = WheatDataset()\ndataset_val.load_wheat_scan('train', image_annotations, ORIG_SIZE, ORIG_SIZE, is_train=False)\ndataset_val.prepare()\n\n# dataset_test = WheatDataset()\n# dataset_test.load_brain_scan('test')\n# dataset_test.prepare()\n\n# Since we're using a very small dataset, and starting from\n# COCO trained weights, we don't need to train too long. Also,\n# no need to train all layers, just the heads should do it.\nprint(\"Training network heads\")\nmodel.train(\n    dataset_train, dataset_val,\n    learning_rate=config.LEARNING_RATE,\n    epochs=1,\n    layers='heads'\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import os\nif not os.path.exists('/kaggle/working/wheat_detector'):\n    os.mkdir('/kaggle/working/wheat_detector')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from shutil import copyfile\nsrc = '/kaggle/input/wheatds/mask_rcnn_wheat_detector_0011.h5'\ndst = '/kaggle/working/wheat_detector/mask_rcnn_wheat.h5'\ncopyfile(src, dst)","execution_count":null,"outputs":[]},{"metadata":{"id":"1dyWTI3LSqGv","outputId":"22201cd6-6168-41f2-acd3-c2d297c38dc3","trusted":true},"cell_type":"code","source":"# Recreate the model in inference mode\nmodel = modellib.MaskRCNN(\n    mode=\"inference\", \n    config=config,\n    model_dir=DEFAULT_LOGS_DIR\n)\n\n# Get path to saved weights\n# Either set a specific path or find last trained weights\n# model_path = os.path.join(ROOT_DIR, \".h5 file name here\")\nmodel_path = model.find_last()\n\n# Load trained weights\nprint(\"Loading weights from \", dst)\nmodel.load_weights(dst, by_name=True)","execution_count":null,"outputs":[]},{"metadata":{"id":"UJn52BAONj2s","outputId":"bd8313ca-7f73-446b-d6cb-9142143c970e","trusted":true},"cell_type":"code","source":"def predict_and_plot_differences(dataset, img_id):\n    original_image, image_meta, gt_class_id, gt_box, gt_mask =\\\n        modellib.load_image_gt(dataset, config, \n                               img_id, use_mini_mask=False)\n\n    results = model.detect([original_image], verbose=0)\n    r = results[0]\n\n#     visualize.display_differences(\n#         original_image,\n#         gt_box, gt_class_id, gt_mask,\n#         r['rois'], r['class_ids'], r['scores'], r['masks'],\n#         class_names = ['wheat'], title=\"\", ax=get_ax(),\n#         show_box=True)\n\n\ndef display_image(dataset, ind):\n    plt.figure(figsize=(5,5))\n    plt.imshow(dataset.load_image(ind))\n    plt.xticks([])\n    plt.yticks([])\n    plt.title('Original Image')\n    plt.show()\n\n#vALIDATION SET\nind = 1\ndisplay_image(dataset_val, ind)\npredict_and_plot_differences(dataset_val, ind)\n\nind = 3\ndisplay_image(dataset_val, ind)\npredict_and_plot_differences(dataset_val, ind)\n\n# #Test Set\n# ind = 1\n# display_image(dataset_test, ind)\n# predict_and_plot_differences(dataset_test, ind)\n# ind = 0\n# display_image(dataset_test, ind)\n# predict_and_plot_differences(dataset_test, ind)","execution_count":null,"outputs":[]},{"metadata":{"id":"_DDSdmdHTLpm","trusted":true},"cell_type":"code","source":"# Get filenames of test dataset DICOM images\ntest_dir = os.path.join(DATASET_DIR, 'test')\ntest_image_fps = get_image_fps(test_dir)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from PIL import Image\n#from matplotlib import image\nfrom mrcnn.visualize import display_instances\n\n# Make predictions on test images, write out sample submission\ndef predict(image_fps, filepath='submission.csv', min_conf=0.98):\n    # assume square image\n    resize_factor = ORIG_SIZE / config.IMAGE_SHAPE[0]\n    #resize_factor = ORIG_SIZE\n    with open(filepath, 'w') as file:\n        file.write(\"image_id,PredictionString\\n\")\n\n        for image_id in tqdm(image_fps):\n            ds = Image.open(image_id)\n            image = np.asarray(ds)\n            \n            #ds = pydicom.read_file(image_id)\n            #image = ds.pixel_array\n            # If grayscale. Convert to RGB for consistency.\n            if len(image.shape) != 3 or image.shape[2] != 3:\n                image = np.stack((image,) * 3, -1)\n            image, window, scale, padding, crop = utils.resize_image(\n                image,\n                min_dim=config.IMAGE_MIN_DIM,\n                min_scale=config.IMAGE_MIN_SCALE,\n                max_dim=config.IMAGE_MAX_DIM,\n                mode=config.IMAGE_RESIZE_MODE)\n\n            new_image_id = os.path.splitext(os.path.basename(image_id))[0]\n\n            results = model.detect([image])\n            r = results[0]\n\n            #display_instances(image, r['rois'], r['masks'], r['class_ids'], ['background', 'wheathead'], r['scores'])\n            out_str = \"\"\n            out_str += new_image_id\n            out_str += \",\"\n            assert( len(r['rois']) == len(r['class_ids']) == len(r['scores']) )\n            if len(r['rois']) == 0:\n                pass\n            else:\n                num_instances = len(r['rois'])\n\n                for i in range(num_instances):\n                    if r['scores'][i] > min_conf:\n                        out_str += ' '\n                        out_str += str(round(r['scores'][i], 2))\n                        out_str += ' '\n\n                        # x1, y1, width, height\n                        x1 = r['rois'][i][1]\n                        y1 = r['rois'][i][0]\n                        width = r['rois'][i][3] - x1\n                        height = r['rois'][i][2] - y1\n                        bboxes_str = \"{} {} {} {}\".format(int(x1*resize_factor), int(y1*resize_factor), \\\n                                                           int(width*resize_factor), int(height*resize_factor))\n                        out_str += bboxes_str\n\n            file.write(out_str+\"\\n\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission_fp = os.path.join(OUT_DIR, 'submission.csv')\npredict(test_image_fps, filepath=submission_fp, min_conf=0.60)\nprint(submission_fp)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_submission = pd.read_csv(submission_fp)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_submission.head(10)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_submission.replace(np.nan, '', inplace=True)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sub_dict = df_submission.set_index('image_id').to_dict()['PredictionString']\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_submission['PredictionString'] = df_submission['image_id'].apply(lambda x: sub_dict[x].strip())\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_submission.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_submission.to_csv(submission_fp, 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}