MahdiKamyabi commited on
Commit
9bd0d04
1 Parent(s): 82813c6

Upload plot_morphsnakes.py

Browse files
Files changed (1) hide show
  1. plot_morphsnakes.py +168 -0
plot_morphsnakes.py ADDED
@@ -0,0 +1,168 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ ====================
3
+ Morphological Snakes
4
+ ====================
5
+
6
+ *Morphological Snakes* [1]_ are a family of methods for image segmentation.
7
+ Their behavior is similar to that of active contours (for example, *Geodesic
8
+ Active Contours* [2]_ or *Active Contours without Edges* [3]_). However,
9
+ *Morphological Snakes* use morphological operators (such as dilation or
10
+ erosion) over a binary array instead of solving PDEs over a floating point
11
+ array, which is the standard approach for active contours. This makes
12
+ *Morphological Snakes* faster and numerically more stable than their
13
+ traditional counterpart.
14
+
15
+ There are two *Morphological Snakes* methods available in this implementation:
16
+ *Morphological Geodesic Active Contours* (**MorphGAC**, implemented in the
17
+ function ``morphological_geodesic_active_contour``) and *Morphological Active
18
+ Contours without Edges* (**MorphACWE**, implemented in the function
19
+ ``morphological_chan_vese``).
20
+
21
+ **MorphGAC** is suitable for images with visible contours, even when these
22
+ contours might be noisy, cluttered, or partially unclear. It requires, however,
23
+ that the image is preprocessed to highlight the contours. This can be done
24
+ using the function ``inverse_gaussian_gradient``, although the user might want
25
+ to define their own version. The quality of the **MorphGAC** segmentation
26
+ depends greatly on this preprocessing step.
27
+
28
+ On the contrary, **MorphACWE** works well when the pixel values of the inside
29
+ and the outside regions of the object to segment have different averages.
30
+ Unlike **MorphGAC**, **MorphACWE** does not require that the contours of the
31
+ object are well defined, and it works over the original image without any
32
+ preceding processing. This makes **MorphACWE** easier to use and tune than
33
+ **MorphGAC**.
34
+
35
+ References
36
+ ----------
37
+
38
+ .. [1] A Morphological Approach to Curvature-based Evolution of Curves and
39
+ Surfaces, Pablo Márquez-Neila, Luis Baumela and Luis Álvarez. In IEEE
40
+ Transactions on Pattern Analysis and Machine Intelligence (PAMI),
41
+ 2014, :DOI:`10.1109/TPAMI.2013.106`
42
+ .. [2] Geodesic Active Contours, Vicent Caselles, Ron Kimmel and Guillermo
43
+ Sapiro. In International Journal of Computer Vision (IJCV), 1997,
44
+ :DOI:`10.1023/A:1007979827043`
45
+ .. [3] Active Contours without Edges, Tony Chan and Luminita Vese. In IEEE
46
+ Transactions on Image Processing, 2001, :DOI:`10.1109/83.902291`
47
+
48
+ """
49
+ import os
50
+ from PIL import Image
51
+ import numpy as np
52
+ import matplotlib.pyplot as plt
53
+ from skimage import data, img_as_float
54
+ from skimage.segmentation import (morphological_chan_vese,
55
+ morphological_geodesic_active_contour,
56
+ inverse_gaussian_gradient,
57
+ checkerboard_level_set, clear_border)
58
+ from skimage.morphology import binary_closing, binary_opening, binary_erosion,disk
59
+ from scipy import ndimage as ndi
60
+ from skimage.filters import roberts, sobel
61
+ from cv2 import imread
62
+ from cv2 import imshow
63
+ from cv2 import waitKey
64
+ import cv2
65
+ def store_evolution_in(lst):
66
+ """Returns a callback function to store the evolution of the level sets in
67
+ the given list.
68
+ """
69
+
70
+ def _store(x):
71
+ lst.append(np.copy(x))
72
+
73
+ return _store
74
+
75
+ images = sorted(os.listdir('./1.3.6.1.4.1.14519.5.2.1.6279.6001.861997885565255340442123234170/'))
76
+ # print(images)
77
+ for k, img in enumerate(images):
78
+ # Morphological ACWE
79
+ image1 = imread(f'./1.3.6.1.4.1.14519.5.2.1.6279.6001.861997885565255340442123234170/{img}', 0)
80
+ image = image1.copy()
81
+ clenimage = image1.copy()
82
+ # Initial level set
83
+ init_ls = checkerboard_level_set(image.shape, 6)
84
+ # List with intermediate results for plotting the evolution
85
+ evolution = []
86
+ callback = store_evolution_in(evolution)
87
+ ls = morphological_chan_vese(image, num_iter=35, init_level_set=init_ls,
88
+ smoothing=3, iter_callback=callback)
89
+
90
+ fig, axes = plt.subplots(2, 2, figsize=(8, 8))
91
+ ax = axes.flatten()
92
+
93
+ ax[0].imshow(image, cmap="gray")
94
+ ax[0].set_axis_off()
95
+ ax[0].contour(ls, [0.5], colors='r')
96
+ ax[0].set_title("Morphological ACWE segmentation", fontsize=12)
97
+
98
+ ret,thresh = cv2.threshold(image1,70,255,0)
99
+
100
+ image1 = clear_border(cv2.bitwise_not(thresh))
101
+ selem = disk(2)
102
+ image1 = binary_erosion(image1,selem)
103
+ selem = disk(10)
104
+ image1 = binary_closing(image1,selem)
105
+ edges = roberts(image1)
106
+ image1 = ndi.binary_fill_holes(edges)
107
+ percentage_white = np.sum(image1== 1)
108
+ # print(percentage_white)
109
+ if (percentage_white / (image1.shape[0]*image1.shape[1])) >= 0.1:
110
+ ax[1].imshow(image1, cmap=plt.cm.bone)
111
+ ax[1].set_axis_off()
112
+ # contour = ax[1].contour(evolution[2], [0.5], colors='g')
113
+ # contour.collections[0].set_label("Iteration 2")
114
+ # contour = ax[1].contour(evolution[7], [0.5], colors='y')
115
+ # contour.collections[0].set_label("Iteration 7")
116
+ # contour = ax[1].contour(evolution[-1], [0.5], colors='r')
117
+ # contour.collections[0].set_label("Iteration 35")
118
+ # ax[1].legend(loc="upper right")
119
+ # title = "Morphological ACWE evolution"
120
+ # ax[1].set_title(title, fontsize=12)
121
+
122
+
123
+ # Morphological GAC
124
+ # image = img_as_float(data.coins())
125
+ #gimage = inverse_gaussian_gradient(image)
126
+
127
+ # Initial level set
128
+ #init_ls = np.zeros(image.shape, dtype=np.int8)
129
+ #init_ls[10:-10, 10:-10] = 1
130
+ # List with intermediate results for plotting the evolution
131
+ #evolution = []
132
+ #callback = store_evolution_in(evolution)
133
+ #ls = morphological_geodesic_active_contour(gimage, num_iter=230,
134
+ # init_level_set=init_ls,
135
+ # smoothing=1, balloon=-1,
136
+ # threshold=0.69,
137
+ # iter_callback=callback)
138
+ ZERO_VALUE = -2000
139
+ get_high_vals = (image1 == 0)
140
+ clenimage[get_high_vals] = ZERO_VALUE
141
+
142
+ ax[2].imshow(clenimage, cmap="gray")
143
+ ax[2].set_axis_off()
144
+ #ax[2].contour(ls, [0.5], colors='r')
145
+ #ax[2].set_title("Morphological GAC segmentation", fontsize=12)
146
+ # print(type(image))
147
+ # ret3,th3 = cv2.threshold(image,200,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
148
+ ret1,th1 = cv2.threshold(clenimage,150,255,cv2.THRESH_BINARY) #T
149
+ selem = disk(2) #T
150
+ th1 = binary_erosion(th1,selem)
151
+ im = Image.fromarray(th1)
152
+ # print(type(th1))
153
+ img = img.split('.')[0]
154
+ im.save(f'{img}.jpg')
155
+ ax[3].imshow(th1, cmap="gray")
156
+ ax[3].set_axis_off()
157
+ #contour = ax[3].contour(evolution[0], [0.5], colors='g')
158
+ #contour.collections[0].set_label("Iteration 0")
159
+ #contour = ax[3].contour(evolution[100], [0.5], colors='y')
160
+ #contour.collections[0].set_label("Iteration 100")
161
+ #contour = ax[3].contour(evolution[-1], [0.5], colors='r')
162
+ #contour.collections[0].set_label("Iteration 230")
163
+ #ax[3].legend(loc="upper right")
164
+ #title = "Morphological GAC evolution"
165
+ #ax[3].set_title(title, fontsize=12)
166
+
167
+ # fig.tight_layout()
168
+ # plt.show()