{
  "id": 148610,
  "title": "Simple Tile Visualizer and Subplot Display",
  "url": "/competitions/prostate-cancer-grade-assessment/discussion/148610",
  "author_name": "Zac Dannelly",
  "post_date": "2020-05-05T00:14:34.235000",
  "votes": 8,
  "comment_count": 0,
  "views": 0,
  "content": "<p>I have been utilizing the amazing wizardry done by <a href=\"/iafoss\">@iafoss</a> throughout this competition in his <a href=\"https://www.kaggle.com/iafoss/panda-concat-tile-pooling-starter-inference\">notebooks</a> and <a href=\"https://www.kaggle.com/c/prostate-cancer-grade-assessment/discussion/146855\">discussions</a> around using tiles pulled from the slides as data input.</p>\n\n<p>I made a <a href=\"https://www.kaggle.com/dannellyz/simple-tile-visualizer-and-subplot-modules\">notebook that displays the modules</a> for both the tiles themselves as well as an overlay of the selected tiles on a given slide. I made them both into simple python modules with outputs as below:</p>\n\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F1342122%2F502c1145ac9c877556c2308650e0901d%2Fviz_img.001.jpeg?generation=1588637596178459&amp;alt=media\" alt=\"\"></p>\n\n<p>I also added some of my notes to the tile module to better understand the magic performed:\n```:::python\ndef tile_plot(base_image, N=12, sz=128, plot=True):\n    \"\"\"\n    Description\n    <strong><em>_</em>___</strong>\n    Tilizer module made by <a href=\"/iafoss\">@iafoss</a> that can be found in the notebook:\n    <a href=\"https://www.kaggle.com/iafoss/panda-concat-tile-pooling-starter-inference\">https://www.kaggle.com/iafoss/panda-concat-tile-pooling-starter-inference</a>\n    Takes a base image and returns the N tiles with the largest differnce\n    from a white backgound each with a given square size of input-sz.</p>\n\n<pre><code>Parameters\n__________\nbase_image: numpy array\n    Image array to split into tiles and plot\nN: int\n    This is the number of tiles to split the image into\nsz: int\n    This is the size for each side of the square tiles\nplot: bool\n    True to show plot of chosen tiles, False for silent return\n\nReturns\n__________\n- List of size N with each item being a numpy array tile.\n\"\"\"\n\n#Get the shape of the input image\nshape = base_image.shape\n\n#Find the padding such that the image divides evenly by the desired size\npad0,pad1 = (sz - shape[0]%sz)%sz, (sz - shape[1]%sz)%sz\n\n#Pad the image with blank space to reach the above found tagrgets\nbase_img = np.pad(base_image,[[pad0//2,pad0-pad0//2],\n                              [pad1//2,pad1-pad1//2],[0,0]],\n                                 constant_values=255)\n\n#Reshape and Transpose to get the images into tiles\nall_tiles = base_img.reshape(base_img.shape[0]//sz,sz, base_img.shape[1]//sz,sz,3)\nall_tiles = all_tiles.transpose(0,2,1,3,4).reshape(-1,sz,sz,3)\n\n#If there are not enough tiles to meet desired N pad again\nif len(all_tiles) &amp;lt; N:\n    all_tiles = np.pad(all_tiles,[[0,N-len(all_tiles)],[0,0],[0,0],[0,0]],\n                                   constant_values=255) \n\n#Sort the images by those with the lowest sum (i.e the least white)\n#Return indexes to the lowest N \nidxs = np.argsort(all_tiles.reshape(all_tiles.shape[0],-1).sum(-1))[:N]\n\n#Slect by index those returned from the above funtion\ntissue_tiles = all_tiles[idxs]\n\nif plot:\n    #Funciton for plotting\n    line_color=[0,255,255]\n    line_sz=5\n    #Get the deminsions in terms of slides\n    tile_cnt_size = [base_img.shape[0]//sz, base_img.shape[1]//sz]\n\n    #Iterate through all images; change the border on the selected tiles\n    prod_tiles = []\n    for i,img in enumerate(all_tiles):\n        if i in idxs:\n            #If image is in the slected slides change the..\n            #Left\n            img[:,:line_sz,:] =  [[line_color]*line_sz]*sz\n            #Right\n            img[:,-line_sz:,:] =  [[line_color]*line_sz]*sz\n            #Top\n            img[:line_sz] =  [[line_color]*sz]*line_sz\n            #Bottom\n            img[-line_sz:] =  [[line_color]*sz]*line_sz\n            #... boarders to the specified color\n        prod_tiles.append(img)\n\n    #Piece the tiles back into one image\n    #Split the array of tiles into a list of rows\n    rows = np.array_split(prod_tiles,tile_cnt_size[0])\n    #Horizontally combine rows\n    row_combine = [np.hstack(tiles) for tiles in rows]\n    #Vertically stack rows back into base image\n    prod_image = np.vstack(row_combine)\n    #Display image\n    plt.imshow(prod_image)\n    plt.show()\nreturn tissue_tiles\n</code></pre>\n\n<p>```</p>\n\n<h3>Hope these are helpful!</h3>",
  "messages": [
    {
      "id": 833618,
      "postDate": "2020-05-05T00:14:34.237Z",
      "content": "<p>I have been utilizing the amazing wizardry done by <a href=\"/iafoss\">@iafoss</a> throughout this competition in his <a href=\"https://www.kaggle.com/iafoss/panda-concat-tile-pooling-starter-inference\">notebooks</a> and <a href=\"https://www.kaggle.com/c/prostate-cancer-grade-assessment/discussion/146855\">discussions</a> around using tiles pulled from the slides as data input.</p>\n\n<p>I made a <a href=\"https://www.kaggle.com/dannellyz/simple-tile-visualizer-and-subplot-modules\">notebook that displays the modules</a> for both the tiles themselves as well as an overlay of the selected tiles on a given slide. I made them both into simple python modules with outputs as below:</p>\n\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F1342122%2F502c1145ac9c877556c2308650e0901d%2Fviz_img.001.jpeg?generation=1588637596178459&amp;alt=media\" alt=\"\"></p>\n\n<p>I also added some of my notes to the tile module to better understand the magic performed:\n```:::python\ndef tile_plot(base_image, N=12, sz=128, plot=True):\n    \"\"\"\n    Description\n    <strong><em>_</em>___</strong>\n    Tilizer module made by <a href=\"/iafoss\">@iafoss</a> that can be found in the notebook:\n    <a href=\"https://www.kaggle.com/iafoss/panda-concat-tile-pooling-starter-inference\">https://www.kaggle.com/iafoss/panda-concat-tile-pooling-starter-inference</a>\n    Takes a base image and returns the N tiles with the largest differnce\n    from a white backgound each with a given square size of input-sz.</p>\n\n<pre><code>Parameters\n__________\nbase_image: numpy array\n    Image array to split into tiles and plot\nN: int\n    This is the number of tiles to split the image into\nsz: int\n    This is the size for each side of the square tiles\nplot: bool\n    True to show plot of chosen tiles, False for silent return\n\nReturns\n__________\n- List of size N with each item being a numpy array tile.\n\"\"\"\n\n#Get the shape of the input image\nshape = base_image.shape\n\n#Find the padding such that the image divides evenly by the desired size\npad0,pad1 = (sz - shape[0]%sz)%sz, (sz - shape[1]%sz)%sz\n\n#Pad the image with blank space to reach the above found tagrgets\nbase_img = np.pad(base_image,[[pad0//2,pad0-pad0//2],\n                              [pad1//2,pad1-pad1//2],[0,0]],\n                                 constant_values=255)\n\n#Reshape and Transpose to get the images into tiles\nall_tiles = base_img.reshape(base_img.shape[0]//sz,sz, base_img.shape[1]//sz,sz,3)\nall_tiles = all_tiles.transpose(0,2,1,3,4).reshape(-1,sz,sz,3)\n\n#If there are not enough tiles to meet desired N pad again\nif len(all_tiles) &amp;lt; N:\n    all_tiles = np.pad(all_tiles,[[0,N-len(all_tiles)],[0,0],[0,0],[0,0]],\n                                   constant_values=255) \n\n#Sort the images by those with the lowest sum (i.e the least white)\n#Return indexes to the lowest N \nidxs = np.argsort(all_tiles.reshape(all_tiles.shape[0],-1).sum(-1))[:N]\n\n#Slect by index those returned from the above funtion\ntissue_tiles = all_tiles[idxs]\n\nif plot:\n    #Funciton for plotting\n    line_color=[0,255,255]\n    line_sz=5\n    #Get the deminsions in terms of slides\n    tile_cnt_size = [base_img.shape[0]//sz, base_img.shape[1]//sz]\n\n    #Iterate through all images; change the border on the selected tiles\n    prod_tiles = []\n    for i,img in enumerate(all_tiles):\n        if i in idxs:\n            #If image is in the slected slides change the..\n            #Left\n            img[:,:line_sz,:] =  [[line_color]*line_sz]*sz\n            #Right\n            img[:,-line_sz:,:] =  [[line_color]*line_sz]*sz\n            #Top\n            img[:line_sz] =  [[line_color]*sz]*line_sz\n            #Bottom\n            img[-line_sz:] =  [[line_color]*sz]*line_sz\n            #... boarders to the specified color\n        prod_tiles.append(img)\n\n    #Piece the tiles back into one image\n    #Split the array of tiles into a list of rows\n    rows = np.array_split(prod_tiles,tile_cnt_size[0])\n    #Horizontally combine rows\n    row_combine = [np.hstack(tiles) for tiles in rows]\n    #Vertically stack rows back into base image\n    prod_image = np.vstack(row_combine)\n    #Display image\n    plt.imshow(prod_image)\n    plt.show()\nreturn tissue_tiles\n</code></pre>\n\n<p>```</p>\n\n<h3>Hope these are helpful!</h3>",
      "rawMarkdown": "I have been utilizing the amazing wizardry done by @iafoss throughout this competition in his [notebooks](https://www.kaggle.com/iafoss/panda-concat-tile-pooling-starter-inference) and [discussions](https://www.kaggle.com/c/prostate-cancer-grade-assessment/discussion/146855) around using tiles pulled from the slides as data input.\n\nI made a [notebook that displays the modules](https://www.kaggle.com/dannellyz/simple-tile-visualizer-and-subplot-modules) for both the tiles themselves as well as an overlay of the selected tiles on a given slide. I made them both into simple python modules with outputs as below:\n\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F1342122%2F502c1145ac9c877556c2308650e0901d%2Fviz_img.001.jpeg?generation=1588637596178459&amp;alt=media)\n\nI also added some of my notes to the tile module to better understand the magic performed:\n```:::python\ndef tile_plot(base_image, N=12, sz=128, plot=True):\n    \"\"\"\n    Description\n    __________\n    Tilizer module made by @iafoss that can be found in the notebook:\n    https://www.kaggle.com/iafoss/panda-concat-tile-pooling-starter-inference\n    Takes a base image and returns the N tiles with the largest differnce\n    from a white backgound each with a given square size of input-sz.\n    \n    Parameters\n    __________\n    base_image: numpy array\n        Image array to split into tiles and plot\n    N: int\n        This is the number of tiles to split the image into\n    sz: int\n        This is the size for each side of the square tiles\n    plot: bool\n        True to show plot of chosen tiles, False for silent return\n    \n    Returns\n    __________\n    - List of size N with each item being a numpy array tile.\n    \"\"\"\n    \n    #Get the shape of the input image\n    shape = base_image.shape\n    \n    #Find the padding such that the image divides evenly by the desired size\n    pad0,pad1 = (sz - shape[0]%sz)%sz, (sz - shape[1]%sz)%sz\n    \n    #Pad the image with blank space to reach the above found tagrgets\n    base_img = np.pad(base_image,[[pad0//2,pad0-pad0//2],\n                                  [pad1//2,pad1-pad1//2],[0,0]],\n                                     constant_values=255)\n    \n    #Reshape and Transpose to get the images into tiles\n    all_tiles = base_img.reshape(base_img.shape[0]//sz,sz, base_img.shape[1]//sz,sz,3)\n    all_tiles = all_tiles.transpose(0,2,1,3,4).reshape(-1,sz,sz,3)\n    \n    #If there are not enough tiles to meet desired N pad again\n    if len(all_tiles) &lt; N:\n        all_tiles = np.pad(all_tiles,[[0,N-len(all_tiles)],[0,0],[0,0],[0,0]],\n                                       constant_values=255) \n    \n    #Sort the images by those with the lowest sum (i.e the least white)\n    #Return indexes to the lowest N \n    idxs = np.argsort(all_tiles.reshape(all_tiles.shape[0],-1).sum(-1))[:N]\n    \n    #Slect by index those returned from the above funtion\n    tissue_tiles = all_tiles[idxs]\n    \n    if plot:\n        #Funciton for plotting\n        line_color=[0,255,255]\n        line_sz=5\n        #Get the deminsions in terms of slides\n        tile_cnt_size = [base_img.shape[0]//sz, base_img.shape[1]//sz]\n        \n        #Iterate through all images; change the border on the selected tiles\n        prod_tiles = []\n        for i,img in enumerate(all_tiles):\n            if i in idxs:\n                #If image is in the slected slides change the..\n                #Left\n                img[:,:line_sz,:] =  [[line_color]*line_sz]*sz\n                #Right\n                img[:,-line_sz:,:] =  [[line_color]*line_sz]*sz\n                #Top\n                img[:line_sz] =  [[line_color]*sz]*line_sz\n                #Bottom\n                img[-line_sz:] =  [[line_color]*sz]*line_sz\n                #... boarders to the specified color\n            prod_tiles.append(img)\n            \n        #Piece the tiles back into one image\n        #Split the array of tiles into a list of rows\n        rows = np.array_split(prod_tiles,tile_cnt_size[0])\n        #Horizontally combine rows\n        row_combine = [np.hstack(tiles) for tiles in rows]\n        #Vertically stack rows back into base image\n        prod_image = np.vstack(row_combine)\n        #Display image\n        plt.imshow(prod_image)\n        plt.show()\n    return tissue_tiles\n```\n\n### Hope these are helpful!",
      "votes": 8
    }
  ],
  "comments": [],
  "raw_markdown_by_id": {
    "833618": "I have been utilizing the amazing wizardry done by @iafoss throughout this competition in his [notebooks](https://www.kaggle.com/iafoss/panda-concat-tile-pooling-starter-inference) and [discussions](https://www.kaggle.com/c/prostate-cancer-grade-assessment/discussion/146855) around using tiles pulled from the slides as data input.\n\nI made a [notebook that displays the modules](https://www.kaggle.com/dannellyz/simple-tile-visualizer-and-subplot-modules) for both the tiles themselves as well as an overlay of the selected tiles on a given slide. I made them both into simple python modules with outputs as below:\n\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F1342122%2F502c1145ac9c877556c2308650e0901d%2Fviz_img.001.jpeg?generation=1588637596178459&amp;alt=media)\n\nI also added some of my notes to the tile module to better understand the magic performed:\n```:::python\ndef tile_plot(base_image, N=12, sz=128, plot=True):\n    \"\"\"\n    Description\n    __________\n    Tilizer module made by @iafoss that can be found in the notebook:\n    https://www.kaggle.com/iafoss/panda-concat-tile-pooling-starter-inference\n    Takes a base image and returns the N tiles with the largest differnce\n    from a white backgound each with a given square size of input-sz.\n    \n    Parameters\n    __________\n    base_image: numpy array\n        Image array to split into tiles and plot\n    N: int\n        This is the number of tiles to split the image into\n    sz: int\n        This is the size for each side of the square tiles\n    plot: bool\n        True to show plot of chosen tiles, False for silent return\n    \n    Returns\n    __________\n    - List of size N with each item being a numpy array tile.\n    \"\"\"\n    \n    #Get the shape of the input image\n    shape = base_image.shape\n    \n    #Find the padding such that the image divides evenly by the desired size\n    pad0,pad1 = (sz - shape[0]%sz)%sz, (sz - shape[1]%sz)%sz\n    \n    #Pad the image with blank space to reach the above found tagrgets\n    base_img = np.pad(base_image,[[pad0//2,pad0-pad0//2],\n                                  [pad1//2,pad1-pad1//2],[0,0]],\n                                     constant_values=255)\n    \n    #Reshape and Transpose to get the images into tiles\n    all_tiles = base_img.reshape(base_img.shape[0]//sz,sz, base_img.shape[1]//sz,sz,3)\n    all_tiles = all_tiles.transpose(0,2,1,3,4).reshape(-1,sz,sz,3)\n    \n    #If there are not enough tiles to meet desired N pad again\n    if len(all_tiles) &lt; N:\n        all_tiles = np.pad(all_tiles,[[0,N-len(all_tiles)],[0,0],[0,0],[0,0]],\n                                       constant_values=255) \n    \n    #Sort the images by those with the lowest sum (i.e the least white)\n    #Return indexes to the lowest N \n    idxs = np.argsort(all_tiles.reshape(all_tiles.shape[0],-1).sum(-1))[:N]\n    \n    #Slect by index those returned from the above funtion\n    tissue_tiles = all_tiles[idxs]\n    \n    if plot:\n        #Funciton for plotting\n        line_color=[0,255,255]\n        line_sz=5\n        #Get the deminsions in terms of slides\n        tile_cnt_size = [base_img.shape[0]//sz, base_img.shape[1]//sz]\n        \n        #Iterate through all images; change the border on the selected tiles\n        prod_tiles = []\n        for i,img in enumerate(all_tiles):\n            if i in idxs:\n                #If image is in the slected slides change the..\n                #Left\n                img[:,:line_sz,:] =  [[line_color]*line_sz]*sz\n                #Right\n                img[:,-line_sz:,:] =  [[line_color]*line_sz]*sz\n                #Top\n                img[:line_sz] =  [[line_color]*sz]*line_sz\n                #Bottom\n                img[-line_sz:] =  [[line_color]*sz]*line_sz\n                #... boarders to the specified color\n            prod_tiles.append(img)\n            \n        #Piece the tiles back into one image\n        #Split the array of tiles into a list of rows\n        rows = np.array_split(prod_tiles,tile_cnt_size[0])\n        #Horizontally combine rows\n        row_combine = [np.hstack(tiles) for tiles in rows]\n        #Vertically stack rows back into base image\n        prod_image = np.vstack(row_combine)\n        #Display image\n        plt.imshow(prod_image)\n        plt.show()\n    return tissue_tiles\n```\n\n### Hope these are helpful!"
  }
}