{"cells":[{"metadata":{},"cell_type":"markdown","source":"The code below selects 16, 128x128 tiles for each image and mask based on the maximum number of tissue pixels.   \nThe kernel also provides computed image stats. Please check my kernels to see how to use this data. \n![](https://i.ibb.co/RzSWP56/convert.png)","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"[IBM](https://developer.ibm.com/technologies/data-science/articles/an-automatic-method-to-identify-tissues-from-big-whole-slide-images-pt1/)  \n[Analysing WSI directly!](https://github.com/mahmoodlab/CLAM)  \n[BAIDU](https://github.com/baidu-research/NCRF#patch-images)  \n[open source tool](https://digitalslidearchive.github.io/HistomicsTK/examples/using_large_image)\n[deepslide-framework](https://github.com/BMIRDS/deepslide/blob/master/code/utils_processing.py)","execution_count":null},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import os\nimport cv2\nimport skimage.io\nfrom tqdm.notebook import tqdm\nimport zipfile\nimport numpy as np","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"TRAIN = '../input/prostate-cancer-grade-assessment/train_images/'\nMASKS = '../input/prostate-cancer-grade-assessment/train_label_masks/'\nOUT_TRAIN = 'train.zip'\nLABELS    = '../input/prostate-cancer-grade-assessment/train.csv'","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!rm -rf ./train.zip","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# def get_tiles(img, n_tiles,tile_size,mode=0):\n#     '''\n#     from 36, 256x256\n#     '''\n#     result = []\n#     h, w, c = img.shape\n#     pad_h = (tile_size - h % tile_size) % tile_size + ((tile_size * mode) // 2)\n#     pad_w = (tile_size - w % tile_size) % tile_size + ((tile_size * mode) // 2)\n#     img2 = np.pad(img,[[pad_h // 2, pad_h - pad_h // 2], [pad_w // 2,pad_w - pad_w//2], [0,0]], constant_values=255)\n#     img3 = img2.reshape(\n#         img2.shape[0] // tile_size,\n#         tile_size,\n#         img2.shape[1] // tile_size,\n#         tile_size,\n#         3\n#     )\n#     img3 = img3.transpose(0,2,1,3,4).reshape(-1, tile_size, tile_size,3)\n#     n_tiles_with_info = (img3.reshape(img3.shape[0],-1).sum(1) < tile_size ** 2 * 3 * 255).sum()\n#     if len(img3) < n_tiles:\n#         img3 = np.pad(img3,[[0,n_tiles-len(img3)],[0,0],[0,0],[0,0]], constant_values=255)\n#     idxs = np.argsort(img3.reshape(img3.shape[0],-1).sum(-1))[:n_tiles]\n#     img3 = img3[idxs]\n#     for i in range(len(img3)):\n#         result.append({'img':img3[i], 'idx':i})\n#     return result, n_tiles_with_info >= n_tiles","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# def tile(img,N,sz):\n#     result = []\n#     shape = img.shape\n#     #paddings\n#     pad0,pad1 = (sz - shape[0]%sz)%sz, (sz - shape[1]%sz)%sz\n#     #images\n#     img = np.pad(img,[[pad0//2,pad0-pad0//2],[pad1//2,pad1-pad1//2],[0,0]],constant_values=255)\n#     img = img.reshape(img.shape[0]//sz,sz,img.shape[1]//sz,sz,3)\n#     img = img.transpose(0,2,1,3,4).reshape(-1,sz,sz,3)\n#     if len(img) < N:\n#         img = np.pad(img,[[0,N-len(img)],[0,0],[0,0],[0,0]],constant_values=255)\n#     idxs = np.argsort(img.reshape(img.shape[0],-1).sum(-1))[:N]\n#     img = img[idxs]\n#     for i in range(len(img)):\n#         result.append({'img':img[i],'idx':i})\n#     return result","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# def display_image(img,is_mask=False):\n#     '''\n#     To display image/mask \n#     args: img, image\n#           is_mask, boolean True if greyscale mask is passed\n#     '''\n#     from matplotlib import pyplot as plt\n#     %matplotlib inline\n#     if is_mask:\n#         plt.imshow(img,cmap='gray')\n#     else:\n#         plt.imshow(img)\n#     plt.show()     ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# img  = skimage.io.MultiImage(os.path.join(TRAIN,'cdd5b7d07b98f61d3668207531b4de07'+'.tiff'))[-1]\n# tiles=tile_high_res(os.path.join(TRAIN,'085a35715e8a0f0edeccff03290a6baf'+'.tiff'))\n# for t in tiles:\n#     img,idx = t['img'],t['idx']\n#     print(t['img'].shape,t['idx'])\n#     display_image(t['img'])","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"# def tile(img, mask):\n#     result = []\n#     shape = img.shape\n#     #paddings\n#     pad0,pad1 = (sz - shape[0]%sz)%sz, (sz - shape[1]%sz)%sz\n#     #images\n#     img = np.pad(img,[[pad0//2,pad0-pad0//2],[pad1//2,pad1-pad1//2],[0,0]],constant_values=255)\n#     img = img.reshape(img.shape[0]//sz,sz,img.shape[1]//sz,sz,3)\n#     img = img.transpose(0,2,1,3,4).reshape(-1,sz,sz,3)\n#     #masks\n#     mask = np.pad(mask,[[pad0//2,pad0-pad0//2],[pad1//2,pad1-pad1//2],[0,0]],constant_values=0)\n#     mask = mask.reshape(mask.shape[0]//sz,sz,mask.shape[1]//sz,sz,3)\n#     mask = mask.transpose(0,2,1,3,4).reshape(-1,sz,sz,3)\n#     if len(img) < N:\n#         mask = np.pad(mask,[[0,N-len(img)],[0,0],[0,0],[0,0]],constant_values=0)\n#         img = np.pad(img,[[0,N-len(img)],[0,0],[0,0],[0,0]],constant_values=255)\n#     idxs = np.argsort(img.reshape(img.shape[0],-1).sum(-1))[:N]\n#     img = img[idxs]\n#     mask = mask[idxs]\n#     for i in range(len(img)):\n#         result.append({'img':img[i], 'mask':mask[i], 'idx':i})\n#     return result\n# x_tot,x2_tot = [],[]\n# names = [name[:-10] for name in os.listdir(MASKS)]\n# with zipfile.ZipFile(OUT_TRAIN, 'w') as img_out,zipfile.ZipFile(OUT_MASKS, 'w') as mask_out:\n#     for name in tqdm(names):\n#         img  = skimage.io.MultiImage(os.path.join(TRAIN,name+'.tiff'))[-1]\n#         mask = skimage.io.MultiImage(os.path.join(MASKS,name+'_mask.tiff'))[-1]\n#         tiles = tile(img,mask)\n#         for t in tiles:\n#             img,mask,idx = t['img'],t['mask'],t['idx']\n#             x_tot.append((img/255.0).reshape(-1,3).mean(0))\n#             x2_tot.append(((img/255.0)**2).reshape(-1,3).mean(0)) \n#             #if read with PIL RGB turns into BGR\n#             img = cv2.imencode('.png',cv2.cvtColor(img, cv2.COLOR_RGB2BGR))[1]\n#             img_out.writestr(f'{name}_{idx}.png', img)\n#             mask = cv2.imencode('.png',mask[:,:,0])[1] \n#             mask_out.writestr(f'{name}_{idx}.png', mask)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def tile_high_res(fname):\n    import gc\n    N = 16\n    sz= 256\n    import openslide\n    # use layer 2 for tile selection\n    img = skimage.io.MultiImage(fname)[-1]\n    shape = img.shape\n    r = 16 # ratio of layer 0 vs layer 2 res\n    sz16 = sz//r\n    pad0,pad1 = (sz16 - shape[0]%sz16)%sz16, (sz16 - shape[1]%sz16)%sz16\n    img  = np.pad(img,[[pad0//2,pad0-pad0//2],[pad1//2,pad1-pad1//2],[0,0]],constant_values=255)\n    img  = img.reshape(img.shape[0]//sz16,sz16,img.shape[1]//sz16,sz16,3)\n    img  = img.transpose(0,2,1,3,4).reshape(-1,sz16,sz16,3)\n    idxs = np.argsort(img.reshape(img.shape[0],-1).sum(-1))[:min(N,len(img))]\n    del img\n    gc.collect()\n    # read layer 0 tile by tile with use of openslide\n    n0,n1 = (pad0+shape[0])//sz16, (pad1+shape[1])//sz16\n    img0  = openslide.OpenSlide(fname)\n    tiles = []\n    for idx in idxs:\n        x = (-pad0//2 + sz16*(idx//n1))*r\n        y = (-pad1//2 + sz16*(idx%n1))*r\n        t = np.array(img0.read_region((y,x),0,(sz,sz)))[:,:,:3]\n        tiles.append(t)\n    del img0\n    gc.collect()\n    for i in range(N - len(tiles)): \n        tiles.append(np.full((sz,sz,3), 255, dtype=np.uint8))\n    result = []\n    for i in range(len(tiles)):\n        result.append({'img':tiles[i],'idx':i})\n    del tiles\n    gc.collect()\n    return result\n#     return np.stack(tiles)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# from joblib import Parallel,delayed\n# x_tot,x2_tot = [],[]\n# imgs=[]\n# full_names = []\n# names = set([name[:-10] for name in os.listdir(MASKS)])-set(to_drop)\n# for name in tqdm(list(names)):\n#     full_names.append(os.path.join(TRAIN,name+'.tiff'))\n# #res=Parallel(n_jobs=8,backend='threading')(delayed(tile_high_res)(name) for name in tqdm(full_names))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# with zipfile.ZipFile(OUT_TRAIN, 'w') as img_out:\n#     for name in tqdm(full_names):\n#         tile_high_res(name,img_out)\n\n# from kaggle_datasets import KaggleDatasets\n# GCS_DS_PATH = KaggleDatasets().get_gcs_path('prostate-cancer-grade-assessment')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"##>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>IDEMPOTENT\nimport pandas as pd\nsusp = pd.read_csv('../input/suspicious-panda/PANDA_Suspicious_Slides.csv')\n# ['marks', 'No Mask', 'Background only', 'No cancerous tissue but ISUP Grade > 0', 'tiss', 'blank']\nto_drop = susp.query(\"reason in ['marks','Background only','tiss','blank']\")['image_id']\nprint(\"len(todrop):\",len(to_drop))\ndf = pd.read_csv(LABELS).set_index('image_id')\ngood_index = list(set(df.index)-set(to_drop))\ndf = df.loc[good_index]\ndf = df.reset_index()\ndf = pd.concat([df.query('isup_grade==0').iloc[:1200],df.query('isup_grade==1').iloc[:1200],df.query('isup_grade==2 or isup_grade==3 or isup_grade==4 or isup_grade==5')],axis=0)\ndf = df.sample(n=2000,random_state=2020).reset_index(drop=True)#shuffling\ndf[['isup_grade']].hist(bins=50)\nnames = df['image_id']\nfull_names = []\nfor name in tqdm(names):\n    full_names.append(os.path.join(TRAIN,name+'.tiff'))\nprint(\"len(full_names):\",len(full_names),\" these are used to genrate tiles further...\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"x_tot,x2_tot = [],[]\nwith zipfile.ZipFile(OUT_TRAIN, 'w') as img_out:\n    for full_path in tqdm(full_names):\n        tiles = tile_high_res(full_path)\n        name = full_path.split(\"/\")[-1].split(\".\")[0]\n        for t in tiles:\n            img,idx = t['img'],t['idx']\n            x_tot.append((img/255.0).reshape(-1,3).mean(0))\n            x2_tot.append(((img/255.0)**2).reshape(-1,3).mean(0)) \n            #-if read with PIL RGB turns into BGR\n            img = cv2.imencode('.png',cv2.cvtColor(img, cv2.COLOR_RGB2BGR))[1]\n            img_out.writestr(f'{name}_{idx}.png', img)\n        del tiles\n        import gc\n        gc.collect()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#image statss........\nimg_avr =  np.array(x_tot).mean(0)\nimg_std =  np.sqrt(np.array(x2_tot).mean(0) - img_avr**2)\nprint('mean:',img_avr, ', std:', np.sqrt(img_std),\"x2_tot:\",np.array(x2_tot).mean(0))     ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"del names\nimport gc\ngc.collect()","execution_count":null,"outputs":[]}],"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":4,"nbformat_minor":4}