{"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_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"!apt install ../input/pyturbojpeg/libturbojpeg_1.4.2-0ubuntu3.4_amd64.deb\n!pip install ../input/pyturbojpeg/PyTurboJPEG-1.4.1","metadata":{"_kg_hide-output":true,"execution":{"iopub.status.busy":"2021-05-31T18:15:59.288358Z","iopub.execute_input":"2021-05-31T18:15:59.288749Z","iopub.status.idle":"2021-05-31T18:16:31.360599Z","shell.execute_reply.started":"2021-05-31T18:15:59.288667Z","shell.execute_reply":"2021-05-31T18:16:31.359648Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\n!pip install ../input/wheat-detection/yacs-0.1.7-py3-none-any.whl\n!pip install ../input/wheat-detection/torch-1.5.0cu101-cp37-cp37m-linux_x86_64.whl\n!pip install ../input/wheat-detection/fvcore-0.1.1.post20200716-py3-none-any.whl\n!pip install ../input/wheat-detection/pycocotools-2.0.1-cp37-cp37m-linux_x86_64.whl\n!pip install ../input/wheat-detection/torchvision-0.6.0cu101-cp37-cp37m-linux_x86_64.whl\n!pip install ../input/wheat-detection/detectron2-0.2cu101-cp37-cp37m-linux_x86_64.whl","metadata":{"execution":{"iopub.status.busy":"2021-05-31T18:16:31.364069Z","iopub.execute_input":"2021-05-31T18:16:31.364417Z","iopub.status.idle":"2021-05-31T18:19:50.400990Z","shell.execute_reply.started":"2021-05-31T18:16:31.364363Z","shell.execute_reply":"2021-05-31T18:19:50.400001Z"},"trusted":true},"execution_count":null,"outputs":[]},{"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 math \n\nimport torch\nimport torch.nn as nn\n\nimport cv2\n\nfrom tqdm.notebook import tqdm # Progress Bar \n\nimport os\nimport sys\nsys.path.append(\"../input/efficientnet-pytorch/EfficientNet-PyTorch/EfficientNet-PyTorch-master\")\n","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-05-31T18:19:50.403151Z","iopub.execute_input":"2021-05-31T18:19:50.403540Z","iopub.status.idle":"2021-05-31T18:19:50.944024Z","shell.execute_reply.started":"2021-05-31T18:19:50.403497Z","shell.execute_reply":"2021-05-31T18:19:50.942599Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"label_dic = {\n    0: 'healthy', \n    1: 'scab',\n    2: 'rust',\n    3: 'frog_eye_leaf_spot',\n    4: 'complex', \n    5: 'powdery_mildew'\n}\n\nnum_classes = 6\n\ndevice = torch.device('cuda' if torch.cuda.is_available else 'cpu')","metadata":{"execution":{"iopub.status.busy":"2021-05-31T18:19:50.949834Z","iopub.execute_input":"2021-05-31T18:19:50.950291Z","iopub.status.idle":"2021-05-31T18:19:50.961739Z","shell.execute_reply.started":"2021-05-31T18:19:50.950247Z","shell.execute_reply":"2021-05-31T18:19:50.960575Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from turbojpeg import TurboJPEG\n\njpeg_reader = TurboJPEG()\n\ndef read_img(img):\n    with open(img, \"rb\") as f:\n        return jpeg_reader.decode(f.read(), 0) ","metadata":{"execution":{"iopub.status.busy":"2021-05-31T18:19:50.967464Z","iopub.execute_input":"2021-05-31T18:19:50.970396Z","iopub.status.idle":"2021-05-31T18:19:50.998350Z","shell.execute_reply.started":"2021-05-31T18:19:50.970350Z","shell.execute_reply":"2021-05-31T18:19:50.997329Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def padding_img(img, inp_dim):\n    '''resize image with unchanged aspect ratio using padding'''\n      \n    img_w, img_h = img.shape[1], img.shape[0]\n    w, h = inp_dim\n    new_w = int(img_w * min(w/img_w, h/img_h))\n    new_h = int(img_h * min(w/img_w, h/img_h))\n\n    resized_image = cv2.resize(img, (new_w,new_h), interpolation = cv2.INTER_AREA)#cv2.INTER_CUBIC\n\n    #create a black canvas    \n    canvas = np.full((inp_dim[1], inp_dim[0], 3), 0, dtype=np.uint8)\n \n    #paste the image on the canvas\n    canvas[(h-new_h)//2:(h-new_h)//2 + new_h,(w-new_w)//2:(w-new_w)//2 + new_w,  :] = resized_image\n    \n    \n    return canvas","metadata":{"execution":{"iopub.status.busy":"2021-05-31T18:19:51.002667Z","iopub.execute_input":"2021-05-31T18:19:51.004539Z","iopub.status.idle":"2021-05-31T18:19:51.017552Z","shell.execute_reply.started":"2021-05-31T18:19:51.004498Z","shell.execute_reply":"2021-05-31T18:19:51.014984Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import detectron2\nfrom detectron2 import model_zoo\nfrom detectron2.config import get_cfg\nfrom detectron2.engine import DefaultPredictor\nfrom detectron2.data import MetadataCatalog\nfrom detectron2.utils.visualizer import Visualizer\nfrom detectron2.utils.logger import setup_logger\n\nsetup_logger()\n\n\ndef get_predictor():\n    cfg = get_cfg()\n    cfg.merge_from_file(model_zoo.get_config_file(\"COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_3x.yaml\"))\n    cfg.DATASETS.TRAIN = ()\n    cfg.DATALOADER.NUM_WORKERS = 16\n\n    cfg.MODEL.ROI_HEADS.BATCH_SIZE_PER_IMAGE = (8)  # faster, and good enough for this toy dataset\n    cfg.MODEL.ROI_HEADS.NUM_CLASSES = 2  # 3 classes (data, fig, hazelnut)\n\n    os.makedirs(cfg.OUTPUT_DIR, exist_ok=True)\n    \n    cfg.MODEL.WEIGHTS = \"../input/image-segmentation-using-detectron2/model.pth\"\n    cfg.MODEL.ROI_HEADS.SCORE_THRESH_TEST = 0.7   # set the testing threshold for this model\n    predictor = DefaultPredictor(cfg)\n    return predictor\n\ndef get_cropped_leaf(img,predictor): \n    #get prediction\n    outputs = predictor(img)\n    \n    #get boxes and masks\n    ins = outputs[\"instances\"]\n    pred_masks = ins.get_fields()[\"pred_masks\"]\n    boxes = ins.get_fields()[\"pred_boxes\"]    \n    \n    #get main leaf mask if the area is >= the mean area of boxes and is closes to the centre \n    masker = pred_masks[np.argmin([calculateDistance(x[0], x[1], int(img.shape[1]/2), int(img.shape[0]/2)) for i,x in enumerate(boxes.get_centers()) if (boxes[i].area()>=torch.mean(boxes.area()).to(\"cpu\")).item()])].to(\"cpu\").numpy().astype(np.uint8)\n\n    #mask image\n    mask_out = cv2.bitwise_and(img, img, mask=masker)\n    \n    #find contours and boxes\n    contours, hierarchy = cv2.findContours(masker.copy() ,cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)\n    contour = contours[np.argmax([cv2.contourArea(x) for x in contours])]\n    rotrect = cv2.minAreaRect(contour)\n    box = cv2.boxPoints(rotrect)\n    box = np.int0(box)\n    \n    #crop image\n    resized = get_cropped(rotrect,box,mask_out)\n    \n    return resized\n\n#function to crop the image to boxand rotate\n\ndef get_cropped(rotrect,box,image):\n    \n    width = int(rotrect[1][0])\n    height = int(rotrect[1][1])\n\n    src_pts = box.astype(\"float32\")\n    # corrdinate of the points in box points after the rectangle has been\n    # straightened\n    dst_pts = np.array([[0, height-1],\n                        [0, 0],\n                        [width-1, 0],\n                        [width-1, height-1]], dtype=\"float32\")\n\n    # the perspective transformation matrix\n    M = cv2.getPerspectiveTransform(src_pts, dst_pts)\n\n    # directly warp the rotated rectangle to get the straightened rectangle\n    warped = cv2.warpPerspective(image, M, (width, height))\n    return warped\n\ndef calculateDistance(x1,y1,x2,y2):  \n    dist = math.hypot(x2 - x1, y2 - y1)\n    return dist \n\n","metadata":{"execution":{"iopub.status.busy":"2021-05-31T18:19:51.022304Z","iopub.execute_input":"2021-05-31T18:19:51.022640Z","iopub.status.idle":"2021-05-31T18:19:51.440764Z","shell.execute_reply.started":"2021-05-31T18:19:51.022613Z","shell.execute_reply":"2021-05-31T18:19:51.439919Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"predictor = get_predictor()","metadata":{"execution":{"iopub.status.busy":"2021-05-31T18:19:51.443024Z","iopub.execute_input":"2021-05-31T18:19:51.443405Z","iopub.status.idle":"2021-05-31T18:20:00.139447Z","shell.execute_reply.started":"2021-05-31T18:19:51.443368Z","shell.execute_reply":"2021-05-31T18:20:00.138574Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import albumentations as A\nfrom albumentations.pytorch import ToTensor\n\ndef transform_valid():\n    \n    augmentation_pipeline = A.Compose(\n        [\n            A.Normalize(\n                mean=[0.485, 0.456, 0.406],\n                std=[0.229, 0.224, 0.225]\n                ),\n            ToTensor() \n        ],\n        p = 1\n    )\n    return lambda img:augmentation_pipeline(image=np.array(img))['image']\n\n\ndef transform_vvv():\n    \n    augmentation_pipeline = A.Compose(\n        [\n            A.SmallestMaxSize(224),\n            A.RandomCrop(224, 224),\n        ],\n        p = 1\n    )\n    return lambda img:augmentation_pipeline(image=np.array(img))['image']\n","metadata":{"execution":{"iopub.status.busy":"2021-05-31T18:20:00.140987Z","iopub.execute_input":"2021-05-31T18:20:00.141332Z","iopub.status.idle":"2021-05-31T18:20:01.645584Z","shell.execute_reply.started":"2021-05-31T18:20:00.141294Z","shell.execute_reply":"2021-05-31T18:20:01.644348Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from efficientnet_pytorch import model as enet\n\nmodel = enet.EfficientNet.from_name('efficientnet-b4')\nmodel._fc = nn.Linear(in_features=model._fc.in_features, out_features=num_classes)\nmodel.load_state_dict(torch.load('../input/tmpth/best_model(4).pth'))\n\nmodel = model.to(device)","metadata":{"execution":{"iopub.status.busy":"2021-05-31T18:20:01.646996Z","iopub.execute_input":"2021-05-31T18:20:01.647467Z","iopub.status.idle":"2021-05-31T18:20:03.133586Z","shell.execute_reply.started":"2021-05-31T18:20:01.647428Z","shell.execute_reply":"2021-05-31T18:20:03.132662Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from glob import glob\nvalid_image_list = glob('../input/plant-pathology-2021-fgvc8/test_images/*.jpg')","metadata":{"execution":{"iopub.status.busy":"2021-05-31T18:20:03.134779Z","iopub.execute_input":"2021-05-31T18:20:03.135177Z","iopub.status.idle":"2021-05-31T18:20:03.147537Z","shell.execute_reply.started":"2021-05-31T18:20:03.135068Z","shell.execute_reply":"2021-05-31T18:20:03.146669Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\ndef to_lab(preds):\n    return ((preds > 0) + torch.nn.functional.one_hot(preds.argmax(1), 6) != 0).long()\n\nmodel.eval()\npredict_list = []\nimage_name_list = []\n\nfor i, image in tqdm(enumerate(valid_image_list)) :\n    image_name = image[48:]\n    \n    \n    img = read_img(image)\n    img = padding_img(get_cropped_leaf(img, predictor),(224,224))\n    img = transform_valid()(img)\n    \n    img = img.to(device)\n    img = img.reshape(-1, 3, 224, 224)\n    \n    with torch.set_grad_enabled(False):\n        predict = model(img)\n\n    predict_list.append(list(to_lab(predict).reshape(-1).nonzero(as_tuple=False).reshape(-1).cpu().numpy()))\n    image_name_list.append(image_name)\n    ","metadata":{"execution":{"iopub.status.busy":"2021-05-31T18:20:03.148830Z","iopub.execute_input":"2021-05-31T18:20:03.149429Z","iopub.status.idle":"2021-05-31T18:20:04.509023Z","shell.execute_reply.started":"2021-05-31T18:20:03.149387Z","shell.execute_reply":"2021-05-31T18:20:04.508196Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#predict_list = np.array(predict_list)\nimage_name_list = np.array(image_name_list)\n\nsubmission_df = pd.DataFrame()\nsubmission_df['image'] = image_name_list\nsubmission_df['label_id'] = predict_list\nsubmission_df['labels'] = submission_df['label_id'].apply(lambda x: \" \".join([label_dic[i] for i in x]))\ndel submission_df['label_id']","metadata":{"execution":{"iopub.status.busy":"2021-05-31T18:20:04.510543Z","iopub.execute_input":"2021-05-31T18:20:04.511144Z","iopub.status.idle":"2021-05-31T18:20:04.524578Z","shell.execute_reply.started":"2021-05-31T18:20:04.511030Z","shell.execute_reply":"2021-05-31T18:20:04.523678Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission_df.to_csv(\"submission.csv\", index = False)","metadata":{"execution":{"iopub.status.busy":"2021-05-31T18:20:04.525834Z","iopub.execute_input":"2021-05-31T18:20:04.526391Z","iopub.status.idle":"2021-05-31T18:20:04.747212Z","shell.execute_reply.started":"2021-05-31T18:20:04.526351Z","shell.execute_reply":"2021-05-31T18:20:04.746308Z"},"trusted":true},"execution_count":null,"outputs":[]}]}