/
course_functions.py
executable file
·115 lines (84 loc) · 2.91 KB
/
course_functions.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import os, sys
import numpy as np
import skimage.morphology as skm
import skimage.filters as skf
from skimage.measure import label, regionprops
from skimage.feature import match_template, peak_local_max
#Define the path of leading to Data folder
def define_data_path():
if 'google.colab' in sys.modules:
datapath = '/content/gdrive/My Drive/'
else:
datapath = '../'
return datapath
def detect_nuclei(image, size = 200, shape = 0.8):
"""Detect nuclei in image using binary operations
Parameters
----------
image : 2D numpy array
image to be segmented
size: number
maximal nucleus size
shape: float
minimal nucleus eccentricity
Returns
-------
newimage : 2D numpy array
mask of nuclei
"""
#median filter
image_med = skf.rank.median(image,selem=np.ones((2,2)))
#otsu thresholding
image_local_threshold = skf.threshold_local(image_med,block_size=51)
image_local = image > image_local_threshold
#remove tiny features
image_local_eroded = skm.binary_erosion(image_local, selem= skm.disk(1))
#label image
image_labeled = label(image_local_eroded)
#analyze regions
our_regions = regionprops(image_labeled)
#create a new mask with constraints on the regions to keep
newimage = np.zeros(image.shape)
#fill in using region coordinates
for x in our_regions:
if (x.area>200):# and (x.eccentricity>shape):
newimage[x.coords[:,0],x.coords[:,1]] = 1
return newimage
def create_disk_template(radius):
"""Create a disk image
Parameters
----------
radius : int
radius of disk
Returns
-------
template : 2D numpy array
binary image of a disk
"""
template = np.zeros((2*radius+5,2*radius+5))
center = [(template.shape[0]-1)/2,(template.shape[1]-1)/2]
Y, X = np.mgrid[0:template.shape[0],0:template.shape[1]]
dist_from_center = np.sqrt((X - center[0])**2 + (Y-center[1])**2)
template[dist_from_center<=radius] = 1
return template
def detect_nuclei_template(image, template):
"""Detect nuclei in image using template matching
Parameters
----------
image : 2D numpy array
image to be segmented
template: 2D numpy array
template for nucleus shape
Returns
-------
masked_peaks : 2D numpy array
mask where each nucleus is represented by a single white pixel
otsu_mask : maks obtained using the Otsu threshold
"""
matched = match_template(image=image, template=template, pad_input=True)
local_max = peak_local_max(matched, min_distance=10,indices=False)
otsu = skf.threshold_otsu(image)
otsu_mask = image>otsu
otsu_mask = skm.binary_dilation(otsu_mask, np.ones((5,5)))
masked_peaks = local_max*otsu_mask
return masked_peaks, otsu_mask