{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.7.6","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":19989,"databundleVersionId":1160143,"sourceType":"competition"},{"sourceId":1219292,"sourceType":"datasetVersion","datasetId":648709},{"sourceId":1251699,"sourceType":"datasetVersion","datasetId":719180},{"sourceId":1285895,"sourceType":"datasetVersion","datasetId":742407},{"sourceId":7002739,"sourceType":"datasetVersion","datasetId":4025711}],"dockerImageVersionId":29956,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport os\nfrom tqdm.auto import tqdm\nimport shutil as sh","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-12-16T09:21:00.914822Z","iopub.execute_input":"2023-12-16T09:21:00.915138Z","iopub.status.idle":"2023-12-16T09:21:00.922671Z","shell.execute_reply.started":"2023-12-16T09:21:00.915110Z","shell.execute_reply":"2023-12-16T09:21:00.921732Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#!git clone https://github.com/ultralytics/yolov5\n#!mv yolov5/* ./\n\n!cp -r ../input/yolov5train/* .","metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_kg_hide-input":true,"execution":{"iopub.status.busy":"2023-12-16T09:21:00.924533Z","iopub.execute_input":"2023-12-16T09:21:00.924915Z","iopub.status.idle":"2023-12-16T09:21:02.041770Z","shell.execute_reply.started":"2023-12-16T09:21:00.924880Z","shell.execute_reply":"2023-12-16T09:21:02.040539Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install --no-deps '../input/weightedboxesfusion/' > /dev/null","metadata":{"execution":{"iopub.status.busy":"2023-12-16T09:21:02.044197Z","iopub.execute_input":"2023-12-16T09:21:02.044500Z","iopub.status.idle":"2023-12-16T09:21:26.934898Z","shell.execute_reply.started":"2023-12-16T09:21:02.044468Z","shell.execute_reply":"2023-12-16T09:21:26.933778Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def convertTrainLabel():\n    df = pd.read_csv('../input/global-wheat-detection/train.csv')\n    bboxs = np.stack(df['bbox'].apply(lambda x: np.fromstring(x[1:-1], sep=',')))\n    for i, column in enumerate(['x', 'y', 'w', 'h']):\n        df[column] = bboxs[:,i]\n    df.drop(columns=['bbox'], inplace=True)\n    df['x_center'] = df['x'] + df['w']/2\n    df['y_center'] = df['y'] + df['h']/2\n    df['classes'] = 0\n    from tqdm.auto import tqdm\n    import shutil as sh\n    df = df[['image_id','x', 'y', 'w', 'h','x_center','y_center','classes']]\n    \n    index = list(set(df.image_id))\n    \n    source = 'train'\n    if True:\n        for fold in [0]:\n            val_index = index[len(index)*fold//5:len(index)*(fold+1)//5]\n            for name,mini in tqdm(df.groupby('image_id')):\n                if name in val_index:\n                    path2save = 'val2017/'\n                else:\n                    path2save = 'train2017/'\n                if not os.path.exists('convertor/fold{}/labels/'.format(fold)+path2save):\n                    os.makedirs('convertor/fold{}/labels/'.format(fold)+path2save)\n                with open('convertor/fold{}/labels/'.format(fold)+path2save+name+\".txt\", 'w+') as f:\n                    row = mini[['classes','x_center','y_center','w','h']].astype(float).values\n                    row = row/1024\n                    row = row.astype(str)\n                    for j in range(len(row)):\n                        text = ' '.join(row[j])\n                        f.write(text)\n                        f.write(\"\\n\")\n                if not os.path.exists('convertor/fold{}/images/{}'.format(fold,path2save)):\n                    os.makedirs('convertor/fold{}/images/{}'.format(fold,path2save))\n                sh.copy(\"../input/global-wheat-detection/{}/{}.jpg\".format(source,name),'convertor/fold{}/images/{}/{}.jpg'.format(fold,path2save,name))\n","metadata":{"execution":{"iopub.status.busy":"2023-12-16T09:21:26.937104Z","iopub.execute_input":"2023-12-16T09:21:26.937415Z","iopub.status.idle":"2023-12-16T09:21:26.957286Z","shell.execute_reply.started":"2023-12-16T09:21:26.937383Z","shell.execute_reply":"2023-12-16T09:21:26.956435Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from ensemble_boxes import *\ndef run_wbf(boxes, scores, image_size=1023, iou_thr=0.5, skip_box_thr=0.7, weights=None):\n    #boxes = [prediction[image_index]['boxes'].data.cpu().numpy()/(image_size-1) for prediction in predictions]\n    #scores = [prediction[image_index]['scores'].data.cpu().numpy() for prediction in predictions]\n    labels = [np.zeros(score.shape[0]) for score in scores]\n    boxes = [box/(image_size) for box in boxes]\n    boxes, scores, labels = weighted_boxes_fusion(boxes, scores, labels, weights=None, iou_thr=iou_thr, skip_box_thr=skip_box_thr)\n    #boxes, scores, labels = nms(boxes, scores, labels, weights=[1,1,1,1,1], iou_thr=0.5)\n    boxes = boxes*(image_size)\n    return boxes, scores, labels\n\ndef TTAImage(image, index):\n    image1 = image.copy()\n    if index==0: \n        rotated_image = cv2.rotate(image1, cv2.ROTATE_90_CLOCKWISE)\n        return rotated_image\n    elif index==1:\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:\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:\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(im0, imgsz, model, device, conf_thres, iou_thres):\n    img = letterbox(im0, new_shape=imgsz)[0]\n    # Convert\n    img = img[:, :, ::-1].transpose(2, 0, 1)  # BGR to RGB, to 3x416x416\n    img = np.ascontiguousarray(img)\n\n\n    img = torch.from_numpy(img).to(device)\n    img =  img.float()  # uint8 to fp16/32\n    img /= 255.0   \n    if img.ndimension() == 3:\n        img = img.unsqueeze(0)\n\n    # Inference\n    pred = model(img, augment=False)[0]\n\n    # Apply NMS\n    pred = non_max_suppression(pred, conf_thres, iou_thres)\n\n    boxes = []\n    scores = []\n    for i, det in enumerate(pred):  # detections per image\n        # save_path = 'draw/' + image_id + '.jpg'\n        if det is not None and len(det):\n            # Rescale boxes from img_size to im0 size\n            det[:, :4] = scale_coords(img.shape[2:], det[:, :4], im0.shape).round()\n\n            # Write 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) ","metadata":{"execution":{"iopub.status.busy":"2023-12-16T09:21:26.958934Z","iopub.execute_input":"2023-12-16T09:21:26.959309Z","iopub.status.idle":"2023-12-16T09:21:26.993942Z","shell.execute_reply.started":"2023-12-16T09:21:26.959268Z","shell.execute_reply":"2023-12-16T09:21:26.993185Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from utils.datasets import *\nfrom utils.utils import *\n\ndef makePseudolabel():\n    source = '../input/global-wheat-detection/test/'\n    weights = '../input/yolov5/yolov5/bestv4.pt'\n    imgsz = 1024\n    conf_thres = 0.5\n    iou_thres = 0.6\n    is_TTA = True\n    \n    imagenames =  os.listdir(source)\n    \n    device = torch.device('cuda') if torch.cuda.is_available() else torch.device('cpu')\n\n    # Load model\n    model = torch.load(weights, map_location=device)['model'].float()  # load to FP32\n    model.to(device).eval()\n    \n    dataset = LoadImages(source, img_size=imgsz)\n\n    path2save = 'train2017/'\n    if not os.path.exists('convertor/fold0/labels/'+path2save):\n        os.makedirs('convertor/fold0/labels/'+path2save)\n    if not os.path.exists('convertor/fold0/images/{}'.format(path2save)):\n        os.makedirs('convertor/fold0/images/{}'.format(path2save))\n            \n    for name in imagenames:\n        image_id = name.split('.')[0]\n        im01 = cv2.imread('%s/%s.jpg'%(source,image_id))  # BGR\n        if im01.shape[0]!=1024 or im01.shape[1]!=1024:\n            continue\n        assert im01 is not None, 'Image Not Found '\n        # Padded resize\n        im_w, im_h = im01.shape[:2]\n        if is_TTA:\n            enboxes = []\n            enscores = []\n            for i in range(4):\n                im0 = TTAImage(im01, i)\n                boxes, scores = detect1Image(im0, imgsz, model, device, conf_thres, iou_thres)\n                for _ in range(3-i):\n                    boxes = rotBoxes90(boxes, im_w, im_h)\n                    \n                enboxes.append(boxes)\n                enscores.append(scores) \n\n            boxes, scores, labels = run_wbf(enboxes, enscores, image_size = im_w, iou_thr=0.6, skip_box_thr=0.43)\n            boxes = boxes.astype(np.int32).clip(min=0, max=im_w)\n        else:\n            boxes, scores = detect1Image(im01, imgsz, model, device, conf_thres, iou_thres)\n\n        boxes[:, 2] = boxes[:, 2] - boxes[:, 0]\n        boxes[:, 3] = boxes[:, 3] - boxes[:, 1]\n        \n        boxes = boxes[scores >= 0.05].astype(np.int32)\n        scores = scores[scores >=float(0.05)]\n        \n        lineo = ''\n        for box in boxes:\n            x1, y1, w, h = box\n            xc, yc, w, h = (x1+w/2)/1024, (y1+h/2)/1024, w/1024, h/1024\n            lineo += '0 %f %f %f %f\\n'%(xc, yc, w, h)\n            \n        fileo = open('convertor/fold0/labels/'+path2save+image_id+\".txt\", 'w+')\n        fileo.write(lineo)\n        fileo.close()\n        sh.copy(\"../input/global-wheat-detection/test/{}.jpg\".format(image_id),'convertor/fold0/images/{}/{}.jpg'.format(path2save,image_id))\n            \n","metadata":{"execution":{"iopub.status.busy":"2023-12-16T09:21:26.995385Z","iopub.execute_input":"2023-12-16T09:21:26.995694Z","iopub.status.idle":"2023-12-16T09:21:29.334273Z","shell.execute_reply.started":"2023-12-16T09:21:26.995657Z","shell.execute_reply":"2023-12-16T09:21:29.333397Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\nconvertTrainLabel()","metadata":{"execution":{"iopub.status.busy":"2023-12-16T09:21:29.335399Z","iopub.execute_input":"2023-12-16T09:21:29.335668Z","iopub.status.idle":"2023-12-16T09:22:16.007492Z","shell.execute_reply.started":"2023-12-16T09:21:29.335641Z","shell.execute_reply":"2023-12-16T09:22:16.006631Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"makePseudolabel()","metadata":{"execution":{"iopub.status.busy":"2023-12-16T09:22:16.009207Z","iopub.execute_input":"2023-12-16T09:22:16.009584Z","iopub.status.idle":"2023-12-16T09:22:25.572560Z","shell.execute_reply.started":"2023-12-16T09:22:16.009542Z","shell.execute_reply":"2023-12-16T09:22:25.571783Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!ls","metadata":{"execution":{"iopub.status.busy":"2023-12-16T09:22:25.574053Z","iopub.execute_input":"2023-12-16T09:22:25.574323Z","iopub.status.idle":"2023-12-16T09:22:26.561799Z","shell.execute_reply.started":"2023-12-16T09:22:25.574296Z","shell.execute_reply":"2023-12-16T09:22:26.560996Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if len(os.listdir('../input/global-wheat-detection/test/'))<11:\n    pass\n    #!python train.py --img 1024 --batch 4 --epochs 1 --data ../input/configyolo5/wheat0.yaml --cfg ../input/yolov5/v5/v5/models/yolov5x.yaml  --weights ../input/yolov5/bestv4.pt   \nelse:\n    !python train.py --img 1024 --batch 4 --epochs 10 --data ../input/configyolo5/wheat0.yaml --cfg ../input/yolov5/v5/v5/models/yolov5x.yaml --weights ../input/yolov5/bestv4.pt\n    \n    \n!rm -rf convertor","metadata":{"execution":{"iopub.status.busy":"2023-12-16T09:22:26.563445Z","iopub.execute_input":"2023-12-16T09:22:26.563738Z","iopub.status.idle":"2023-12-16T09:22:27.828147Z","shell.execute_reply.started":"2023-12-16T09:22:26.563708Z","shell.execute_reply":"2023-12-16T09:22:27.827126Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def 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\n    return \" \".join(pred_strings)","metadata":{"execution":{"iopub.status.busy":"2023-12-16T09:22:27.830137Z","iopub.execute_input":"2023-12-16T09:22:27.830545Z","iopub.status.idle":"2023-12-16T09:22:27.837637Z","shell.execute_reply.started":"2023-12-16T09:22:27.830501Z","shell.execute_reply":"2023-12-16T09:22:27.836699Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def detect():\n    source = '../input/global-wheat-detection/test/'\n    weights = 'weights/best.pt'\n    if not os.path.exists(weights):\n        weights = '../input/yolov5/yolov5/bestv4.pt'\n    imgsz = 1024\n    conf_thres = 0.5\n    iou_thres = 0.6\n    is_TTA = True\n    \n    imagenames =  os.listdir(source)\n    \n    device = torch.device('cuda') if torch.cuda.is_available() else torch.device('cpu')\n\n    # Load model\n    model = torch.load(weights, map_location=device)['model'].float()  # load to FP32\n    model.to(device).eval()\n    \n    dataset = LoadImages(source, img_size=imgsz)\n\n    results = []\n    fig, ax = plt.subplots(5, 2, figsize=(30, 70))\n    count = 0\n    # img = torch.zeros((1, 3, imgsz, imgsz), device=device)  # init img\n    #for path, img, im0s, _ in dataset:\n    for name in imagenames:\n        image_id = name.split('.')[0]\n        im01 = cv2.imread('%s/%s.jpg'%(source,image_id))  # BGR\n        assert im01 is not None, 'Image Not Found '\n        # Padded resize\n        im_w, im_h = im01.shape[:2]\n        if is_TTA:\n            enboxes = []\n            enscores = []\n            for i in range(4):\n                im0 = TTAImage(im01, i)\n                boxes, scores = detect1Image(im0, imgsz, model, device, conf_thres, iou_thres)\n                for _ in range(3-i):\n                    boxes = rotBoxes90(boxes, im_w, im_h)\n                    \n                if 1: #i<3:\n                    enboxes.append(boxes)\n                    enscores.append(scores) \n            boxes, scores = detect1Image(im01, imgsz, model, device, conf_thres, iou_thres)\n            enboxes.append(boxes)\n            enscores.append(scores)\n\n            boxes, scores, labels = run_wbf(enboxes, enscores, image_size = im_w, iou_thr=0.6, skip_box_thr=0.5)\n            boxes = boxes.astype(np.int32).clip(min=0, max=im_w)\n        else:\n            boxes, scores = detect1Image(im01, imgsz, model, device, conf_thres, iou_thres)\n\n        boxes[:, 2] = boxes[:, 2] - boxes[:, 0]\n        boxes[:, 3] = boxes[:, 3] - boxes[:, 1]\n        \n        boxes = boxes[scores >= 0.05].astype(np.int32)\n        scores = scores[scores >=float(0.05)]\n        if count<10:\n            #sample = image.permute(1,2,0).cpu().numpy()\n            for box, score in zip(boxes,scores):\n                cv2.rectangle(im0,\n                              (box[0], box[1]),\n                              (box[2]+box[0], box[3]+box[1]),\n                              (220, 0, 0), 2)\n                cv2.putText(im0, '%.2f'%(score), (box[0], box[1]), cv2.FONT_HERSHEY_SIMPLEX ,  \n                   0.5, (255,255,255), 2, cv2.LINE_AA)\n            ax[count%5][count//5].imshow(im0)\n            count+=1\n            \n        result = {\n            'image_id': image_id,\n            'PredictionString': format_prediction_string(boxes, scores)\n        }\n\n        results.append(result)\n    return results","metadata":{"execution":{"iopub.status.busy":"2023-12-16T09:22:27.840963Z","iopub.execute_input":"2023-12-16T09:22:27.841319Z","iopub.status.idle":"2023-12-16T09:22:27.868499Z","shell.execute_reply.started":"2023-12-16T09:22:27.841283Z","shell.execute_reply":"2023-12-16T09:22:27.867777Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"results = detect()\ntest_df = pd.DataFrame(results, columns=['image_id', 'PredictionString'])\ntest_df.to_csv('submission.csv', index=False)\ntest_df.head()","metadata":{"execution":{"iopub.status.busy":"2023-12-16T09:22:27.869771Z","iopub.execute_input":"2023-12-16T09:22:27.870056Z","iopub.status.idle":"2023-12-16T09:22:39.327401Z","shell.execute_reply.started":"2023-12-16T09:22:27.870029Z","shell.execute_reply":"2023-12-16T09:22:39.326079Z"},"trusted":true},"execution_count":null,"outputs":[]}]}