{"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":"!pip install histomicstk --find-links https://girder.github.io/large_image_wheels","metadata":{"execution":{"iopub.status.busy":"2021-08-25T22:12:54.220329Z","iopub.execute_input":"2021-08-25T22:12:54.221042Z","iopub.status.idle":"2021-08-25T22:13:44.141365Z","shell.execute_reply.started":"2021-08-25T22:12:54.220916Z","shell.execute_reply":"2021-08-25T22:13:44.140434Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import histomicstk as htk\n\nimport numpy as np\nimport scipy as sp\n\nimport skimage.io\nimport skimage.measure\nimport skimage.color\n\nimport matplotlib.pyplot as plt\nimport matplotlib.patches as mpatches\n%matplotlib inline\n\n#Some nice default configuration for plots\nplt.rcParams['figure.figsize'] = 10, 10\nplt.rcParams['image.cmap'] = 'gray'\ntitlesize = 24","metadata":{"execution":{"iopub.status.busy":"2021-08-25T22:13:44.143027Z","iopub.execute_input":"2021-08-25T22:13:44.143453Z","iopub.status.idle":"2021-08-25T22:13:47.557535Z","shell.execute_reply.started":"2021-08-25T22:13:44.143416Z","shell.execute_reply":"2021-08-25T22:13:47.556447Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"input_image_file = ('https://data.kitware.com/api/v1/file/'\n                    '576ad39b8d777f1ecd6702f2/download')  # Easy1.png\n\nim_input = skimage.io.imread(input_image_file)[:, :, :3]\n\nplt.imshow(im_input)\n_ = plt.title('Input Image', fontsize=16)","metadata":{"execution":{"iopub.status.busy":"2021-08-25T22:13:47.559591Z","iopub.execute_input":"2021-08-25T22:13:47.560021Z","iopub.status.idle":"2021-08-25T22:13:50.21668Z","shell.execute_reply.started":"2021-08-25T22:13:47.559977Z","shell.execute_reply":"2021-08-25T22:13:50.213857Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Load reference image for normalization\nref_image_file = ('https://data.kitware.com/api/v1/file/'\n                  '57718cc28d777f1ecd8a883c/download')  # L1.png\n\nim_reference = skimage.io.imread(ref_image_file)[:, :, :3]\n\n# get mean and stddev of reference image in lab space\nmean_ref, std_ref = htk.preprocessing.color_conversion.lab_mean_std(im_reference)\n\n# perform reinhard color normalization\nim_nmzd = htk.preprocessing.color_normalization.reinhard(im_input, mean_ref, std_ref)\n\n# Display results\nplt.figure(figsize=(20, 10))\n\nplt.subplot(1, 2, 1)\nplt.imshow(im_reference)\n_ = plt.title('Reference Image', fontsize=titlesize)\n\nplt.subplot(1, 2, 2)\nplt.imshow(im_nmzd)\n_ = plt.title('Normalized Input Image', fontsize=titlesize)","metadata":{"execution":{"iopub.status.busy":"2021-08-25T22:13:50.21998Z","iopub.execute_input":"2021-08-25T22:13:50.220733Z","iopub.status.idle":"2021-08-25T22:13:53.572366Z","shell.execute_reply.started":"2021-08-25T22:13:50.220662Z","shell.execute_reply":"2021-08-25T22:13:53.571414Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# create stain to color map\nstainColorMap = {\n    'hematoxylin': [0.65, 0.70, 0.29],\n    'eosin':       [0.07, 0.99, 0.11],\n    'dab':         [0.27, 0.57, 0.78],\n    'null':        [0.0, 0.0, 0.0]\n}\n\n# specify stains of input image\nstain_1 = 'hematoxylin'   # nuclei stain\nstain_2 = 'eosin'         # cytoplasm stain\nstain_3 = 'null'          # set to null of input contains only two stains\n\n# create stain matrix\nW = np.array([stainColorMap[stain_1],\n              stainColorMap[stain_2],\n              stainColorMap[stain_3]]).T\n\n# perform standard color deconvolution\nim_stains = htk.preprocessing.color_deconvolution.color_deconvolution(im_nmzd, W).Stains\n\n# Display results\nplt.figure(figsize=(20, 10))\n\nplt.subplot(1, 2, 1)\nplt.imshow(im_stains[:, :, 0])\nplt.title(stain_1, fontsize=titlesize)\n\nplt.subplot(1, 2, 2)\nplt.imshow(im_stains[:, :, 1])\n_ = plt.title(stain_2, fontsize=titlesize)","metadata":{"execution":{"iopub.status.busy":"2021-08-25T22:13:53.573777Z","iopub.execute_input":"2021-08-25T22:13:53.57429Z","iopub.status.idle":"2021-08-25T22:13:55.152832Z","shell.execute_reply.started":"2021-08-25T22:13:53.574251Z","shell.execute_reply":"2021-08-25T22:13:55.151751Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# get nuclei/hematoxylin channel\nim_nuclei_stain = im_stains[:, :, 0]\n\n# segment foreground\nforeground_threshold = 60\n\nim_fgnd_mask = sp.ndimage.morphology.binary_fill_holes(\n    im_nuclei_stain < foreground_threshold)\n\n# run adaptive multi-scale LoG filter\nmin_radius = 10\nmax_radius = 15\n\nim_log_max, im_sigma_max = htk.filters.shape.cdog(\n    im_nuclei_stain, im_fgnd_mask,\n    sigma_min=min_radius * np.sqrt(2),\n    sigma_max=max_radius * np.sqrt(2)\n)\n\n# detect and segment nuclei using local maximum clustering\nlocal_max_search_radius = 10\n\nim_nuclei_seg_mask, seeds, maxima = htk.segmentation.nuclear.max_clustering(\n    im_log_max, im_fgnd_mask, local_max_search_radius)\n\n# filter out small objects\nmin_nucleus_area = 80\n\nim_nuclei_seg_mask = htk.segmentation.label.area_open(\n    im_nuclei_seg_mask, min_nucleus_area).astype(np.int)\n\n# compute nuclei properties\nobjProps = skimage.measure.regionprops(im_nuclei_seg_mask)\n\nprint('Number of nuclei = ', len(objProps))\n\n# Display results\nplt.figure(figsize=(20, 10))\n\nplt.subplot(1, 2, 1)\nplt.imshow(skimage.color.label2rgb(im_nuclei_seg_mask, im_input, bg_label=0), origin='lower')\nplt.title('Nuclei segmentation mask overlay', fontsize=titlesize)\n\nplt.subplot(1, 2, 2)\nplt.imshow( im_input )\nplt.xlim([0, im_input.shape[1]])\nplt.ylim([0, im_input.shape[0]])\nplt.title('Nuclei bounding boxes', fontsize=titlesize)\n\nfor i in range(len(objProps)):\n\n    c = [objProps[i].centroid[1], objProps[i].centroid[0], 0]\n    width = objProps[i].bbox[3] - objProps[i].bbox[1] + 1\n    height = objProps[i].bbox[2] - objProps[i].bbox[0] + 1\n\n    cur_bbox = {\n        \"type\":        \"rectangle\",\n        \"center\":      c,\n        \"width\":       width,\n        \"height\":      height,\n    }\n\n    plt.plot(c[0], c[1], 'g+')\n    mrect = mpatches.Rectangle([c[0] - 0.5 * width, c[1] - 0.5 * height] ,\n                               width, height, fill=False, ec='g', linewidth=2)\n    plt.gca().add_patch(mrect)","metadata":{"execution":{"iopub.status.busy":"2021-08-25T22:13:55.154441Z","iopub.execute_input":"2021-08-25T22:13:55.155078Z","iopub.status.idle":"2021-08-25T22:13:59.505459Z","shell.execute_reply.started":"2021-08-25T22:13:55.155015Z","shell.execute_reply":"2021-08-25T22:13:59.501971Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}