pyclustering  0.10.1
pyclustring is a Python, C++ data mining library.
syncsegm.py
1 """!
2 
3 @brief Double-layer oscillatory network with phase oscillator for image segmentation.
4 @details Implementation based on paper @cite inproceedings::nnet::syncsegm::1.
5 
6 @authors Andrei Novikov (pyclustering@yandex.ru)
7 @date 2014-2020
8 @copyright BSD-3-Clause
9 
10 """
11 
12 import warnings
13 
14 from math import floor
15 
16 try:
17  from PIL import Image
18 except Exception as error_instance:
19  warnings.warn("Impossible to import PIL (please, install 'PIL'), pyclustering's visualization "
20  "functionality is partially not available (details: '%s')." % str(error_instance))
21 
22 from pyclustering.cluster.syncnet import syncnet
23 
24 from pyclustering.nnet import solve_type, initial_type
25 from pyclustering.nnet.sync import sync_visualizer
26 
27 from pyclustering.utils import read_image
28 
29 
31  """!
32  @brief Result visualizer of double-layer oscillatory network 'syncsegm'.
33 
34  """
35 
36  @staticmethod
37  def show_first_layer_dynamic(analyser):
38  """!
39  @brief Shows output dynamic of the first layer.
40 
41  @param[in] analyser (syncsegm_analyser): Analyser of output dynamic of the 'syncsegm' oscillatory network.
42 
43  """
44 
45  sync_visualizer.show_output_dynamic(analyser.get_first_layer_analyser());
46 
47 
48  @staticmethod
50  """!
51  @brief Shows output dynamic of the second layer.
52 
53  @param[in] analyser (syncsegm_analyser): Analyser of output dynamic of the 'syncsegm' oscillatory network.
54 
55  """
56 
57  second_layer_analysers = analyser.get_second_layer_analysers();
58  analysers_sequence = [ object_segment_analyser['analyser'] for object_segment_analyser in second_layer_analysers ]
59 
60  sync_visualizer.show_output_dynamics(analysers_sequence);
61 
62 
64  """!
65  @brief Performs analysis of output dynamic of the double-layer oscillatory network 'syncsegm' to extract information about segmentation results.
66 
67  """
68 
69  def __init__(self, color_analyser, object_segment_analysers = None):
70  """!
71  @brief Constructor of the analyser.
72 
73  @param[in] color_analyser (list): Analyser of coloring segmentation results of the first layer.
74  @param[in] object_segment_analysers (list): Analysers of objects on image segments - results of the second layer.
75 
76  """
77 
78  self.__color_analyser = color_analyser;
79  self.__object_segment_analysers = object_segment_analysers;
80 
81 
83  """!
84  @brief Returns analyser of coloring segmentation of the first layer.
85 
86  """
87 
88  return self.__color_analyser;
89 
90 
92  """!
93  @brief Returns analysers of object segmentation of the second layer.
94 
95  """
96 
97  return self.__object_segment_analysers;
98 
99 
100  def allocate_colors(self, eps = 0.01, noise_size = 1):
101  """!
102  @brief Allocates color segments.
103 
104  @param[in] eps (double): Tolerance level that define maximal difference between phases of oscillators in one segment.
105  @param[in] noise_size (uint): Threshold that defines noise - segments size (in pixels) that is less then the threshold is considered as a noise.
106 
107  @return (list) Color segments where each color segment consists of indexes of pixels that forms color segment.
108 
109  """
110 
111  segments = self.__color_analyser.allocate_clusters(eps);
112  real_segments = [cluster for cluster in segments if len(cluster) > noise_size];
113  return real_segments;
114 
115 
116  def allocate_objects(self, eps = 0.01, noise_size = 1):
117  """!
118  @brief Allocates object segments.
119 
120  @param[in] eps (double): Tolerance level that define maximal difference between phases of oscillators in one segment.
121  @param[in] noise_size (uint): Threshold that defines noise - segments size (in pixels) that is less then the threshold is considered as a noise.
122 
123  @return (list) Object segments where each object segment consists of indexes of pixels that forms object segment.
124 
125  """
126 
127  if (self.__object_segment_analysers is None):
128  return [];
129 
130  segments = [];
131  for object_segment_analyser in self.__object_segment_analysers:
132  indexes = object_segment_analyser['color_segment'];
133  analyser = object_segment_analyser['analyser'];
134 
135  segments += analyser.allocate_clusters(eps, indexes);
136 
137  real_segments = [segment for segment in segments if len(segment) > noise_size];
138  return real_segments;
139 
140 
141 class syncsegm:
142  """!
143  @brief Class represents segmentation algorithm syncsegm.
144  @details syncsegm is a bio-inspired algorithm that is based on double-layer oscillatory network that uses modified Kuramoto model.
145  Algorithm extracts colors and colored objects. It uses only CCORE (C++ implementation of pyclustering) parts to implement the algorithm.
146 
147  CCORE option is True by default to use sync network in the pyclustering core - C/C++ shared library for processing that significantly increases performance.
148 
149  Example:
150  @code
151  # create oscillatory for image segmentaion - extract colors (radius 128) and objects (radius 4),
152  # and ignore noise (segments with size that is less than 10 pixels)
153  algorithm = syncsegm(128, 4, 10);
154 
155  # extract segments (colors and objects)
156  analyser = algorithm(path_to_file);
157 
158  # obtain segmentation results (only colors - from the first layer)
159  color_segments = analyser.allocate_colors(0.01, 10);
160  draw_image_mask_segments(path_to_file, color_segments);
161 
162  # obtain segmentation results (objects - from the second layer)
163  object_segments = analyser.allocate_objects(0.01, 10);
164  draw_image_mask_segments(path_to_file, object_segments);
165  @endcode
166 
167  """
168 
169  def __init__(self, color_radius, object_radius, noise_size = 0, ccore = True):
170  """!
171  @brief Contructor of the oscillatory network SYNC for cluster analysis.
172 
173  @param[in] color_radius (double): Radius of color connectivity (color similarity) for the first layer.
174  @param[in] object_radius (double): Radius of object connectivity (object similarity) for the second layer,
175  if 'None' then object segmentation is not performed (only color segmentation).
176  @param[in] noise_size (double): Size of segment that should be considered as a noise and ignored by the second layer.
177  @param[in] ccore (bool): If 'True' then C/C++ implementation is used to increase performance.
178 
179  """
180 
181  self.__color_radius = color_radius;
182  self.__object_radius = object_radius;
183  self.__noise_size = noise_size;
184 
185  self.__order_color = 0.9995;
186  self.__order_object = 0.999;
187 
188  self.__network = None;
189  self.__ccore = ccore;
190 
191 
192  def process(self, image_source, collect_dynamic = False, order_color = 0.9995, order_object = 0.999):
193  """!
194  @brief Performs image segmentation.
195 
196  @param[in] image_source (string): Path to image file that should be processed.
197  @param[in] collect_dynamic (bool): If 'True' then whole dynamic of each layer of the network is collected.
198  @param[in] order_color (double): Local synchronization order for the first layer - coloring segmentation.
199  @param[in] order_object (double): Local synchronization order for the second layer - object segmentation.
200 
201  @return (syncsegm_analyser) Analyser of segmentation results by the network.
202 
203  """
204 
205  self.__order_color = order_color
206  self.__order_object = order_object
207 
208  data = read_image(image_source)
209  color_analyser = self.__analyse_colors(data, collect_dynamic)
210 
211  if self.__object_radius is None:
212  return syncsegm_analyser(color_analyser, None)
213 
214  object_segment_analysers = self.__analyse_objects(image_source, color_analyser, collect_dynamic)
215  return syncsegm_analyser(color_analyser, object_segment_analysers)
216 
217 
218  def __analyse_colors(self, image_data, collect_dynamic):
219  """!
220  @brief Performs color segmentation by the first layer.
221 
222  @param[in] image_data (array_like): Image sample as a array-like structure.
223  @param[in] collect_dynamic (bool): If 'True' then whole dynamic of the first layer of the network is collected.
224 
225  @return (syncnet_analyser) Analyser of color segmentation results of the first layer.
226 
227  """
228 
229  network = syncnet(image_data, self.__color_radius, initial_phases = initial_type.RANDOM_GAUSSIAN, ccore = self.__ccore);
230  analyser = network.process(self.__order_color, solve_type.FAST, collect_dynamic);
231 
232  return analyser;
233 
234 
235  def __analyse_objects(self, image_source, color_analyser, collect_dynamic):
236  """!
237  @brief Performs object segmentation by the second layer.
238 
239  @param[in] image_source (string): Path to image file that should be processed.
240  @param[in] color_analyser (syncnet_analyser): Analyser of color segmentation results.
241  @param[in] collect_dynamic (bool): If 'True' then whole dynamic of the first layer of the network is collected.
242 
243  @return (map) Analysers of object segments.
244 
245  """
246 
247  # continue analysis
248  pointer_image = Image.open(image_source);
249  image_size = pointer_image.size;
250 
251  object_analysers = [];
252 
253  color_segments = color_analyser.allocate_clusters();
254 
255  for segment in color_segments:
256  object_analyser = self.__analyse_color_segment(image_size, segment, collect_dynamic);
257  if (object_analyser is not None):
258  object_analysers.append( { 'color_segment': segment, 'analyser': object_analyser } );
259 
260  pointer_image.close();
261  return object_analysers;
262 
263 
264  def __analyse_color_segment(self, image_size, color_segment, collect_dynamic):
265  """!
266  @brief Performs object segmentation of separate segment.
267 
268  @param[in] image_size (list): Image size presented as a [width x height].
269  @param[in] color_segment (list): Image segment that should be processed.
270  @param[in] collect_dynamic (bool): If 'True' then whole dynamic of the second layer of the network is collected.
271 
272  @return (syncnet_analyser) Analyser of object segmentation results of the second layer.
273 
274  """
275  coordinates = self.__extract_location_coordinates(image_size, color_segment);
276 
277  if (len(coordinates) < self.__noise_size):
278  return None;
279 
280  network = syncnet(coordinates, self.__object_radius, initial_phases = initial_type.EQUIPARTITION, ccore = True);
281  analyser = network.process(self.__order_object, solve_type.FAST, collect_dynamic);
282 
283  return analyser;
284 
285 
286  def __extract_location_coordinates(self, image_size, color_segment):
287  """!
288  @brief Extracts coordinates of specified image segment.
289 
290  @param[in] image_size (list): Image size presented as a [width x height].
291  @param[in] color_segment (list): Image segment whose coordinates should be extracted.
292 
293  @return (list) Coordinates of each pixel.
294 
295  """
296  coordinates = [];
297  for index in color_segment:
298  y = floor(index / image_size[0]);
299  x = index - y * image_size[0];
300 
301  coordinates.append([x, y]);
302 
303  return coordinates;
304 
pyclustering.nnet.syncsegm.syncsegm_analyser.__color_analyser
__color_analyser
Definition: syncsegm.py:78
pyclustering.nnet.syncsegm.syncsegm_analyser.__object_segment_analysers
__object_segment_analysers
Definition: syncsegm.py:79
pyclustering.nnet.syncsegm.syncsegm_visualizer
Result visualizer of double-layer oscillatory network 'syncsegm'.
Definition: syncsegm.py:30
pyclustering.nnet.sync
Neural Network: Oscillatory Neural Network based on Kuramoto model.
Definition: sync.py:1
pyclustering.nnet.syncsegm.syncsegm.__color_radius
__color_radius
Definition: syncsegm.py:181
pyclustering.cluster.syncnet
Cluster analysis algorithm: Sync.
Definition: syncnet.py:1
pyclustering.nnet.syncsegm.syncsegm.__noise_size
__noise_size
Definition: syncsegm.py:183
pyclustering.nnet.syncsegm.syncsegm_analyser.__init__
def __init__(self, color_analyser, object_segment_analysers=None)
Constructor of the analyser.
Definition: syncsegm.py:69
pyclustering.nnet.syncsegm.syncsegm_analyser.get_second_layer_analysers
def get_second_layer_analysers(self)
Returns analysers of object segmentation of the second layer.
Definition: syncsegm.py:91
pyclustering.cluster.syncnet.syncnet
Class represents clustering algorithm SyncNet.
Definition: syncnet.py:146
pyclustering.nnet.syncsegm.syncsegm_visualizer.show_first_layer_dynamic
def show_first_layer_dynamic(analyser)
Shows output dynamic of the first layer.
Definition: syncsegm.py:37
pyclustering.nnet.syncsegm.syncsegm.__ccore
__ccore
Definition: syncsegm.py:189
pyclustering.nnet.syncsegm.syncsegm
Class represents segmentation algorithm syncsegm.
Definition: syncsegm.py:141
pyclustering.nnet.syncsegm.syncsegm_analyser.allocate_colors
def allocate_colors(self, eps=0.01, noise_size=1)
Allocates color segments.
Definition: syncsegm.py:100
pyclustering.nnet.syncsegm.syncsegm_visualizer.show_second_layer_dynamic
def show_second_layer_dynamic(analyser)
Shows output dynamic of the second layer.
Definition: syncsegm.py:49
pyclustering.nnet.syncsegm.syncsegm.process
def process(self, image_source, collect_dynamic=False, order_color=0.9995, order_object=0.999)
Performs image segmentation.
Definition: syncsegm.py:192
pyclustering.nnet.syncsegm.syncsegm.__order_object
__order_object
Definition: syncsegm.py:186
pyclustering.nnet.syncsegm.syncsegm.__analyse_objects
def __analyse_objects(self, image_source, color_analyser, collect_dynamic)
Performs object segmentation by the second layer.
Definition: syncsegm.py:235
pyclustering.nnet.syncsegm.syncsegm.__init__
def __init__(self, color_radius, object_radius, noise_size=0, ccore=True)
Contructor of the oscillatory network SYNC for cluster analysis.
Definition: syncsegm.py:169
pyclustering.nnet
Neural and oscillatory network module. Consists of models of bio-inspired networks.
Definition: __init__.py:1
pyclustering.nnet.syncsegm.syncsegm.__extract_location_coordinates
def __extract_location_coordinates(self, image_size, color_segment)
Extracts coordinates of specified image segment.
Definition: syncsegm.py:286
pyclustering.nnet.syncsegm.syncsegm_analyser.allocate_objects
def allocate_objects(self, eps=0.01, noise_size=1)
Allocates object segments.
Definition: syncsegm.py:116
pyclustering.nnet.syncsegm.syncsegm.__analyse_colors
def __analyse_colors(self, image_data, collect_dynamic)
Performs color segmentation by the first layer.
Definition: syncsegm.py:218
pyclustering.nnet.syncsegm.syncsegm.__object_radius
__object_radius
Definition: syncsegm.py:182
pyclustering.nnet.syncsegm.syncsegm.__network
__network
Definition: syncsegm.py:188
pyclustering.nnet.syncsegm.syncsegm.__order_color
__order_color
Definition: syncsegm.py:185
pyclustering.nnet.syncsegm.syncsegm.__analyse_color_segment
def __analyse_color_segment(self, image_size, color_segment, collect_dynamic)
Performs object segmentation of separate segment.
Definition: syncsegm.py:264
pyclustering.utils
Utils that are used by modules of pyclustering.
Definition: __init__.py:1
pyclustering.nnet.syncsegm.syncsegm_analyser
Performs analysis of output dynamic of the double-layer oscillatory network 'syncsegm' to extract inf...
Definition: syncsegm.py:63
pyclustering.nnet.syncsegm.syncsegm_analyser.get_first_layer_analyser
def get_first_layer_analyser(self)
Returns analyser of coloring segmentation of the first layer.
Definition: syncsegm.py:82