{"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":"# HuBMAP Making Dataset for Instance Segentation","metadata":{}},{"cell_type":"markdown","source":"# Based Notebook\nhttps://www.kaggle.com/code/itsuki9180/hubmap-making-dataset","metadata":{}},{"cell_type":"markdown","source":"## import libraries and metadata","metadata":{}},{"cell_type":"code","source":"import os\nimport json\nfrom PIL import Image\nfrom collections import Counter\n\nimport numpy as np\nimport pandas as pd\nimport plotly.express as px\nimport plotly.graph_objects as go\nimport tifffile as tiff\nimport matplotlib.pyplot as plt\nfrom tqdm import tqdm\n\nimport cv2","metadata":{"execution":{"iopub.status.busy":"2023-06-12T15:05:24.153595Z","iopub.execute_input":"2023-06-12T15:05:24.154126Z","iopub.status.idle":"2023-06-12T15:05:25.723630Z","shell.execute_reply.started":"2023-06-12T15:05:24.154080Z","shell.execute_reply":"2023-06-12T15:05:25.722508Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"with open('/kaggle/input/hubmap-hacking-the-human-vasculature/polygons.jsonl', 'r') as json_file:\n    json_list = list(json_file)","metadata":{"execution":{"iopub.status.busy":"2023-06-12T15:05:25.726579Z","iopub.execute_input":"2023-06-12T15:05:25.727069Z","iopub.status.idle":"2023-06-12T15:05:26.073351Z","shell.execute_reply.started":"2023-06-12T15:05:25.726996Z","shell.execute_reply":"2023-06-12T15:05:26.072297Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tiles_dicts = []\nfor json_str in json_list:\n    tiles_dicts.append(json.loads(json_str))","metadata":{"execution":{"iopub.status.busy":"2023-06-12T15:05:26.075898Z","iopub.execute_input":"2023-06-12T15:05:26.076299Z","iopub.status.idle":"2023-06-12T15:05:30.218073Z","shell.execute_reply.started":"2023-06-12T15:05:26.076269Z","shell.execute_reply":"2023-06-12T15:05:30.217226Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tile_meta_df = pd.read_csv(\"/kaggle/input/hubmap-hacking-the-human-vasculature/tile_meta.csv\")\ntile_meta_df","metadata":{"execution":{"iopub.status.busy":"2023-06-12T15:05:30.219500Z","iopub.execute_input":"2023-06-12T15:05:30.220312Z","iopub.status.idle":"2023-06-12T15:05:30.281362Z","shell.execute_reply.started":"2023-06-12T15:05:30.220281Z","shell.execute_reply":"2023-06-12T15:05:30.280290Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## visualize code from [[EDA] ❤️HuBMAP-HHV ~ Interactive annotations📊](https://www.kaggle.com/code/leonidkulyk/eda-hubmap-hhv-interactive-annotations/notebook)","metadata":{}},{"cell_type":"code","source":"def get_cartesian_coords(coords, img_height):\n    coords_array = np.array(coords).squeeze()\n    xs = coords_array[:, 0]\n    ys = -coords_array[:, 1] + img_height\n    \n    return xs, ys\n\ndef plot_annotated_image(image_dict, scale_factor: int = 1.0) -> None:\n    #array = tiff.imread(CFG.img_path_template.format(image_dict[\"id\"]))\n    array = tiff.imread(f'/kaggle/input/hubmap-hacking-the-human-vasculature/train/{image_dict[\"id\"]}.tif')\n    \n    img_example = Image.fromarray(array)\n    annotations = image_dict[\"annotations\"]\n    \n    # create figure\n    fig = go.Figure()\n\n    # constants\n    img_width = img_example.size[0]\n    img_height = img_example.size[1]\n    \n\n    # add invisible scatter trace\n    fig.add_trace(\n        go.Scatter(\n            x=[0, img_width],\n            y=[0, img_height],\n            mode=\"markers\",\n            marker_opacity=0\n        )\n    )\n\n    # configure axes\n    fig.update_xaxes(\n        visible=False,\n        range=[0, img_width]\n    )\n\n    fig.update_yaxes(\n        visible=False,\n        range=[0, img_height],\n        # the scaleanchor attribute ensures that the aspect ratio stays constant\n        scaleanchor=\"x\"\n    )\n\n    # add image\n    fig.add_layout_image(dict(\n        x=0,\n        sizex=img_width,\n        y=img_height,\n        sizey=img_height,\n        xref=\"x\", yref=\"y\",\n        opacity=1.0,\n        layer=\"below\",\n        sizing=\"stretch\",\n        source=img_example\n    ))\n    \n    # add polygons\n    for annotation in annotations:\n        name = annotation[\"type\"]\n        xs, ys = get_cartesian_coords(annotation[\"coordinates\"], img_height)\n        fig.add_trace(go.Scatter(\n            x=xs, y=ys, fill=\"toself\",\n            name=name,\n            hovertemplate=\"%{name}\",\n            mode='lines'\n        ))\n\n    # configure other layout\n    fig.update_layout(\n        width=img_width * scale_factor,\n        height=img_height * scale_factor,\n        margin={\"l\": 0, \"r\": 0, \"t\": 0, \"b\": 0},\n        showlegend=False\n    )\n\n    # disable the autosize on double click because it adds unwanted margins around the image\n    # and finally show figure\n    fig.show(config={'doubleClick': 'reset'})","metadata":{"execution":{"iopub.status.busy":"2023-06-12T15:05:43.065992Z","iopub.execute_input":"2023-06-12T15:05:43.067057Z","iopub.status.idle":"2023-06-12T15:05:43.080957Z","shell.execute_reply.started":"2023-06-12T15:05:43.066995Z","shell.execute_reply":"2023-06-12T15:05:43.079988Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_annotated_image(tiles_dicts[0])","metadata":{"execution":{"iopub.status.busy":"2023-06-12T15:05:43.928060Z","iopub.execute_input":"2023-06-12T15:05:43.928752Z","iopub.status.idle":"2023-06-12T15:05:44.354655Z","shell.execute_reply.started":"2023-06-12T15:05:43.928710Z","shell.execute_reply":"2023-06-12T15:05:44.353886Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## make sample annotation for Instance Segmentation","metadata":{}},{"cell_type":"code","source":"len(tiles_dicts)","metadata":{"execution":{"iopub.status.busy":"2023-06-12T15:05:49.683573Z","iopub.execute_input":"2023-06-12T15:05:49.685085Z","iopub.status.idle":"2023-06-12T15:05:49.693343Z","shell.execute_reply.started":"2023-06-12T15:05:49.685022Z","shell.execute_reply":"2023-06-12T15:05:49.691952Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"mask = np.zeros((512, 512), dtype=np.float32)\nmask_glomerulus = np.zeros((512, 512), dtype=np.float32)\nmask_unsure = np.zeros((512, 512), dtype=np.float32)\nfor annot in tiles_dicts[0]['annotations']:\n    cords = annot['coordinates']\n    if annot['type'] == \"blood_vessel\":\n        for cd in cords:\n            rr, cc = np.array([i[1] for i in cd]), np.asarray([i[0] for i in cd])\n            mask[rr, cc] = 1\n            \n    if annot['type'] == \"glomerulus\":\n        for cd in cords:\n            rr, cc = np.array([i[1] for i in cd]), np.asarray([i[0] for i in cd])\n            mask_glomerulus[rr, cc] = 1\n            \n    if annot['type'] == \"unsure\":\n        for cd in cords:\n            rr, cc = np.array([i[1] for i in cd]), np.asarray([i[0] for i in cd])\n            mask_unsure[rr, cc] = 1\n        \nplt.subplot(1, 3, 1)\nplt.imshow(mask)\nplt.axis('off')\nplt.title('blood_vessel')\nplt.subplot(1, 3, 2)\nplt.imshow(mask_glomerulus)\nplt.axis('off')\nplt.title('glomerulus')\nplt.subplot(1, 3, 3)\nplt.imshow(mask_unsure)\nplt.axis('off')\nplt.title('unsure')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-06-12T15:10:58.272189Z","iopub.execute_input":"2023-06-12T15:10:58.272693Z","iopub.status.idle":"2023-06-12T15:10:58.607768Z","shell.execute_reply.started":"2023-06-12T15:10:58.272649Z","shell.execute_reply":"2023-06-12T15:10:58.606573Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"contours,_ = cv2.findContours((mask*255).astype(np.uint8), 1, 2)\nzero_img = np.zeros([mask.shape[0], mask.shape[1], 3], dtype=\"uint8\")\n\nfor p in contours:\n    cv2.fillPoly(zero_img, [p], (255, 255, 255))\n    \nplt.imshow(zero_img)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-06-12T15:11:24.592970Z","iopub.execute_input":"2023-06-12T15:11:24.593442Z","iopub.status.idle":"2023-06-12T15:11:24.872672Z","shell.execute_reply.started":"2023-06-12T15:11:24.593410Z","shell.execute_reply":"2023-06-12T15:11:24.870386Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from copy import deepcopy\ncontours, hierarchy = cv2.findContours(mask.astype(\"uint8\"), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)\nimg_with_area = zero_img\nprint(img_with_area.shape)\n\nprint(len(contours))\n        \nfor i in range(len(contours)):\n    if cv2.contourArea(contours[i]) > (mask.shape[0] * mask.shape[1]) * 0.0001:\n        cv2.fillPoly(img_with_area, [contours[i][:,0,:]], (255-4*(i+1),255-4*(i+1),255-4*(i+1)), lineType=cv2.LINE_8, shift=0)\n        \nplt.imshow(img_with_area)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-06-12T15:13:16.335996Z","iopub.execute_input":"2023-06-12T15:13:16.336470Z","iopub.status.idle":"2023-06-12T15:13:16.596256Z","shell.execute_reply.started":"2023-06-12T15:13:16.336432Z","shell.execute_reply":"2023-06-12T15:13:16.595199Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## functionalize","metadata":{}},{"cell_type":"code","source":"def mask2area(mask):\n    contours,_ = cv2.findContours((mask*255).astype(np.uint8), 1, 2)\n    zero_img = np.zeros([mask.shape[0], mask.shape[1], 3], dtype=\"uint8\")\n    for p in contours:\n        cv2.fillPoly(zero_img, [p], (255, 255, 255))\n        \n    contours, hierarchy = cv2.findContours(mask.astype(\"uint8\"), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)\n    img_with_area = zero_img\n\n    for i in range(len(contours)):\n        cv2.fillPoly(img_with_area, [contours[i][:,0,:]], (255-4*(i+1),255-4*(i+1),255-4*(i+1)), lineType=cv2.LINE_8, shift=0)\n    \n    return img_with_area","metadata":{"execution":{"iopub.status.busy":"2023-06-12T15:37:09.175226Z","iopub.execute_input":"2023-06-12T15:37:09.175683Z","iopub.status.idle":"2023-06-12T15:37:09.184025Z","shell.execute_reply.started":"2023-06-12T15:37:09.175654Z","shell.execute_reply":"2023-06-12T15:37:09.182730Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def make_seg_mask(tiles_dict):\n    masks = {}\n    labels = [\"blood_vessel\", \"glomerulus\", \"unsure\"]\n    for label in labels:\n        masks[label] = np.zeros((512, 512), dtype=np.float32)\n\n    for annot in tiles_dict['annotations']:\n        cords = annot['coordinates']\n        label = annot['type']\n        for cd in cords:\n            rr, cc = np.array([i[1] for i in cd]), np.asarray([i[0] for i in cd])\n            masks[label][rr, cc] = 1\n    \n    for label in labels:\n        masks[label] = mask2area(masks[label])\n            \n    return masks","metadata":{"execution":{"iopub.status.busy":"2023-06-12T15:38:09.960924Z","iopub.execute_input":"2023-06-12T15:38:09.961435Z","iopub.status.idle":"2023-06-12T15:38:09.969334Z","shell.execute_reply.started":"2023-06-12T15:38:09.961399Z","shell.execute_reply":"2023-06-12T15:38:09.968046Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"os.makedirs('train/image', exist_ok=True)\nos.makedirs('train/mask', exist_ok=True)\nlabels = [\"blood_vessel\", \"glomerulus\", \"unsure\"]\nfor label in labels:\n    os.makedirs(f'train/mask/{label}', exist_ok=True)\n\nno_mask_images = []\nfor i, tldc in enumerate(tqdm(tiles_dicts)):\n    array = tiff.imread(f'/kaggle/input/hubmap-hacking-the-human-vasculature/train/{tldc[\"id\"]}.tif')\n    img_example = Image.fromarray(array)\n    img = np.array(img_example)\n    masks = make_seg_mask(tldc)\n    \n    if np.sum(masks['blood_vessel'])>0:\n        cv2.imwrite(f'train/image/{tldc[\"id\"]}.png', img)\n        for label, mask in masks.items():\n            cv2.imwrite(f'train/mask/{label}/{tldc[\"id\"]}.png', mask)\n    else:\n        no_mask_images.append(tldc['id'])\n\n        \nprint(f\"{','.join(no_mask_images)} have no blood_vessel mask\")","metadata":{"execution":{"iopub.status.busy":"2023-06-12T15:44:52.351586Z","iopub.execute_input":"2023-06-12T15:44:52.352008Z","iopub.status.idle":"2023-06-12T15:46:19.205913Z","shell.execute_reply.started":"2023-06-12T15:44:52.351960Z","shell.execute_reply":"2023-06-12T15:46:19.204802Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}