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

Upload morphsnakes .py

Browse files
Files changed (1) hide show
  1. morphsnakes .py +156 -0
morphsnakes .py ADDED
@@ -0,0 +1,156 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+
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)
58
+ from cv2 import imread
59
+ from cv2 import imshow
60
+ from cv2 import waitKey
61
+ import cv2
62
+ def store_evolution_in(lst):
63
+ """Returns a callback function to store the evolution of the level sets in
64
+ the given list.
65
+ """
66
+
67
+ def _store(x):
68
+ lst.append(np.copy(x))
69
+
70
+ return _store
71
+
72
+ images = sorted(os.listdir('./mini/'))
73
+ # print(images)
74
+ for k, img in enumerate(images):
75
+ # Morphological ACWE
76
+ image1 = imread(f'./mini/{img}', 0)
77
+ image = image1.copy()
78
+ # Initial level set
79
+ init_ls = checkerboard_level_set(image.shape, 6)
80
+ # List with intermediate results for plotting the evolution
81
+ evolution = []
82
+ callback = store_evolution_in(evolution)
83
+ ls = morphological_chan_vese(image, num_iter=35, init_level_set=init_ls,
84
+ smoothing=3, iter_callback=callback)
85
+
86
+ fig, axes = plt.subplots(2, 2, figsize=(8, 8))
87
+ ax = axes.flatten()
88
+
89
+ ax[0].imshow(image, cmap="gray")
90
+ ax[0].set_axis_off()
91
+ ax[0].contour(ls, [0.5], colors='r')
92
+ ax[0].set_title("Morphological ACWE segmentation", fontsize=12)
93
+ withe = np.ones_like(image, dtype='uint8') * 255
94
+
95
+ ret1,thresh1 = cv2.threshold(withe,70,255,0)
96
+ ret,thresh = cv2.threshold(image1,70,255,0)
97
+
98
+ new = np.bitwise_and(cv2.bitwise_not(ls),thresh)[140:420,70:420]
99
+
100
+ for i in range(new.shape[0]):
101
+ for j in range(new.shape[1]):
102
+ if new[i][j] > 0:
103
+ new[i][j] -= 130
104
+
105
+
106
+ cv2.imwrite(f'./output/{img}', new)
107
+
108
+
109
+ # ax[1].imshow(ls, cmap="gray")
110
+ # ax[1].set_axis_off()
111
+ # contour = ax[1].contour(evolution[2], [0.5], colors='g')
112
+ # contour.collections[0].set_label("Iteration 2")
113
+ # contour = ax[1].contour(evolution[7], [0.5], colors='y')
114
+ # contour.collections[0].set_label("Iteration 7")
115
+ # contour = ax[1].contour(evolution[-1], [0.5], colors='r')
116
+ # contour.collections[0].set_label("Iteration 35")
117
+ # ax[1].legend(loc="upper right")
118
+ # title = "Morphological ACWE evolution"
119
+ # ax[1].set_title(title, fontsize=12)
120
+
121
+
122
+ # Morphological GAC
123
+ # image = img_as_float(data.coins())
124
+ #gimage = inverse_gaussian_gradient(image)
125
+
126
+ # Initial level set
127
+ #init_ls = np.zeros(image.shape, dtype=np.int8)
128
+ #init_ls[10:-10, 10:-10] = 1
129
+ # List with intermediate results for plotting the evolution
130
+ #evolution = []
131
+ #callback = store_evolution_in(evolution)
132
+ #ls = morphological_geodesic_active_contour(gimage, num_iter=230,
133
+ # init_level_set=init_ls,
134
+ # smoothing=1, balloon=-1,
135
+ # threshold=0.69,
136
+ # iter_callback=callback)
137
+
138
+ # ax[2].imshow(new, cmap="gray")
139
+ # ax[2].set_axis_off()
140
+ #ax[2].contour(ls, [0.5], colors='r')
141
+ #ax[2].set_title("Morphological GAC segmentation", fontsize=12)
142
+
143
+ #ax[3].imshow(ls, cmap="gray")
144
+ #ax[3].set_axis_off()
145
+ #contour = ax[3].contour(evolution[0], [0.5], colors='g')
146
+ #contour.collections[0].set_label("Iteration 0")
147
+ #contour = ax[3].contour(evolution[100], [0.5], colors='y')
148
+ #contour.collections[0].set_label("Iteration 100")
149
+ #contour = ax[3].contour(evolution[-1], [0.5], colors='r')
150
+ #contour.collections[0].set_label("Iteration 230")
151
+ #ax[3].legend(loc="upper right")
152
+ #title = "Morphological GAC evolution"
153
+ #ax[3].set_title(title, fontsize=12)
154
+
155
+ # fig.tight_layout()
156
+ # plt.show()