{"cells":[{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"!cp -r ../input/yolomodel/* .","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from utils.datasets import *\nfrom utils.utils import *\nfrom models.experimental import *\nimport sys\nsys.path.insert(0, \"../input/weightedboxesfusion\")\nfrom ensemble_boxes import *\nimport torch\nimport glob\nimport pandas as pd","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"weights = [\"../input/40efolds/best48fold0.pt\", \"../input/40efolds/best48fold1.pt\", \"../input/40efolds/best48fold2.pt\",  \"../input/40efolds/best48fold3.pt\", \"../input/40efolds/best40fold4.pt\"]\nprint(len(weights))\nsource = \"../input/global-wheat-detection/test\"\nimgsz = 1024\nbuilt_in_tta = True\n\ndevice = torch_utils.select_device(\"0\" if torch.cuda.is_available() else \"\")\n#If using CUDA, we can use half-floats\nhalf = device.type != 'cpu'  # half precision only supported on CUDA","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"skip_box_thr = 0.2\niou_thr = 0.57 #current best 0.55<0.6\nscore_thr = 0.2\ndef run_wbf(boxes,scores, image_size=1024, iou_thr=0.4, skip_box_thr=0.34, weights=None):\n    labels0 = [np.ones(len(scores[idx])) for idx in range(len(scores))]\n    boxes, scores, labels = weighted_boxes_fusion(boxes, scores, labels0, weights=None, iou_thr=iou_thr, skip_box_thr=skip_box_thr)\n    return boxes, scores","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def TTAImage(image, index):\n    image1 = image.copy()\n    if index==0:  #rotate once\n        rotated_image = cv2.rotate(image1, cv2.ROTATE_90_CLOCKWISE)\n        return rotated_image\n    elif index==1: #rotate twice\n        rotated_image2 = cv2.rotate(image1, cv2.ROTATE_90_CLOCKWISE)\n        rotated_image2 = cv2.rotate(rotated_image2, cv2.ROTATE_90_CLOCKWISE)\n        return rotated_image2\n    elif index==2:#rotate thrice\n        rotated_image3 = cv2.rotate(image1, cv2.ROTATE_90_CLOCKWISE)\n        rotated_image3 = cv2.rotate(rotated_image3, cv2.ROTATE_90_CLOCKWISE)\n        rotated_image3 = cv2.rotate(rotated_image3, cv2.ROTATE_90_CLOCKWISE)\n        return rotated_image3\n    elif index == 3: # four rotatins = original image\n        return image1\n    \ndef rotBoxes90(boxes, im_w, im_h):\n    ret_boxes =[]\n    for box in boxes:\n        x1, y1, x2, y2 = box\n        x1, y1, x2, y2 = x1-im_w//2, im_h//2 - y1, x2-im_w//2, im_h//2 - y2\n        x1, y1, x2, y2 = y1, -x1, y2, -x2\n        x1, y1, x2, y2 = int(x1+im_w//2), int(im_h//2 - y1), int(x2+im_w//2), int(im_h//2 - y2)\n        x1a, y1a, x2a, y2a = min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2)\n        ret_boxes.append([x1a, y1a, x2a, y2a])\n    return np.array(ret_boxes)\n\ndef detect1Image(img, img0, model, device, aug):\n    #normalize image values\n    img = img.transpose(2,0,1)\n    img = torch.from_numpy(img).to(device)\n    img = img.half() if half else img.float()  # uint8 to fp16/32\n    img /= 255.0\n    if img.ndimension() == 3:\n        img = img.unsqueeze(0)\n    \n    # the prediction(Using Yolo implementation)\n    pred = model(img, augment=aug)[0]\n    \n    # Apply NMS\n    pred = non_max_suppression(pred, score_thr, iou_thr, merge=True, classes=None, agnostic=False)\n    \n    boxes = []\n    scores = []\n    for i, det in enumerate(pred):  # for every detection\n        if det is not None and len(det): \n            # Rescale boxes from img_size to img0 size\n            det[:, :4] = scale_coords(img.shape[2:], det[:, :4], img0.shape).round()\n\n            # Store results\n            for *xyxy, conf, cls in det:\n                boxes.append([int(xyxy[0]), int(xyxy[1]), int(xyxy[2]), int(xyxy[3])])\n                scores.append(conf)\n\n    return np.array(boxes), np.array(scores) ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def detect():\n    models = []\n\n    # Load all models using weight.pt files\n    for w in weights if isinstance(weights, list) else [weights]:\n        models.append(torch.load(w, map_location=device)['model'].to(device).float().eval())\n        \n    # Load test image dataset using Yolo implementation\n    dataset = LoadImages(source, img_size=imgsz)\n    \n    # init img\n    img = torch.zeros((1, 3, imgsz, imgsz), device=device)  \n    \n    #If using CUDA, turn all models to half float\n    for model in models:\n        if half:\n            model.half()  # to FP16\n        _ = model(img.half() if half else img) if device.type != 'cpu' else None  # run once\n\n    all_paths, all_bboxes, all_confs = [], [], []\n    for p, img, img0, _ in dataset:\n        print()\n        img = img.transpose(1,2,0) # [H, W, 3]\n\n        all_paths.append(p)\n        m_box, m_score = [], []\n        for model in models:\n            enboxes = []\n            enscores = []\n            \n            #Detect the image rotated once, twice, three times and not at all\n            for i in range(4):\n                img1 = TTAImage(img, i)\n                boxes, scores = detect1Image(img1, img0, model, device, aug=False)\n                for _ in range(3-i):\n                    boxes = rotBoxes90(boxes, *img.shape[:2])            \n                enboxes.append(boxes)\n                enscores.append(scores)\n            #Detect the image flipped(based on Yolo implement)\n            boxes, scores = detect1Image(img, img0, model, device, aug=True)\n            enboxes.append(boxes)\n            enscores.append(scores) \n            \n            #for the 5 TTA detections , fuse boxes\n            boxes, scores = run_wbf(enboxes, enscores, image_size=1024, iou_thr=iou_thr, skip_box_thr=skip_box_thr)\n            boxes = boxes.astype(np.int32).clip(min=0, max=1024)\n            \n            #Ignore low percentage predictions\n            indices = scores >= score_thr\n            boxes = boxes[indices]\n            scores = scores[indices]\n            #For each model, store the 'good' boxes and scores\n            m_box.append(boxes)\n            m_score.append(scores)\n            \n        all_bboxes.append(m_box)\n        all_confs.append(m_score)\n    return all_paths, all_bboxes, all_confs","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"with torch.no_grad():\n    res = detect()\npaths,all_boxes,all_confs = res","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"results =[]\ndef format_prediction_string(boxes, scores):\n    pred_strings = []\n    for j in zip(scores, boxes):\n        pred_strings.append(\"{0:.4f} {1} {2} {3} {4}\".format(j[0], j[1][0], j[1][1], j[1][2], j[1][3]))\n    return \" \".join(pred_strings)\nbts = []\nsts = []\nfor row in range(len(paths)):\n    image_id = paths[row].split(\"/\")[-1].split(\".\")[0]\n    #Combine ensemble predictions\n    boxes, scores = run_wbf(all_boxes[row],all_confs[row], skip_box_thr = skip_box_thr, iou_thr = iou_thr)\n    \n    #Ignore bad predictions\n    indices = scores >= score_thr\n    boxes = boxes[indices]\n    scores = scores[indices]\n    \n    #Fix boxes to image size and store them\n    boxes = (boxes*1024/1024).astype(np.int32).clip(min=0, max=1023)\n    boxes[:, 2] = boxes[:, 2] - boxes[:, 0]\n    boxes[:, 3] = boxes[:, 3] - boxes[:, 1]\n    result = {'image_id': image_id,'PredictionString': format_prediction_string(boxes, scores)}\n    results.append(result)\n    \n    #boxes to show\n    bts.append(boxes)\n    #scores to show\n    sts.append(scores)\n!rm -rf *\ntest_df = pd.DataFrame(results, columns=['image_id', 'PredictionString'])\ntest_df.to_csv('submission.csv', index=False)\ntest_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"amount_to_show = 10\nshown = []\nfig = plt.figure(figsize=[20,20])\nper_row = 3\ncount = amount_to_show\nrows = 1\n\nfont = cv2.FONT_HERSHEY_SIMPLEX \nfontScale = 1\n# color = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)) \nthickness = 3\nwhile count > per_row:\n    count -= per_row\n    rows +=1\ncolor = (255, 255, 255)    \nfor i in range(1, amount_to_show+1):\n    fig.add_subplot(rows, per_row, i)\n    idx = random.randint(0, 9)\n    while idx  in shown:\n        idx = random.randint(0, 9)\n    shown.append(idx)\n    image = image = cv2.imread(paths[idx], cv2.IMREAD_COLOR)\n    for b,s in zip(bts[idx],sts[idx]):\n        image = cv2.rectangle(image, (b[0],b[1]), (b[0]+b[2],b[1]+b[3]), color, 2) \n        image = cv2.putText(image, '{}{:.2}'.format(\"Wheat\", s), (b[0]+np.random.randint(3),b[1]), font,  \n                       fontScale, color, thickness, cv2.LINE_AA)\n    \n    plt.title(paths[idx].split(\"/\")[-1].split(\".\")[0])\n    plt.imshow(image[:,:,::-1])\n    cv2.imwrite(paths[idx].split(\"/\")[-1].split(\".\")[0] + \".jpg\", image)\nfig.tight_layout()\nplt.show()","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}