{"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":"markdown","source":"for discussion refer to:\nhttps://www.kaggle.com/competitions/hubmap-hacking-the-human-vasculature/discussion/419143","metadata":{}},{"cell_type":"code","source":" if 0:\n    #https://www.kaggle.com/code/saworz/import-install-pycocotools-for-submission\n    !pip install -q pycocotools\n    !pip show pycocotools\n    !mkdir wheels\n    %cd wheels\n    !pip wheel pycocotools\n    %cd ../\n    !zip -r pycocotools_206.zip wheels\n\ntry:\n    import pycocotools\nexcept:\n    print('install pycocotools_206 ...')\n    !pip install --no-index --no-deps /kaggle/input/hubmap-vessel-00/pycocotools_206/wheels/*.whl\n    \nimport sys\nsys.path.append('/kaggle/input/hubmap-vessel-00') \nsys.path.append('/kaggle/input/hubmap-vessel-00/yolov7/seg') \n\n#!pip install ultralytics\n#https://www.kaggle.com/datasets/chenjiexu/yolov8\n\nimport torch\nprint('torch',torch.__version__)\n\nimport pandas as pd\nimport numpy as np\nfrom glob import glob\n\n%matplotlib inline \nimport matplotlib\nimport matplotlib.pyplot as plt\n\nimport base64\nfrom pycocotools import _mask as coco_mask\nimport typing as t\nimport zlib\nimport cv2\n\nprint('numpy',np.__version__)\nfrom yolov7.seg.models.common import DetectMultiBackend\nfrom yolov7.seg.utils.general import non_max_suppression\nfrom yolov7.seg.utils.segment.general import process_mask, scale_masks\nfrom yolov7.seg.utils.torch_utils import select_device\n\nprint('IMPORT OK!!!')\n\n#############################################################################################################\ndef encode_binary_mask(mask: np.ndarray) -> t.Text:\n    \"\"\"Converts a binary mask into OID challenge encoding ascii text.\"\"\"\n\n    # check input mask --\n    #if mask.dtype != np.bool:\n    if mask.dtype != bool:\n        raise ValueError(\n            \"encode_binary_mask expects a binary mask, received dtype == %s\" %\n            mask.dtype)\n\n    mask = np.squeeze(mask)\n    if len(mask.shape) != 2:\n        raise ValueError(\n            \"encode_binary_mask expects a 2d mask, received shape == %s\" %\n            mask.shape)\n\n    # convert input mask to expected COCO API input --\n    mask_to_encode = mask.reshape(mask.shape[0], mask.shape[1], 1)\n    mask_to_encode = mask_to_encode.astype(np.uint8)\n    mask_to_encode = np.asfortranarray(mask_to_encode)\n\n    # RLE encode mask --\n    encoded_mask = coco_mask.encode(mask_to_encode)[0][\"counts\"]\n\n    # compress and base64 encoding --\n    binary_str = zlib.compress(encoded_mask, zlib.Z_BEST_COMPRESSION)\n    base64_str = base64.b64encode(binary_str)\n    return base64_str\n\ndef dilate_predict_mask(out_mask):\n    for i in range(len(out_mask)):\n        kernel = np.ones(shape=(3, 3), dtype=np.uint8)\n        out_mask[i] = cv2.dilate(out_mask[i], kernel, 3)\n    return out_mask\n\ndef predict_one(model, image_file, device):\n    im0 = cv2.imread(image_file)  # BGR\n\n    # Resize and pad image while meeting stride-multiple constraints\n    #im = letterbox(im0, self.img_size, stride=self.stride, auto=self.auto)[0]  # padded resize\n    im = im0\n    im = im.transpose((2, 0, 1))[::-1]  # HWC to CHW, BGR to RGB\n    im = np.ascontiguousarray(im)  # contiguous\n\n    im = torch.from_numpy(im).to(device)\n    im = im.float()  # uint8 to fp16/32\n    im /= 255  # 0 - 255 to 0.0 - 1.0\n    im = im[None]  # expand for batch dim\n\n\n    # inference\n    pred, out = model(im, augment=False, visualize=False)\n    proto = out[1]\n    #print(pred.shape)\n    #pred.shape: torch.Size([1, 16128, 40])\n\n    # NMS\n    pred = non_max_suppression(pred, conf_thres=0.001, iou_thres=0.6, classes=0, agnostic=False, max_det=1000, nm=32) #nm = num_mask?\n\n    out_mask = []\n    out_conf = []\n    for i, det in enumerate(pred):  # per image\n        if len(det):\n            masks = process_mask(proto[i], det[:, 6:], det[:, :4], im.shape[2:], upsample=True)  # HWC\n            confs = det[:, 4]\n            clasf = det[:, 5]\n\n            out_conf = confs.data.cpu().numpy()\n\n            # https://www.kaggle.com/competitions/hubmap-hacking-the-human-vasculature/discussion/416901\n            for mask, confidence, classification in zip(masks, confs, clasf):\n                binary_mask = mask.cpu().numpy() \n                out_mask.append(binary_mask)\n  \n    return out_mask, out_conf\n\n\n#############################################################################################################\nmode = 'submit' #'submit' #debug\n\nif mode=='debug':\n    image_dir = '/kaggle/input/hubmap-hacking-the-human-vasculature/train'\n    image_id = glob(f'{image_dir}/*.tif')\n    image_id = [f.split('/')[-1][:-4] for f in image_id] #[:25]\n    \n\nif mode=='submit': \n    image_dir = '/kaggle/input/hubmap-hacking-the-human-vasculature/test' \n    valid_df = pd.read_csv('/kaggle/input/hubmap-hacking-the-human-vasculature/sample_submission.csv')\n    #image_id = valid_df['id'].values\n    \n    image_id = glob(f'{image_dir}/*.tif')\n    image_id = [f.split('/')[-1][:-4] for f in image_id]\n    \nprint('image_dir', image_dir)\nprint(len(image_id),image_id )\n \n\n#-------------------------------------------------\n\nmodel_file='/kaggle/input/hubmap-vessel-weight-00/yoloyv7-public-best.pt'\ndata_yaml='/kaggle/working/hubmap-predict.yaml'\n\n# Create a yaml file as expected by YOLOv7 (and others)\nyaml_text = \"\"\"\n# class names\nnames: \n  0: blood_vessel\n  1: glomerulus\n  2: unsure\n\"\"\"\nwith open(data_yaml, 'w') as text_file:\n    text_file.write(yaml_text)\n\ndevice = select_device('0') \nmodel = DetectMultiBackend(model_file, device=device, dnn=False, data=data_yaml, fp16=False)\nmodel.warmup(imgsz=(1,3,512,512))  \nprint('model.training', model.model.training)\n\n#-------------------------------------------------\n \nsubmission=[] \n#https://www.kaggle.com/code/itsuki9180/hubmap-inference\nfor t,id in enumerate(image_id):\n    print(t,id) \n    prediction_string = ''\n    try: \n        image_file = f'{image_dir}/{id}.tif' \n        mask, conf = predict_one(model, image_file, device)\n        \n        mask = dilate_predict_mask(mask)\n\n        all = np.zeros((512,512), dtype=np.uint8)\n        if len(mask)>0:\n            num_mask = len(mask)\n            for i in range(num_mask):\n                m = mask[i]>0\n                #if all[m].mean() > 0.7: continue\n                all[m] = 1\n\n                e = encode_binary_mask(m)\n                if i == 0:\n                    prediction_string = f'0 {conf[i]} {e.decode(\"utf-8\")}'\n                else:\n                    prediction_string += f' 0 {conf[i]} {e.decode(\"utf-8\")}'\n    except:\n        pass\n    \n    if t==0:\n        print('prediction_string')\n        print(prediction_string[:200])\n        #print(prediction_string)\n        \n        image = cv2.imread(image_file)\n        mask = all/(all.max()+0.001)\n        plt.imshow(image)\n        plt.imshow(mask)\n        plt.show()\n        \n  \n    submission.append({\n        'id':id,\n        'height':512,\n        'width':512,\n        'prediction_string':prediction_string,\n    })    \n    #print(prediction_string)\n\nsubmission_df = pd.DataFrame(submission)\nsubmission_df.to_csv('submission.csv',index=False)\nprint(submission_df)\nprint('SUBMIT OK !!!')\n\n# '''\n# /kaggle/input/hubmap-hacking-the-human-vasculature/test/72e40acccadf.tif\n# (12, 512, 512) 1 uint8\n# [    0.83434     0.76198     0.75391     0.69363     0.66402     0.64325     0.62769     0.61784     0.54618     0.45178     0.31751     0.25086]\n\n# '''","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-06-25T01:52:06.657212Z","iopub.execute_input":"2023-06-25T01:52:06.657610Z","iopub.status.idle":"2023-06-25T01:52:07.839763Z","shell.execute_reply.started":"2023-06-25T01:52:06.657579Z","shell.execute_reply":"2023-06-25T01:52:07.838843Z"},"trusted":true},"execution_count":null,"outputs":[]}]}