{"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":"import pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport plotly\nimport plotly.express as px\nimport plotly.graph_objects as go\nimport plotly.figure_factory as ff\nfrom pathlib import Path\nfrom tqdm.notebook import tqdm\nimport collections\nimport glob\nimport gc\nfrom IPython.display import display\nimport cv2\n\nimport torch\nfrom torch.utils.data import Dataset, DataLoader\nimport torch.nn as nn\nimport torch.functional as F\nimport torch.optim as optim\nfrom torch.optim.lr_scheduler import ReduceLROnPlateau, CosineAnnealingLR\n\nimport albumentations as al\nfrom albumentations.pytorch.transforms import ToTensorV2","metadata":{"_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","papermill":{"duration":3.340065,"end_time":"2021-10-16T10:11:57.719098","exception":false,"start_time":"2021-10-16T10:11:54.379033","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-10-17T10:41:50.963002Z","iopub.execute_input":"2021-10-17T10:41:50.963326Z","iopub.status.idle":"2021-10-17T10:41:56.841902Z","shell.execute_reply.started":"2021-10-17T10:41:50.963240Z","shell.execute_reply":"2021-10-17T10:41:56.841079Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# config","metadata":{"papermill":{"duration":0.008001,"end_time":"2021-10-16T10:11:57.739102","exception":false,"start_time":"2021-10-16T10:11:57.731101","status":"completed"},"tags":[]}},{"cell_type":"code","source":"ORIGINAL_PATH = Path('../input/sartorius-cell-instance-segmentation/')\nTRAIN_IMAGE_PATH = ORIGINAL_PATH / 'train'\nTEST_IMAGE_PATH = ORIGINAL_PATH / 'test'\nTRAIN_SEMI_PATH = ORIGINAL_PATH / 'train_semi_supervised'\nLIVE_CELL_ANT_PATH = ORIGINAL_PATH / 'LIVECell_dataset_2021' / 'annotations'\nLIVE_CELL_IMG_PATH = ORIGINAL_PATH / 'LIVECell_dataset_2021' / 'images'\nTRAIN_PATH = ORIGINAL_PATH / 'train.csv'\nSUB_PATH = ORIGINAL_PATH / 'sample_submission.csv'","metadata":{"papermill":{"duration":0.017041,"end_time":"2021-10-16T10:11:57.764401","exception":false,"start_time":"2021-10-16T10:11:57.747360","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-10-17T10:41:56.843302Z","iopub.execute_input":"2021-10-17T10:41:56.843514Z","iopub.status.idle":"2021-10-17T10:41:56.848555Z","shell.execute_reply.started":"2021-10-17T10:41:56.843487Z","shell.execute_reply":"2021-10-17T10:41:56.847796Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Function","metadata":{"papermill":{"duration":0.007928,"end_time":"2021-10-16T10:11:57.780568","exception":false,"start_time":"2021-10-16T10:11:57.772640","status":"completed"},"tags":[]}},{"cell_type":"code","source":"def rle2mask(rle, shape):\n    \n    mask = np.zeros(shape, dtype=int).flatten()\n    rle = np.array(rle.split(), dtype=int)\n    starts = rle[0::2] - 1\n    lengths = rle[1::2]\n    ends = starts + lengths\n    for lo, hi in zip(starts, ends):\n        mask[lo:hi] = 1\n    mask = mask.reshape(shape)\n    \n    return mask","metadata":{"papermill":{"duration":0.016566,"end_time":"2021-10-16T10:11:57.805034","exception":false,"start_time":"2021-10-16T10:11:57.788468","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-10-17T10:41:56.849575Z","iopub.execute_input":"2021-10-17T10:41:56.849805Z","iopub.status.idle":"2021-10-17T10:41:56.862388Z","shell.execute_reply.started":"2021-10-17T10:41:56.849779Z","shell.execute_reply":"2021-10-17T10:41:56.861732Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Read data","metadata":{"papermill":{"duration":0.007665,"end_time":"2021-10-16T10:11:57.820911","exception":false,"start_time":"2021-10-16T10:11:57.813246","status":"completed"},"tags":[]}},{"cell_type":"code","source":"sub_df = pd.read_csv(SUB_PATH)\nsub_df.head()","metadata":{"papermill":{"duration":0.044835,"end_time":"2021-10-16T10:11:57.873788","exception":false,"start_time":"2021-10-16T10:11:57.828953","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-10-17T10:41:56.863791Z","iopub.execute_input":"2021-10-17T10:41:56.864509Z","iopub.status.idle":"2021-10-17T10:41:56.901300Z","shell.execute_reply.started":"2021-10-17T10:41:56.864477Z","shell.execute_reply":"2021-10-17T10:41:56.900530Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df = pd.read_csv(TRAIN_PATH)\nprint(f'Number of image: {train_df.id.nunique()}')\n\ntrain_df.tail()","metadata":{"papermill":{"duration":0.668025,"end_time":"2021-10-16T10:11:58.550494","exception":false,"start_time":"2021-10-16T10:11:57.882469","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-10-17T10:41:56.902687Z","iopub.execute_input":"2021-10-17T10:41:56.902955Z","iopub.status.idle":"2021-10-17T10:41:57.522050Z","shell.execute_reply.started":"2021-10-17T10:41:56.902925Z","shell.execute_reply":"2021-10-17T10:41:57.521477Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cell_df = train_df.groupby(['cell_type'])['id'].count().reset_index(name='number_image')\n\nfig = go.Figure()\nfig.add_trace(go.Pie(values=cell_df.number_image, labels=cell_df.cell_type, hole=0.2, textinfo='label+value+percent'))\nfig.update_layout(\n    title={\n        'text': 'Distribution of cell type', 'font': {'color': 'blue', 'size': 16},\n        'y': 0.9, 'x': 0.5, 'xanchor': 'center', 'yanchor': 'top'\n    },\n    showlegend=False\n)\n    \nfig.show()\n\ndel cell_df\ngc.collect()","metadata":{"papermill":{"duration":0.324944,"end_time":"2021-10-16T10:11:58.885135","exception":false,"start_time":"2021-10-16T10:11:58.560191","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-10-17T10:41:57.523007Z","iopub.execute_input":"2021-10-17T10:41:57.523338Z","iopub.status.idle":"2021-10-17T10:41:57.789314Z","shell.execute_reply.started":"2021-10-17T10:41:57.523310Z","shell.execute_reply":"2021-10-17T10:41:57.788769Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"annot_df = train_df.pivot_table(index='id', columns='cell_type', values='annotation', aggfunc='count', fill_value=0).reset_index()\nannot_df['number_annot'] = annot_df[['astro', 'cort', 'shsy5y']].apply(np.sum, axis=1)\nannot_df['number_cell_type'] = annot_df[['astro', 'cort', 'shsy5y']].apply(lambda x: sum([1 if i!=0 else 0 for i in x]), axis=1)\n\ndisplay(annot_df.head())\ncell_types = ['astro', 'cort', 'shsy5y']\ncolors = ['#A56CC1', '#A6ACEC', '#63F5EF']\n\nastro = annot_df[annot_df.astro!=0].astro.values\ncort = annot_df[annot_df.cort!=0].cort.values\nshsy5y = annot_df[annot_df.shsy5y!=0].shsy5y.values\n\nfig = ff.create_distplot([astro, cort, shsy5y], cell_types, colors=colors, bin_size=5)\nfig.update_layout(\n    title={\n        'text': 'Distribution of cell type in each image', 'font': {'color': 'blue', 'size': 16},\n        'y': 0.9, 'x': 0.5, 'xanchor': 'center', 'yanchor': 'top'\n    }\n)\nfig.show()","metadata":{"papermill":{"duration":0.237856,"end_time":"2021-10-16T10:11:59.133820","exception":false,"start_time":"2021-10-16T10:11:58.895964","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-10-17T10:41:57.790362Z","iopub.execute_input":"2021-10-17T10:41:57.791241Z","iopub.status.idle":"2021-10-17T10:41:58.014718Z","shell.execute_reply.started":"2021-10-17T10:41:57.791208Z","shell.execute_reply":"2021-10-17T10:41:58.013755Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_image = glob.glob(f'{str(TRAIN_IMAGE_PATH)}/*.png')\ntrain_semi_image = glob.glob(f'{str(TRAIN_SEMI_PATH)}/*.png')\ntest_image = glob.glob(f'{str(TEST_IMAGE_PATH)}/*.png')\nprint(f'Train image: {len(train_image)}, train semi: {len(train_semi_image)}, test image: {len(test_image)}')","metadata":{"papermill":{"duration":0.305331,"end_time":"2021-10-16T10:11:59.452066","exception":false,"start_time":"2021-10-16T10:11:59.146735","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-10-17T10:41:58.016253Z","iopub.execute_input":"2021-10-17T10:41:58.016574Z","iopub.status.idle":"2021-10-17T10:41:58.449340Z","shell.execute_reply.started":"2021-10-17T10:41:58.016532Z","shell.execute_reply":"2021-10-17T10:41:58.448733Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Display image","metadata":{"papermill":{"duration":0.012532,"end_time":"2021-10-16T10:11:59.477660","exception":false,"start_time":"2021-10-16T10:11:59.465128","status":"completed"},"tags":[]}},{"cell_type":"code","source":"def display_image(df, image_folder, cell_type, number_sample=3):\n    \n    colors = {'astro': (249,38,114), 'cort': (166,226,46), 'shsy5y': (102,217,239)}\n    cell_df = df[df.cell_type==cell_type].reset_index(drop=True)\n    list_image = cell_df.id.unique()\n    for idx in range(number_sample):\n        image_id = np.random.choice(list_image)\n        sample_df = cell_df[cell_df.id==image_id].reset_index(drop=True)\n        image_path = [i for i in image_folder if image_id in i][0]\n        \n        #image display\n        img = cv2.imread(image_path)\n        fig, ax = plt.subplots(1, figsize=(30, 30))\n        overlay = img.copy()\n        \n        mask = np.zeros(img.shape[:-1], dtype=np.uint8)\n        for idx, rle in enumerate(sample_df.annotation):\n            mask += rle2mask(rle, img.shape[:-1]).astype(np.uint8)\n            \n        mask = mask.clip(0, 1)\n        mask_img = np.zeros_like(img)\n        mask_img[mask==1, :] = colors[cell_type]\n        final = cv2.addWeighted(mask_img, 0.5, img, 1, 0)\n            \n        ax.imshow(final)\n        plt.title(f'{cell_type}: {image_id}', fontsize=30, color='blue')\n        plt.show()\n    \nfor cell_type in cell_types:\n    display_image(train_df, train_image, cell_type, number_sample=3)","metadata":{"papermill":{"duration":13.620547,"end_time":"2021-10-16T10:12:13.111413","exception":false,"start_time":"2021-10-16T10:11:59.490866","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-10-17T10:43:38.349381Z","iopub.execute_input":"2021-10-17T10:43:38.349674Z","iopub.status.idle":"2021-10-17T10:43:51.756075Z","shell.execute_reply.started":"2021-10-17T10:43:38.349639Z","shell.execute_reply":"2021-10-17T10:43:51.755248Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Dataset","metadata":{}},{"cell_type":"code","source":"def aug(sub='train', size=(512, 512)):\n    if sub=='train':\n        return al.Compose([\n            al.HorizontalFlip(p=0.5),\n            al.VerticalFlip(p=0.5),\n            al.Transpose(p=0.5),\n            al.ShiftScaleRotate(shift_limit=0.0625, scale_limit=0.1, rotate_limit=45, p=0.5),\n            al.OneOf([\n                al.MotionBlur(p=0.3),\n                al.MedianBlur(p=0.3),\n                al.Blur(p=0.4)\n            ], p=0.3),\n            al.OneOf([\n                al.Sharpen(p=0.3),\n                al.Emboss(p=0.3),\n                al.RandomBrightnessContrast(p=0.4)\n            ], p=0.3),\n            al.Resize(size[0], size[1]),\n            al.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]),\n            ToTensorV2(transpose_mask=True)\n        ], p=1)\n    elif sub=='validation':\n        return al.Compose([\n            al.Resize(size[0], size[1]),\n            al.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]),\n            ToTensorV2(transpose_mask=True)\n        ], p=1)\n    elif sub=='test':\n        return al.Compose([\n            al.Resize(size[0], size[1]),\n            al.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]),\n            ToTensorV2()\n        ], p=1)","metadata":{"execution":{"iopub.status.busy":"2021-10-17T10:42:11.290812Z","iopub.execute_input":"2021-10-17T10:42:11.291240Z","iopub.status.idle":"2021-10-17T10:42:11.304347Z","shell.execute_reply.started":"2021-10-17T10:42:11.291204Z","shell.execute_reply":"2021-10-17T10:42:11.303393Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class sartoriousDataset(Dataset):\n    def __init__(self, df, image_folder, size, has_transforms, sub='train'):\n        super(sartoriousDataset, self).__init__()\n        \n        self.df = df\n        self.image_folder = image_folder\n        self.has_transforms = has_transforms\n        self.sub = sub\n        self.list_label = ['astro', 'cort', 'shsy5y']\n        if self.has_transforms:\n            self.transforms = aug(sub, size)\n        \n    def __len__(self):\n        return len(self.image_folder)\n    \n    def __getitem__(self, idx):\n        image_path = self.image_folder[idx]\n        image_id = image_path.split('/')[-1][:-4]\n        image_df = self.df[self.df.id==image_id].reset_index(drop=True)\n        image = cv2.imread(image_path)\n        h, w = image.shape[:-1]\n        \n        if self.sub != 'test':\n            mask = np.zeros([h, w], dtype=np.uint8)\n            for idx, (rle, label) in enumerate(zip(image_df.annotation, image_df.cell_type)):\n                mask += rle2mask(rle, [h, w]).astype(np.uint8)\n            mask = mask.clip(0, 1)\n            label = self.list_label.index(label)\n            if self.has_transforms:\n                augument = self.transforms(image=image, mask=mask)\n                image, mask = augument['image'], augument['mask']\n            else:\n                mask = torch.from_numpy(mask).float()\n            return image, mask, label\n        \n        if self.has_transforms:\n            image = self.transforms(image=image)['image']\n        else:\n            image = torch.from_numpy(image).float()\n        return image_id, image\n    \nbs = 4\ncolors = {'astro': (0.1, 0.1, 0.1), 'cort': (0.5, 0.5, 0.5), 'shsy5y': (0.8, 0.8, 0.8)}\nds = sartoriousDataset(train_df, train_image, (512, 512), has_transforms=True, sub='train')\ndl = DataLoader(ds, batch_size=bs, shuffle=True)\n\nimage, mask, label = next(iter(dl))\nimage = image.detach().cpu().numpy()\nmask = mask.detach().cpu().numpy()\nfig, ax = plt.subplots(1, bs, figsize=(30, 30))\nfor i in range(bs):\n    img = image[i].transpose(1, 2, 0)\n    img[(mask[i]==1), :] = colors[ds.list_label[label[i]]]\n    ax[i].imshow(img)\n    ax[i].set_title(f'{ds.list_label[label[i]]}')\n    \ndel ds, dl\ngc.collect()","metadata":{"execution":{"iopub.status.busy":"2021-10-17T10:43:01.623185Z","iopub.execute_input":"2021-10-17T10:43:01.623460Z","iopub.status.idle":"2021-10-17T10:43:03.378878Z","shell.execute_reply.started":"2021-10-17T10:43:01.623432Z","shell.execute_reply":"2021-10-17T10:43:03.377852Z"},"trusted":true},"execution_count":null,"outputs":[]}]}