{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import os\nimport cv2\nimport PIL\nimport random\nimport openslide\nimport skimage.io\nimport matplotlib\nimport numpy as np\nimport pandas as pd\nimport seaborn as sns\nimport matplotlib.pyplot as plt\nfrom IPython.display import Image, display","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df = pd.read_csv('../input/prostate-cancer-grade-assessment/train.csv').sample(n=100, random_state=0).reset_index(drop=True)\n\nimages = list(train_df['image_id'])\nlabels = list(train_df['isup_grade'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data_dir = '../input/prostate-cancer-grade-assessment/train_images/'","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Compute statistics","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"First we need to write a function to compute the proportion of white pixels in the region.","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"## Select k-best regions","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"Then we need a function to sort a list of tuples, where one component of the tuple is the proportion of white pixels in the regions. We are sorting in ascending order.","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"Since we will only store, the coordinates of the top-left pixel, we need a way to retrieve the k best regions, hence the function hereafter...","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"## Slide over the image","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"The main function: the two while loops slide over the image (the first one from top to bottom, the second from left to right). The order does not matter actually.\nThen you select the region, compute the statistics of that region, sort the array and select the k-best regions.","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"## Show the results","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"Now we will show some results. \n\nPlease note:\n1. The smaller the window size, the more precise but the longer.\n2. I would say that a window size of around 200 is a good choice. It is a good trade-off between generality, having enough of the biopsy structure captured as well as enough details.\n3. A too small window size might harm the performance of the model since you might select only a tiny portion of the biopsy. (To counter this, introducing a random choice might be worth trying).","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"# sample 2","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"def compute_statistics(image):\n    \"\"\"\n    Args:\n        image                  numpy.array   multi-dimensional array of the form WxHxC\n    \n    Returns:\n        ratio_white_pixels     float         ratio of white pixels over total pixels in the image \n    \"\"\"\n    width, height = image.shape[0], image.shape[1]\n    num_pixels = width * height\n\n    num_white_pixels = 0\n\n    summed_matrix = np.sum(image, axis=-1)\n    # Note: A 3-channel white pixel has RGB (255, 255, 255)\n    num_white_pixels = np.count_nonzero(summed_matrix > 700)\n    # num_white_pixels = np.count_nonzero(summed_matrix > 255*3-1)\n    ratio_white_pixels = num_white_pixels / num_pixels\n\n    # red_concentration = np.mean(image[:,:,0])\n    # red_concentration = np.mean(image[:,:,0][summed_matrix!=255*3])\n    green_concentration = np.mean(image[:, :, 1])\n    # green_concentration = np.mean(image[:,:,1][summed_matrix<200*3])\n    blue_concentration = np.mean(image[:, :, 2])\n    # blue_concentration = np.mean(image[:,:,2][summed_matrix<200*3])\n\n    return ratio_white_pixels, green_concentration, blue_concentration\n\n\ndef select_k_best_regions(regions, k=20):\n    \"\"\"\n    Args:\n        regions               list           list of 2-component tuples first component the region, \n                                             second component the ratio of white pixels\n                                             \n        k                     int            number of regions to select\n    \"\"\"\n    # regions = [x for x in regions if x[3] > 100 and x[4] > 100]\n    k_best_regions = sorted(regions, key=lambda tup: tup[2])[:k]\n    return k_best_regions\n\n\ndef get_k_best_regions(coordinates, image, window_size=512):\n    regions = {}\n    for i, tup in enumerate(coordinates):\n        x, y = tup[0], tup[1]\n        regions[i] = image[x : x + window_size, y : y + window_size, :]\n\n    return regions\n\n\ndef detect_best_window_size(image, K=16, scaling_factor=1.0):\n    # image = skimage.io.MultiImage(slide_path)[2]\n    # image = np.array(image)\n    ratio_white_pixels, green_concentration, blue_concentration = compute_statistics(\n        image\n    )\n    # print(ratio_white_pixels, green_concentration, blue_concentration)\n    h, w = image.shape[:2]\n    return max(\n        int(np.sqrt(h * w * (1.0 - ratio_white_pixels) * scaling_factor / K)), 32\n    )\n\n\ndef generate_patches(\n    slide_path, window_size=128, stride=128, k=20, auto_ws=False, scaling_factor=1.0\n):\n\n    image = skimage.io.MultiImage(slide_path)[2]\n    image = np.array(image)\n\n    if auto_ws:\n        window_size = detect_best_window_size(\n            image, K=k, scaling_factor=scaling_factor\n        )\n        stride = window_size\n\n    max_width, max_height = image.shape[0], image.shape[1]\n    regions_container = []\n    i = 0\n\n    while window_size + stride * i <= max_height:\n        j = 0\n\n        while window_size + stride * j <= max_width:\n            x_top_left_pixel = j * stride\n            y_top_left_pixel = i * stride\n\n            patch = image[\n                x_top_left_pixel : x_top_left_pixel + window_size,\n                y_top_left_pixel : y_top_left_pixel + window_size,\n                :,\n            ]\n\n            (\n                ratio_white_pixels,\n                green_concentration,\n                blue_concentration,\n            ) = compute_statistics(patch)\n\n            region_tuple = (\n                x_top_left_pixel,\n                y_top_left_pixel,\n                ratio_white_pixels,\n                green_concentration,\n                blue_concentration,\n            )\n            regions_container.append(region_tuple)\n\n            j += 1\n\n        i += 1\n\n    k_best_region_coordinates = select_k_best_regions(regions_container, k=k)\n    k_best_regions = get_k_best_regions(k_best_region_coordinates, image, window_size)\n\n    return image, k_best_region_coordinates, k_best_regions, window_size\n\n\ndef glue_to_one_picture_from_coord(url, coordinates, window_size=200, k=16, layer=0):\n    side = int(np.sqrt(k))\n    slide = openslide.OpenSlide(url)\n    lv2_scale = slide.level_downsamples[2]\n    scale = slide.level_downsamples[2] / slide.level_downsamples[layer]\n    # print(scale)\n\n    # image = np.zeros((int(side*window_size*scale), int(side*window_size*scale), 3), dtype=np.uint8)\n    image = np.full(\n        (int(side * window_size * scale), int(side * window_size * scale), 3),\n        255,\n        dtype=np.uint8,\n    )\n    # print(coordinates)\n    for i, patch_coord in enumerate(coordinates):\n        x = i // side\n        y = i % side\n        patch = np.asarray(\n            slide.read_region(\n                (int(patch_coord[1] * lv2_scale), int(patch_coord[0] * lv2_scale)),\n                layer,\n                (int(window_size * scale), int(window_size * scale)),\n            )\n        )[:, :, :3]\n        image[\n            int(x * window_size * scale) : int(x * window_size * scale)\n            + int(window_size * scale),\n            int(y * window_size * scale) : int(y * window_size * scale)\n            + int(window_size * scale),\n            :,\n        ] = patch\n    slide.close()\n    return image\n\ndef glue_to_one_picture_from_coord_lowlayer(url, coordinates, window_size=200, k=16, layer=1):\n    side = int(np.sqrt(k))\n    slide = openslide.OpenSlide(url)\n    lv2_scale = slide.level_downsamples[2]\n    scale = slide.level_downsamples[2] / slide.level_downsamples[layer]\n    # print(scale)\n    slide.close()\n    \n    slide = skimage.io.MultiImage(url)[layer]\n    slide = np.array(slide)\n\n    image = np.full((int(side * window_size * scale), int(side * window_size * scale), 3),255,dtype=np.uint8,)\n    # print(coordinates)\n    for i, patch_coord in enumerate(coordinates):\n        x = i // side\n        y = i % side\n        patch = slide[int(patch_coord[0] * scale): int(patch_coord[0] * scale) + int(window_size * scale),\n                      int(patch_coord[1] * scale): int(patch_coord[1] * scale) + int(window_size * scale),:]\n        image[int(x * window_size * scale) : int(x * window_size * scale) + int(window_size * scale),\n            int(y * window_size * scale) : int(y * window_size * scale) + int(window_size * scale),:,] = patch\n    return image\n\ndef glue_to_one_picture(image_patches, window_size=200, k=16):\n    side = int(np.sqrt(k))\n    image = np.zeros((side * window_size, side * window_size, 3), dtype=np.uint8)\n\n    for i, patch in image_patches.items():\n        x = i // side\n        y = i % side\n        image[\n            x * window_size : (x + 1) * window_size,\n            y * window_size : (y + 1) * window_size,\n            :,\n        ] = patch\n\n    return image\n\n\ndef load_img(img_name, K=16, scaling_factor=1.0, layer=0, auto_ws=True, window_size=128):\n    WINDOW_SIZE = window_size\n    STRIDE = window_size\n    # K = 16\n    image, best_coordinates, best_regions, win = generate_patches(\n        img_name,\n        window_size=WINDOW_SIZE,\n        stride=STRIDE,\n        k=K,\n        auto_ws=auto_ws,\n        scaling_factor=scaling_factor,\n    )\n    WINDOW_SIZE = win\n    STRIDE = WINDOW_SIZE\n    # print(win)\n    # glued_image = glue_to_one_picture(best_regions, window_size=WINDOW_SIZE, k=K)\n    if layer == 0:\n        glued_image = glue_to_one_picture_from_coord(\n            img_name, best_coordinates, window_size=WINDOW_SIZE, k=K, layer=layer\n        )\n    else:\n        glued_image = glue_to_one_picture_from_coord_lowlayer(\n            img_name, best_coordinates, window_size=WINDOW_SIZE, k=K, layer=layer\n        )\n    return glued_image","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_kg_hide-input":true,"_kg_hide-output":true},"cell_type":"code","source":"img_id = \"3790f55cad63053e956fb73027179707\"\nex_url = data_dir + img_id + '.tiff'\nimage = skimage.io.MultiImage(ex_url)[1]\nplt.imshow(image)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"%%time\nimg_id = \"3790f55cad63053e956fb73027179707\"\nimg_id = images[25]\nex_url = data_dir + img_id + '.tiff'\nglued_image = load_img(ex_url, K=16, scaling_factor=1.0, layer=1, auto_ws=True, window_size=128)\n#cv2.cvtColor(glued_image, cv2.COLOR_RGB2BGR)\nplt.imshow(glued_image)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"fig, ax = plt.subplots(6, 2, figsize=(20, 25))\npen_marked_images = [\n    'fd6fe1a3985b17d067f2cb4d5bc1e6e1',\n    'ebb6a080d72e09f6481721ef9f88c472',\n    'ebb6d5ca45942536f78beb451ee43cc4',\n    'ea9d52d65500acc9b9d89eb6b82cdcdf',\n    'e726a8eac36c3d91c3c4f9edba8ba713',\n    'e90abe191f61b6fed6d6781c8305fe4b',\n    'fd0bb45eba479a7f7d953f41d574bf9f',\n    'ff10f937c3d52eff6ad4dd733f2bc3ac',\n    'feee2e895355a921f2b75b54debad328',\n    'feac91652a1c5accff08217d19116f1c',\n    'fb01a0a69517bb47d7f4699b6217f69d',\n    'f00ec753b5618cfb30519db0947fe724',\n    'e9a4f528b33479412ee019e155e1a197',\n    'f062f6c1128e0e9d51a76747d9018849',\n    'f39bf22d9a2f313425ee201932bac91a',\n]\n#for i, img in enumerate(images[:6]):\nfor i, img in enumerate(pen_marked_images[:6]):\n    url = data_dir + img + '.tiff'\n    #image, best_coordinates, best_regions, _ = generate_patches(url, window_size=WINDOW_SIZE, stride=STRIDE, k=K)\n    glued_image = load_img(url, K=16, scaling_factor=1.0)\n    \n    ax[i][0].imshow(image)\n    ax[i][0].set_title(f'{img} - Original - Label: {labels[i]}')\n    \n    ax[i][1].imshow(glued_image)\n    ax[i][1].set_title(f'{img} - Glued - Label: {labels[i]}')\n\nfig.suptitle('From biopsy to glued patches')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import sys\n\nprint(\"{}{: >25}{}{: >10}{}\".format('|','Variable Name','|','Memory','|'))\nprint(\" ------------------------------------ \")\nfor var_name in dir():\n    if not var_name.startswith(\"_\") and sys.getsizeof(eval(var_name)) > 10000: #ここだけアレンジ\n        print(\"{}{: >25}{}{: >10}{}\".format('|',var_name,'|',sys.getsizeof(eval(var_name)),'|'))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"del glued_image\ndel image","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}