{"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":"# Object 目的\n- Comprehensively check if the train data is correct and find all incorrect data.<br>\n網羅的にデータ誤りを確認して、全ての誤りデータを見つける。","metadata":{}},{"cell_type":"markdown","source":"# 0. Prepare Data and Visualization データ・可視化準備","metadata":{}},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nfrom glob import glob\nfrom PIL import Image\nimport os, shutil\nfrom tqdm import tqdm\ntqdm.pandas()\nimport tensorflow as tf\nfrom matplotlib.patches import Rectangle\nimport cv2\nimport math\nfrom IPython.core.interactiveshell import InteractiveShell\nInteractiveShell.ast_node_interactivity = \"all\"\nfrom IPython import display\nfrom pathlib import Path","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-07-12T06:16:12.880482Z","iopub.execute_input":"2022-07-12T06:16:12.882046Z","iopub.status.idle":"2022-07-12T06:16:12.891986Z","shell.execute_reply.started":"2022-07-12T06:16:12.881911Z","shell.execute_reply":"2022-07-12T06:16:12.890633Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train = pd.read_csv('../input/uw-madison-gi-tract-image-segmentation/train.csv')\ndf_train.rename(columns = {'class':'class_name'}, inplace = True)\n\n# id情報から、case, day, slice 情報を抜き出して列追加\ndf_train['case'] = df_train['id'].apply(lambda x: int(x.split('_')[0].replace('case', '')))\ndf_train['day'] = df_train['id'].apply(lambda x: int(x.split('_')[1].replace('day', '')))\ndf_train['slice'] = df_train['id'].apply(lambda x: x.split('_')[3])\n\n# path_partial：idから画像データの path 情報を部分的に作成（4つの数字が分からない）\nTRAIN_DIR='../input/uw-madison-gi-tract-image-segmentation/train'\nall_train_images = glob(os.path.join(TRAIN_DIR, '**', '*.png'), recursive=True)\nx = all_train_images[0].rsplit('/', 4)[0] ## ../input/uw-madison-gi-tract-image-segmentation/train\n\npath_partial_list = []\nfor i in range(0, df_train.shape[0]):\n    path_partial_list.append(os.path.join(x,\n                          'case'+str(df_train['case'].values[i]),\n                          'case'+str(df_train['case'].values[i])+'_'+ 'day'+str(df_train['day'].values[i]),\n                          'scans',\n                          'slice_'+str(df_train['slice'].values[i])))\ndf_train[\"path_partial\"] = path_partial_list\n\n# inputフォルダから、直接正しいpath情報を取得し、path_partialと対応付け\npath_partial_list = []\nfor i in range(0, len(all_train_images)):\n    path_partial_list.append(str(all_train_images[i].rsplit('_',4)[0]))\n    \ntmp_df = pd.DataFrame()\ntmp_df['path_partial'] = path_partial_list\ntmp_df['path'] = all_train_images\n\n# path 情報列追加\ndf_train = df_train.merge(tmp_df, on='path_partial').drop(columns=['path_partial'])\n\n# path の数値から、幅と高さの情報取得\ndf_train['width'] = df_train['path'].apply(lambda x: int(x[:-4].rsplit('_',4)[1]))\ndf_train['height'] = df_train['path'].apply(lambda x: int(x[:-4].rsplit('_',4)[2]))\ndf_train['width_space'] = df_train['path'].apply(lambda x: float(x[:-4].rsplit('_',4)[3]))\ndf_train['height_space'] = df_train['path'].apply(lambda x: float(x[:-4].rsplit('_',4)[4]))\n\ndel x,path_partial_list,tmp_df\n\ntmp_df = df_train\n\n# 同じidに対する、large_bowel, small_bowel, stomach の情報を1行にまとめる\ndf_train = pd.DataFrame({'id':tmp_df['id'][::3]})\n\ndf_train['large_bowel'] = tmp_df['segmentation'][::3].values\ndf_train['small_bowel'] = tmp_df['segmentation'][1::3].values\ndf_train['stomach'] = tmp_df['segmentation'][2::3].values\n\ndf_train['path'] = tmp_df['path'][::3].values\ndf_train['case'] = tmp_df['case'][::3].values\ndf_train['day'] = tmp_df['day'][::3].values\ndf_train['slice'] = tmp_df['slice'][::3].values\ndf_train['width'] = tmp_df['width'][::3].values\ndf_train['height'] = tmp_df['height'][::3].values\ndf_train['width_space'] = tmp_df['width_space'][::3].values\ndf_train['height_space'] = tmp_df['height_space'][::3].values\n\ndel tmp_df\n\ndf_train.reset_index(inplace=True,drop=True)\ndf_train.fillna('',inplace=True); \n# 各画像に対して、存在するラベル数をカウント\ndf_train['count'] = np.sum(df_train.iloc[:,1:4]!='',axis=1).values\n\ndf_train2 = df_train","metadata":{"execution":{"iopub.status.busy":"2022-07-12T06:16:13.301487Z","iopub.execute_input":"2022-07-12T06:16:13.302008Z","iopub.status.idle":"2022-07-12T06:16:19.582545Z","shell.execute_reply.started":"2022-07-12T06:16:13.301967Z","shell.execute_reply":"2022-07-12T06:16:19.581550Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def show_label_slice(df, CASE, DAY):\n    fig = plt.figure(figsize=(6,4))\n    ax = fig.add_subplot(1,1,1)\n    plt.scatter(x=df['label'], y=df['slice'], alpha=1, s=2)\n    plt.title('case {} day {}'.format(CASE, DAY))\n    plt.xticks([0, 1, 2], ['large_bowel','small_bowel','stomach'])\n    plt.xlabel('')\n    plt.ylabel('slice')\n    plt.xlim(-0.5,2.5)\n    plt.ylim(0,int(df_train[(df_train['case']==CASE) & (df_train['day']==DAY)]['slice'].max()))\n    ax.invert_yaxis()\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2022-07-12T06:16:19.584177Z","iopub.execute_input":"2022-07-12T06:16:19.584701Z","iopub.status.idle":"2022-07-12T06:16:19.593012Z","shell.execute_reply.started":"2022-07-12T06:16:19.584664Z","shell.execute_reply":"2022-07-12T06:16:19.591643Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def rle_decode(mask_rle, shape):\n    '''\n    mask_rle: run-length as string formated (start length)\n    shape: (height,width) of array to return \n    Returns numpy array, 1 - mask, 0 - background\n\n    '''\n    s = np.asarray(mask_rle.split(), dtype=int)\n    starts = s[0::2] - 1\n    lengths = s[1::2]\n    ends = starts + lengths\n    img = np.zeros(shape[0]*shape[1], dtype=np.uint8)\n    for lo, hi in zip(starts, ends):\n        img[lo:hi] = 1\n    return img.reshape(shape) \n\ndef rle_encode(img):\n    '''\n    img: numpy array, 1 - mask, 0 - background\n    Returns run length as string formated\n    '''\n    pixels = img.flatten()\n    pixels = np.concatenate([[0], pixels, [0]])\n    runs = np.where(pixels[1:] != pixels[:-1])[0] + 1\n    runs[1::2] -= runs[::2]\n    return ' '.join(str(x) for x in runs)","metadata":{"execution":{"iopub.status.busy":"2022-07-12T06:16:19.595265Z","iopub.execute_input":"2022-07-12T06:16:19.595798Z","iopub.status.idle":"2022-07-12T06:16:19.612014Z","shell.execute_reply.started":"2022-07-12T06:16:19.595748Z","shell.execute_reply":"2022-07-12T06:16:19.611068Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_metadata(row):\n    data = row['id'].split('_')\n    case = int(data[0].replace('case',''))\n    day = int(data[1].replace('day',''))\n    slice_ = int(data[-1])\n    row['case'] = case\n    row['day'] = day\n    row['slice'] = slice_\n    return row\n\ndef path2info(row):\n    path = row['image_path']\n    data = path.split('/')\n    slice_ = int(data[-1].split('_')[1])\n    case = int(data[-3].split('_')[0].replace('case',''))\n    day = int(data[-3].split('_')[1].replace('day',''))\n    width = int(data[-1].split('_')[2])\n    height = int(data[-1].split('_')[3])\n    row['height'] = height\n    row['width'] = width\n    row['case'] = case\n    row['day'] = day\n    row['slice'] = slice_\n    return row\n","metadata":{"execution":{"iopub.status.busy":"2022-07-12T06:16:19.614751Z","iopub.execute_input":"2022-07-12T06:16:19.615727Z","iopub.status.idle":"2022-07-12T06:16:19.628144Z","shell.execute_reply.started":"2022-07-12T06:16:19.615672Z","shell.execute_reply":"2022-07-12T06:16:19.627193Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def id2mask(id_):\n    idf = df_train[df_train['id']==id_]\n    wh = idf[['height','width']].iloc[0]\n    shape = (wh.height, wh.width, 3)\n    mask = np.zeros(shape, dtype=np.uint8)\n    for i, class_ in enumerate(['large_bowel', 'small_bowel', 'stomach']):\n        cdf = idf[idf['class']==class_]\n        rle = cdf.segmentation.squeeze()\n        if len(cdf) and not pd.isna(rle):\n            mask[..., i] = rle_decode(rle, shape[:2])\n    return mask\n\ndef id2maskduplicated(id_):\n    idf = df_train[df_train['id']==id_]\n    wh = idf[['height','width']].iloc[0]\n    shape = (wh.height, wh.width, 3)\n    maskduplicated = np.zeros(shape, dtype=np.uint8)\n    tmp = np.zeros(shape, dtype=np.uint8)\n    for i, class_ in enumerate(['large_bowel', 'small_bowel', 'stomach']):\n        cdf = idf[idf['class']==class_]\n        rle = cdf.segmentation.squeeze()\n        if len(cdf) and not pd.isna(rle):\n            tmp[..., i] = rle_decode(rle, shape[:2])\n    maskduplicated[...,0] = tmp[..., 0] * tmp[..., 1] + tmp[..., 1] * tmp[..., 2] + tmp[..., 2] * tmp[..., 0]\n    maskduplicated[...,1] = tmp[..., 0] * tmp[..., 1] + tmp[..., 1] * tmp[..., 2] + tmp[..., 2] * tmp[..., 0]\n    return maskduplicated\n\ndef rgb2gray(mask):\n    pad_mask = np.pad(mask, pad_width=[(0,0),(0,0),(1,0)])\n    gray_mask = pad_mask.argmax(-1)\n    return gray_mask\n\ndef gray2rgb(mask):\n    rgb_mask = tf.keras.utils.to_categorical(mask, num_classes=4)\n    return rgb_mask[..., 1:].astype(mask.dtype)","metadata":{"execution":{"iopub.status.busy":"2022-07-12T06:16:19.629570Z","iopub.execute_input":"2022-07-12T06:16:19.630453Z","iopub.status.idle":"2022-07-12T06:16:19.648610Z","shell.execute_reply.started":"2022-07-12T06:16:19.630407Z","shell.execute_reply":"2022-07-12T06:16:19.647643Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def load_img(path):\n    img = cv2.imread(path, cv2.IMREAD_UNCHANGED)\n    img = img.astype('float32') \n    img = (img - img.min())/(img.max() - img.min())*255.0 \n    img = img.astype('uint8')\n    return img\n\ndef display_xy_imgs_masked(case, day, slice_list, df_train):\n    # train画像のpath取得\n    TRAIN_DIR='../input/uw-madison-gi-tract-image-segmentation/train/case'+str(case)+'/case'+str(case)+'_day'+str(day)+'/scans/'\n    train_images = glob(os.path.join(TRAIN_DIR, '**', '*.png'), recursive=True)\n    train_images = sorted(train_images)\n\n    # 画像表示\n    i=1\n    plt.figure(figsize=(40,10 * math.ceil(len(slice_list)/5)))\n    for slice_i in slice_list:\n        path = train_images[slice_i-1]\n        img = load_img(path)\n        mask = id2mask(df_train[df_train['image_path']==path].iloc[0,0])*255\n        #print(df_train[df_train['image_path']==path].iloc[0,0])\n        clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))\n        img = clahe.apply(img)\n        plt.subplot(math.ceil(len(slice_list)/5),5,i)\n        plt.imshow(img, cmap='gray')\n        if mask is not None:\n            plt.imshow(mask, alpha=0.5)\n            handles = [Rectangle((0,0),1,1, color=_c) for _c in [(0.667,0.0,0.0), (0.0,0.667,0.0), (0.0,0.0,0.667)]]\n            labels = [ \"Large Bowel\", \"Small Bowel\", \"Stomach\"]\n            plt.legend(handles,labels)\n        #plt.axis('off')\n        plt.title('slice {}'.format(slice_i))\n        #plt.tight_layout()\n        i+=1\n    plt.show()\n    \ndef display_xy_imgs_masked_duplicated(path_list):\n    # 画像表示\n    i=1\n    plt.figure(figsize=(40,10 * math.ceil(len(path_list)/5)))\n    for path in path_list:\n        img = load_img(path)\n        mask = id2mask(df_train[df_train['image_path']==path].iloc[0,0])*255\n        maskdupulicated = id2maskduplicated(df_train[df_train['image_path']==path].iloc[0,0])*255\n        #print(df_train[df_train['image_path']==path].iloc[0,0])\n        clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))\n        img = clahe.apply(img)\n        plt.subplot(math.ceil(len(path_list)/5),5,i)\n        plt.imshow(img, cmap='gray')\n        if mask is not None:\n            plt.imshow(mask, alpha=0.3)\n            plt.imshow(maskdupulicated, alpha=0.5)\n            handles = [Rectangle((0,0),1,1, color=_c) for _c in [(0.667,0.0,0.0), (0.0,0.667,0.0), (0.0,0.0,0.667), (0.667,0.667,0.0)]]\n            labels = [ \"Large Bowel\", \"Small Bowel\", \"Stomach\",\"Mask Duplicated\"]\n            plt.legend(handles,labels)\n        plt.axis('off')\n        \n        plt.title(df_train[df_train['image_path']==path].iloc[0,0], size='xx-large')\n        #plt.tight_layout()\n        i+=1\n    plt.show()\n\ndef display_xy_five_imgs_duplicated(case, day, slice_num):\n    # train画像のpath取得\n    TRAIN_DIR='../input/uw-madison-gi-tract-image-segmentation/train/case'+str(case)+'/case'+str(case)+'_day'+str(day)+'/scans/'\n    train_images = glob(os.path.join(TRAIN_DIR, '**', '*.png'), recursive=True)\n    train_images = sorted(train_images)\n    # 画像表示\n    i=0\n    fig, ax = plt.subplots(1,5,figsize=(40,10))\n    for slice_i in range(slice_num-3,slice_num+2):\n        path = train_images[slice_i]\n        img = load_img(path)\n        mask = id2mask(df_train[df_train['image_path']==path].iloc[0,0])*255\n        maskdupulicated = id2maskduplicated(df_train[df_train['image_path']==path].iloc[0,0])*255\n        #print(df_train[df_train['image_path']==path].iloc[0,0])\n        clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))\n        img = clahe.apply(img)\n        ax[i].imshow(img, cmap='gray')\n        if mask is not None:\n            ax[i].imshow(mask, alpha=0.3)\n            ax[i].imshow(maskdupulicated, alpha=0.5)\n            handles = [Rectangle((0,0),1,1, color=_c) for _c in [(0.667,0.0,0.0), (0.0,0.667,0.0), (0.0,0.0,0.667), (0.667,0.667,0.0)]]\n            labels = [ \"Large Bowel\", \"Small Bowel\", \"Stomach\",\"Mask Duplicated\"]\n            ax[i].legend(handles,labels)\n        ax[i].axis('off')\n        if i == 2:\n            ax[i].set_title('slice {}'.format(slice_i+1), color='red', size='xx-large')\n        else:\n            ax[i].set_title('slice {}'.format(slice_i+1), color='black', size='xx-large')\n        i+=1\n    plt.show()\n    \ndef display_xy_five_imgs(case, day, slice_num):\n    # train画像のpath取得\n    TRAIN_DIR='../input/uw-madison-gi-tract-image-segmentation/train/case'+str(case)+'/case'+str(case)+'_day'+str(day)+'/scans/'\n    train_images = glob(os.path.join(TRAIN_DIR, '**', '*.png'), recursive=True)\n    train_images = sorted(train_images)\n    # 画像表示\n    i=0\n    fig, ax = plt.subplots(1,5,figsize=(40,10))\n    for slice_i in range(slice_num-3,slice_num+2):\n        path = train_images[slice_i]\n        img = load_img(path)\n        mask = id2mask(df_train[df_train['image_path']==path].iloc[0,0])*255\n        maskdupulicated = id2maskduplicated(df_train[df_train['image_path']==path].iloc[0,0])*255\n        #print(df_train[df_train['image_path']==path].iloc[0,0])\n        clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))\n        img = clahe.apply(img)\n        ax[i].imshow(img, cmap='gray')\n        if mask is not None:\n            ax[i].imshow(mask, alpha=0.5)\n            handles = [Rectangle((0,0),1,1, color=_c) for _c in [(0.667,0.0,0.0), (0.0,0.667,0.0), (0.0,0.0,0.667)]]\n            labels = [ \"Large Bowel\", \"Small Bowel\", \"Stomach\"]\n            ax[i].legend(handles,labels)\n        ax[i].axis('off')\n        if i == 2:\n            ax[i].set_title('slice {}'.format(slice_i+1), color='red', size='xx-large')\n        else:\n            ax[i].set_title('slice {}'.format(slice_i+1), color='black', size='xx-large')\n        i+=1\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2022-07-12T06:16:19.650941Z","iopub.execute_input":"2022-07-12T06:16:19.652041Z","iopub.status.idle":"2022-07-12T06:16:19.700321Z","shell.execute_reply.started":"2022-07-12T06:16:19.651962Z","shell.execute_reply":"2022-07-12T06:16:19.698692Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train = pd.read_csv('../input/uw-madison-gi-tract-image-segmentation/train.csv')\ndf_train = df_train.progress_apply(get_metadata, axis=1)\npaths = glob('../input/uw-madison-gi-tract-image-segmentation/train/*/*/*/*')\npath_df = pd.DataFrame(paths, columns=['image_path'])\npath_df = path_df.progress_apply(path2info, axis=1)\ndf_train = df_train.merge(path_df, on=['case','day','slice'])","metadata":{"execution":{"iopub.status.busy":"2022-07-12T06:16:19.701783Z","iopub.execute_input":"2022-07-12T06:16:19.702769Z","iopub.status.idle":"2022-07-12T06:21:27.979609Z","shell.execute_reply.started":"2022-07-12T06:16:19.702727Z","shell.execute_reply":"2022-07-12T06:21:27.978176Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 1. Mask Nothing マスクが存在しない","metadata":{}},{"cell_type":"code","source":"# count mask slices by the case-day\ndf_label_exist = df_train2[['case','day','large_bowel','small_bowel','stomach']].copy()\ndf_label_exist['large_bowel'] = df_label_exist['large_bowel'] != ''\ndf_label_exist['small_bowel'] = df_label_exist['small_bowel'] != ''\ndf_label_exist['stomach'] = df_label_exist['stomach'] != ''\ndf_label_exist = df_label_exist.groupby(['case','day']).sum()\ndf_label_exist.head()","metadata":{"execution":{"iopub.status.busy":"2022-07-12T06:21:27.981098Z","iopub.execute_input":"2022-07-12T06:21:27.981473Z","iopub.status.idle":"2022-07-12T06:21:28.047459Z","shell.execute_reply.started":"2022-07-12T06:21:27.981441Z","shell.execute_reply":"2022-07-12T06:21:28.046658Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_label_exist[df_label_exist['large_bowel']*df_label_exist['small_bowel']*df_label_exist['stomach']==0]","metadata":{"execution":{"iopub.status.busy":"2022-07-12T06:21:28.048560Z","iopub.execute_input":"2022-07-12T06:21:28.049370Z","iopub.status.idle":"2022-07-12T06:21:28.061852Z","shell.execute_reply.started":"2022-07-12T06:21:28.049330Z","shell.execute_reply":"2022-07-12T06:21:28.061093Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"##### case43 day26\nOne kind of mask does not exist.<br>\nマスクが一つ存在しない。","metadata":{"execution":{"iopub.status.busy":"2022-06-27T03:09:17.529877Z","iopub.execute_input":"2022-06-27T03:09:17.530517Z","iopub.status.idle":"2022-06-27T03:09:17.539636Z","shell.execute_reply.started":"2022-06-27T03:09:17.530463Z","shell.execute_reply":"2022-06-27T03:09:17.538114Z"}}},{"cell_type":"code","source":"case = 43\n\npath_list = glob('../input/umdgi-gif-animation-of-3d-mask-image/case'+str(case)+'*')\npath_list.sort()\nfor path in path_list:\n    with open(Path(path),'rb') as f: display.Image(data=f.read(), format='png')","metadata":{"execution":{"iopub.status.busy":"2022-07-12T06:21:28.064511Z","iopub.execute_input":"2022-07-12T06:21:28.065639Z","iopub.status.idle":"2022-07-12T06:21:28.358738Z","shell.execute_reply.started":"2022-07-12T06:21:28.065580Z","shell.execute_reply":"2022-07-12T06:21:28.356972Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"##### case43 day26\nOnly on day26 no large_bowel mask is present.<br>\nIs it possible that the large_bowel was removed?<br>\n同じ case43 の中でも、day26のみ大腸のマスクが存在しない。<br>\n大腸を切除した可能性もある？","metadata":{}},{"cell_type":"markdown","source":"# 2. Masks Overlap マスクの重複","metadata":{}},{"cell_type":"code","source":"dTRAIN_DIR='../input/uw-madison-gi-tract-image-segmentation/train/'\ntrain_images = glob(os.path.join(TRAIN_DIR, '**', '*.png'), recursive=True)\ntrain_images = sorted(train_images)\n\npath_list = []\nfor path in tqdm(train_images):\n    mask = id2mask(df_train[df_train['image_path']==path].iloc[0,0])\n    #print(mask.sum(axis=2).max())\n    if mask.sum(axis=2).max() > 1:\n        mask_area = (mask[...,0]*mask[...,1]).sum()+(mask[...,1]*mask[...,2]).sum()+(mask[...,2]*mask[...,0]).sum()\n        path_list.append([path,mask_area])\ndf_mask_area = pd.DataFrame(path_list,columns=['path','mask_area'])","metadata":{"execution":{"iopub.status.busy":"2022-07-12T06:21:28.360596Z","iopub.execute_input":"2022-07-12T06:21:28.360957Z","iopub.status.idle":"2022-07-12T06:49:37.291097Z","shell.execute_reply.started":"2022-07-12T06:21:28.360925Z","shell.execute_reply":"2022-07-12T06:49:37.290098Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_mask_area.describe()","metadata":{"execution":{"iopub.status.busy":"2022-07-12T06:49:37.292620Z","iopub.execute_input":"2022-07-12T06:49:37.292956Z","iopub.status.idle":"2022-07-12T06:49:37.311184Z","shell.execute_reply.started":"2022-07-12T06:49:37.292922Z","shell.execute_reply":"2022-07-12T06:49:37.310106Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"4,225 slice images (about 11.0%) with overlapping mask regions<br>\nIgnore small pixels overlap and narrow down the target to be checked from the histogram.<br>\nマスク領域が重複しているスライス画像は、4,225枚（約11.0%）<br>\n多少の重複は無視するとして、ヒストグラムから確認する対象を絞る。","metadata":{}},{"cell_type":"code","source":"df_mask_area['mask_area'].hist(bins=100)","metadata":{"execution":{"iopub.status.busy":"2022-07-12T06:49:37.312571Z","iopub.execute_input":"2022-07-12T06:49:37.313352Z","iopub.status.idle":"2022-07-12T06:49:37.689492Z","shell.execute_reply.started":"2022-07-12T06:49:37.313299Z","shell.execute_reply":"2022-07-12T06:49:37.688250Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Check the slice images (21 slices) with a mask overlap area of 200 pixels or more.<br>\nマスク重複領域が200ピクセル以上のスライス画像（21枚）を確認する。","metadata":{"execution":{"iopub.status.busy":"2022-06-28T01:43:10.135316Z","iopub.execute_input":"2022-06-28T01:43:10.136195Z","iopub.status.idle":"2022-06-28T01:43:10.142259Z","shell.execute_reply.started":"2022-06-28T01:43:10.136153Z","shell.execute_reply":"2022-06-28T01:43:10.140876Z"}}},{"cell_type":"code","source":"path_list = df_mask_area[df_mask_area['mask_area']>=200]['path'].tolist()\ndisplay_xy_imgs_masked_duplicated(path_list)","metadata":{"execution":{"iopub.status.busy":"2022-07-12T06:49:37.691186Z","iopub.execute_input":"2022-07-12T06:49:37.692376Z","iopub.status.idle":"2022-07-12T06:49:54.478369Z","shell.execute_reply.started":"2022-07-12T06:49:37.692322Z","shell.execute_reply":"2022-07-12T06:49:54.477313Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Some of the exact same organs are covered by two different masks.<br>\nThe following is a look at the incorrect slices along with the before and after slice images.<br>\n少しマスク領域が被っているものから、全く同じ臓器に2種類のマスクがかぶっているものまで様々。<br>\n以下、誤りデータについて前後のスライス情報とともに見ていく。","metadata":{}},{"cell_type":"code","source":"display_xy_five_imgs_duplicated(111,0,113)","metadata":{"execution":{"iopub.status.busy":"2022-07-12T06:49:54.479724Z","iopub.execute_input":"2022-07-12T06:49:54.480059Z","iopub.status.idle":"2022-07-12T06:49:56.101921Z","shell.execute_reply.started":"2022-07-12T06:49:54.480025Z","shell.execute_reply":"2022-07-12T06:49:56.100618Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"##### case111 day0 Slice113\nThe large_bowel and small_bowel intestine overlap. Boundary between large_bowel and large_bowel intestine is disjointed from slice to slice.<br>\n大腸と小腸が重複。重複箇所以外も大腸と小腸の境界がスライスごとにばらばら。","metadata":{}},{"cell_type":"code","source":"display_xy_five_imgs_duplicated(133,0,109)","metadata":{"execution":{"iopub.status.busy":"2022-07-12T06:49:56.103517Z","iopub.execute_input":"2022-07-12T06:49:56.103936Z","iopub.status.idle":"2022-07-12T06:49:57.666532Z","shell.execute_reply.started":"2022-07-12T06:49:56.103897Z","shell.execute_reply":"2022-07-12T06:49:57.665452Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"##### case133 day0 Slice109\nThe large_bowel and small_bowel intestine overlap. The mask changes from large_bowel to small_bowel.<br>\n大腸と小腸が重複。途中まで大腸だったエリアが小腸に変わる。","metadata":{}},{"cell_type":"code","source":"case = 16\nday  = 0\n\npath = '../input/umdgi-gif-animation-of-3d-mask-image/case'+str(case)+'_'+'day'+str(day)+'.gif'\nwith open(Path(path),'rb') as f: display.Image(data=f.read(), format='png')","metadata":{"execution":{"iopub.status.busy":"2022-07-12T06:49:57.668100Z","iopub.execute_input":"2022-07-12T06:49:57.668497Z","iopub.status.idle":"2022-07-12T06:49:57.779817Z","shell.execute_reply.started":"2022-07-12T06:49:57.668465Z","shell.execute_reply":"2022-07-12T06:49:57.778291Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"##### case16 day0 slice41~47\nThe mask changes from stomach to small_bowel.<br>\n途中まで胃だったエリアが小腸に変わる。","metadata":{}},{"cell_type":"code","source":"display_xy_five_imgs_duplicated(33,21,126)","metadata":{"execution":{"iopub.status.busy":"2022-07-12T06:49:57.781613Z","iopub.execute_input":"2022-07-12T06:49:57.782743Z","iopub.status.idle":"2022-07-12T06:49:59.428622Z","shell.execute_reply.started":"2022-07-12T06:49:57.782672Z","shell.execute_reply":"2022-07-12T06:49:59.427225Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"##### case33 day21 slice126\nThe area of the large_bowel overlaps the area of the small_bowel.<br>\n小腸のエリアに大腸のエリアが重なる。","metadata":{"execution":{"iopub.status.busy":"2022-06-29T06:29:53.171398Z","iopub.execute_input":"2022-06-29T06:29:53.172123Z","iopub.status.idle":"2022-06-29T06:29:53.177707Z","shell.execute_reply.started":"2022-06-29T06:29:53.172083Z","shell.execute_reply":"2022-06-29T06:29:53.176427Z"}}},{"cell_type":"code","source":"case = 44\nday  = 19\n\npath = '../input/umdgi-gif-animation-of-3d-mask-image/case'+str(case)+'_'+'day'+str(day)+'.gif'\nwith open(Path(path),'rb') as f: display.Image(data=f.read(), format='png')","metadata":{"execution":{"iopub.status.busy":"2022-07-12T06:49:59.430110Z","iopub.execute_input":"2022-07-12T06:49:59.430469Z","iopub.status.idle":"2022-07-12T06:49:59.526768Z","shell.execute_reply.started":"2022-07-12T06:49:59.430437Z","shell.execute_reply":"2022-07-12T06:49:59.525187Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"##### case44 day19 slice86~89\nThe area of the small_bowel overlaps the area of the large_bowel.<br>\n大腸の領域に小腸が重複。","metadata":{}},{"cell_type":"code","source":"case = 65\nday  = 28\n\npath = '../input/umdgi-gif-animation-of-3d-mask-image/case'+str(case)+'_'+'day'+str(day)+'.gif'\nwith open(Path(path),'rb') as f: display.Image(data=f.read(), format='png')","metadata":{"execution":{"iopub.status.busy":"2022-07-12T06:49:59.529174Z","iopub.execute_input":"2022-07-12T06:49:59.529857Z","iopub.status.idle":"2022-07-12T06:49:59.637305Z","shell.execute_reply.started":"2022-07-12T06:49:59.529819Z","shell.execute_reply":"2022-07-12T06:49:59.636185Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"##### case65 day28 slice109~116\nThe stomach and small_bowel overlap.<br>\n胃と小腸が重複。","metadata":{}},{"cell_type":"code","source":"case = 84\nday  = 0\n\npath = '../input/umdgi-gif-animation-of-3d-mask-image/case'+str(case)+'_'+'day'+str(day)+'.gif'\nwith open(Path(path),'rb') as f: display.Image(data=f.read(), format='png')","metadata":{"execution":{"iopub.status.busy":"2022-07-12T06:49:59.638727Z","iopub.execute_input":"2022-07-12T06:49:59.639930Z","iopub.status.idle":"2022-07-12T06:49:59.779276Z","shell.execute_reply.started":"2022-07-12T06:49:59.639879Z","shell.execute_reply":"2022-07-12T06:49:59.777336Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"##### case84 day0 slice121~124\nThe area of the large_bowel overlaps the area of the small_bowel.<br>\n小腸の領域に大腸が重複","metadata":{}},{"cell_type":"markdown","source":"# 3. Non-Continuous Mask 非連続なマスク","metadata":{}},{"cell_type":"code","source":"df_label_exist = df_train2[['case','day','slice','large_bowel','small_bowel','stomach']].sort_values(['case','day']).reset_index().drop('index',axis=1)\ndf_label_exist['large_bowel'] = ~df_label_exist['large_bowel'].isin([''])\ndf_label_exist['small_bowel'] = ~df_label_exist['small_bowel'].isin([''])\ndf_label_exist['stomach'] = ~df_label_exist['stomach'].isin([''])\ndf_label_exist_shift = df_label_exist.shift()\ndf_label_exist['large_bowel_appear_disapear'] = (df_label_exist['large_bowel'] != df_label_exist_shift['large_bowel'])\ndf_label_exist['small_bowel_appear_disapear'] = (df_label_exist['small_bowel'] != df_label_exist_shift['small_bowel'])\ndf_label_exist['stomach_appear_disapear'] = (df_label_exist['stomach'] != df_label_exist_shift['stomach'])\ndf_label_exist.iloc[0,6:]=False\ndf_label_exist = df_label_exist.groupby(['case', 'day']).sum()","metadata":{"execution":{"iopub.status.busy":"2022-07-12T06:49:59.780849Z","iopub.execute_input":"2022-07-12T06:49:59.781269Z","iopub.status.idle":"2022-07-12T06:49:59.865428Z","shell.execute_reply.started":"2022-07-12T06:49:59.781231Z","shell.execute_reply":"2022-07-12T06:49:59.864417Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_label_exist[(df_label_exist['large_bowel_appear_disapear'] > 2) |(df_label_exist['small_bowel_appear_disapear'] > 2)| (df_label_exist['stomach_appear_disapear'] > 2) ]","metadata":{"execution":{"iopub.status.busy":"2022-07-12T06:49:59.866640Z","iopub.execute_input":"2022-07-12T06:49:59.866971Z","iopub.status.idle":"2022-07-12T06:49:59.882974Z","shell.execute_reply.started":"2022-07-12T06:49:59.866940Z","shell.execute_reply":"2022-07-12T06:49:59.881900Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"View the slices in succession and count the number of times the mask appears or disappears.<br>\nA count greater than 2 indicates that the mask is non-continuous.<br>\nカウントが2を超えるものは、スライスを上から見ていって、ラベルが消えてまた出現することを示す。","metadata":{}},{"cell_type":"code","source":"case = 7\nday  = 0\n\npath = '../input/umdgi-gif-animation-of-3d-mask-image/case'+str(case)+'_'+'day'+str(day)+'.gif'\nwith open(Path(path),'rb') as f: display.Image(data=f.read(), format='png')","metadata":{"execution":{"iopub.status.busy":"2022-07-12T06:49:59.884151Z","iopub.execute_input":"2022-07-12T06:49:59.884734Z","iopub.status.idle":"2022-07-12T06:50:00.000821Z","shell.execute_reply.started":"2022-07-12T06:49:59.884701Z","shell.execute_reply":"2022-07-12T06:49:59.999904Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"##### case7 day0\nThe mask of the stomach is non-continuous. Prior to that, all mask positions did not match the MRI image.<br>\n胃が2回点滅する。それ以前に全てのマスク位置がMRI画像と合っていない。","metadata":{}},{"cell_type":"code","source":"display_xy_five_imgs(15,0,56)","metadata":{"execution":{"iopub.status.busy":"2022-07-12T06:50:00.002204Z","iopub.execute_input":"2022-07-12T06:50:00.003142Z","iopub.status.idle":"2022-07-12T06:50:01.436922Z","shell.execute_reply.started":"2022-07-12T06:50:00.003042Z","shell.execute_reply":"2022-07-12T06:50:01.435651Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"##### case15 day0\nThe large_bowel breaks off in the middle, and three slices later, the large_bowel appears from a different position.<br>\n大腸が途中で切れて、3スライス後、別の位置から大腸が出現する。","metadata":{}},{"cell_type":"code","source":"display_xy_five_imgs(43,18,38)","metadata":{"execution":{"iopub.status.busy":"2022-07-12T06:50:01.438477Z","iopub.execute_input":"2022-07-12T06:50:01.438850Z","iopub.status.idle":"2022-07-12T06:50:02.854713Z","shell.execute_reply.started":"2022-07-12T06:50:01.438815Z","shell.execute_reply":"2022-07-12T06:50:02.853856Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"##### case43 day18 slice38\nIncorrect large_bowel mask exist.<br>\n誤った大腸が存在。","metadata":{"execution":{"iopub.status.busy":"2022-07-02T13:18:42.467065Z","iopub.execute_input":"2022-07-02T13:18:42.467524Z","iopub.status.idle":"2022-07-02T13:18:42.474653Z","shell.execute_reply.started":"2022-07-02T13:18:42.467487Z","shell.execute_reply":"2022-07-02T13:18:42.473335Z"}}},{"cell_type":"code","source":"display_xy_five_imgs(124,19,74)","metadata":{"execution":{"iopub.status.busy":"2022-07-12T06:50:02.856047Z","iopub.execute_input":"2022-07-12T06:50:02.857333Z","iopub.status.idle":"2022-07-12T06:50:04.255648Z","shell.execute_reply.started":"2022-07-12T06:50:02.857290Z","shell.execute_reply":"2022-07-12T06:50:04.254660Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"##### case124 day 19 slice74\nThe stomach mask is disconnected.<br>\n胃のマスクが途切れている。","metadata":{}},{"cell_type":"code","source":"case = 138\nday  = 0\n\npath = '../input/umdgi-gif-animation-of-3d-mask-image/case'+str(case)+'_'+'day'+str(day)+'.gif'\nwith open(Path(path),'rb') as f: display.Image(data=f.read(), format='png')","metadata":{"execution":{"iopub.status.busy":"2022-07-12T06:50:04.259990Z","iopub.execute_input":"2022-07-12T06:50:04.260522Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"##### case138 day0\nThe large_bowel mask is repeatedly disconnected.<br>\n大腸のマスクが何度も途切れている。","metadata":{}},{"cell_type":"code","source":"display_xy_five_imgs(144,15,97)","metadata":{"execution":{"iopub.status.busy":"2022-07-12T07:09:20.015925Z","iopub.execute_input":"2022-07-12T07:09:20.016416Z","iopub.status.idle":"2022-07-12T07:09:21.381722Z","shell.execute_reply.started":"2022-07-12T07:09:20.016380Z","shell.execute_reply":"2022-07-12T07:09:21.380202Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"##### case144 day15 slice97,98\nThe large_bowel mask is disconnected.<br>\n大腸のラベルが途切れている。","metadata":{}},{"cell_type":"markdown","source":"# 4. Others その他","metadata":{}},{"cell_type":"code","source":"display_xy_five_imgs(2,1,80)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"##### case2 day1 slice80\nThe large_bowel exists outside the body (Right side of the image).<br>\n大腸が身体の外（画像の右端）に存在する。","metadata":{"execution":{"iopub.status.busy":"2022-07-02T14:30:25.376078Z","iopub.execute_input":"2022-07-02T14:30:25.376488Z","iopub.status.idle":"2022-07-02T14:30:25.383804Z","shell.execute_reply.started":"2022-07-02T14:30:25.376456Z","shell.execute_reply":"2022-07-02T14:30:25.382398Z"}}},{"cell_type":"code","source":"display_xy_five_imgs(2,1,84)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"##### case2 day1\nThe boundary between the stomach and small_bowel is blurred.<br>\n胃と小腸の境界があいまい。","metadata":{}},{"cell_type":"code","source":"display_xy_five_imgs(6,24,94)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"##### case6 day24 slice94\nOnly this slice is the small_bowel, and the next and subsequent slices are the large_bowel.<br>\nこのスライスのみ小腸で、次のスライス以降は大腸","metadata":{"execution":{"iopub.status.busy":"2022-07-02T14:53:29.358731Z","iopub.execute_input":"2022-07-02T14:53:29.359665Z","iopub.status.idle":"2022-07-02T14:53:29.365762Z","shell.execute_reply.started":"2022-07-02T14:53:29.359616Z","shell.execute_reply":"2022-07-02T14:53:29.364817Z"}}},{"cell_type":"code","source":"display_xy_five_imgs(11,13,77)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"##### case11 day13 slice77\nThe stomach turns into the small_bowel.<br>\n胃が小腸に変わる","metadata":{}},{"cell_type":"code","source":"display_xy_five_imgs(15,20,57)\ndisplay_xy_five_imgs(15,20,62)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"##### case15 day20 slice58~61\nA small independent large_bowel is present.<br>\n独立した小さな大腸が存在。","metadata":{}},{"cell_type":"code","source":"display_xy_five_imgs(16,0,71)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"##### case16 day0 slice71,73\nThe large_bowel and small_bowel overlap.<br>\n大腸と小腸が重複","metadata":{}},{"cell_type":"code","source":"display_xy_five_imgs(18,0,89)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"##### case18 day0 slice89\nThe large_bowel and small_bowel overlap.<br>\n大腸と小腸が重複","metadata":{}},{"cell_type":"code","source":"display_xy_five_imgs(18,17,110)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"##### case18 day17 slice110\nThe large_bowel and small_bowel overlap.<br>\n大腸と小腸が重複","metadata":{}},{"cell_type":"code","source":"display_xy_five_imgs(41,25,100)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"##### case41 day25 slice100\nThe large_bowel and small_bowel overlap.<br>\n大腸と小腸が重複","metadata":{}},{"cell_type":"code","source":"display_xy_five_imgs(43,18,89)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"##### case43 day18 slice89\nThe large_bowel and small_bowel overlap.<br>\n大腸と小腸が重複","metadata":{}},{"cell_type":"code","source":"display_xy_five_imgs(43,22,111)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"##### case43 day22 slice111\nThe large_bowel and small_bowel overlap.<br>\n大腸と小腸が重複","metadata":{}},{"cell_type":"code","source":"display_xy_five_imgs(65,0,88)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"##### case65 day0 slice88\nOnly this slice is the small_bowel, and the next and subsequent slices are the large_bowel.<br>\nこのスライスのみ小腸で、次のスライス以降は大腸","metadata":{}},{"cell_type":"code","source":"display_xy_five_imgs(67,16,50)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"##### case67 day16 slice50-51\nA small independent large_bowel is present.<br>\n独立した小さな大腸が存在。","metadata":{}},{"cell_type":"code","source":"display_xy_five_imgs(74,19,113)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"##### case74 day19 slice113\nThe large_bowel mask is disconnected.<br>\n大腸が途切れている","metadata":{}},{"cell_type":"code","source":"display_xy_five_imgs(118,14,88)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"##### case118 day14 slice88\nThe large_bowel and small_bowel overlap.<br>\n大腸と小腸が重複","metadata":{}},{"cell_type":"code","source":"display_xy_five_imgs(129,24,114)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"##### case129 day24 slice114\nThe large_bowel and small_bowel overlap.<br>\n大腸と小腸が重複","metadata":{}},{"cell_type":"code","source":"display_xy_five_imgs(131,0,100)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"##### case131 day0 slice100\nThe large_bowel mask is disconnected.<br>\n大腸が途切れている","metadata":{}},{"cell_type":"code","source":"display_xy_five_imgs(131,21,87)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"##### case131 day21 slice87\nThe small_bowel mask is disconnected.<br>\n小腸が途切れている","metadata":{}},{"cell_type":"code","source":"display_xy_five_imgs(139,14,102)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"##### case139 day14 slice102\nThe stomach mask next to the small_bowel is disconnected.<br>\n小腸の隣の胃が途切れる。","metadata":{}},{"cell_type":"code","source":"display_xy_five_imgs(143,18,64)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"##### case143 day18 slice64\nA part of the small_bowel mask is disconnected.<br>\n小腸の一部が途切れている","metadata":{}},{"cell_type":"code","source":"display_xy_five_imgs(148,20,88)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"##### case148 day20 slice88-89\nA small independent large_bowel is present.<br>\n独立した小さな大腸が存在。","metadata":{}}]}