Image.py 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  1. import pandas as pd
  2. import scipy.misc as sm
  3. from skimage.measure import label
  4. from skimage.segmentation import clear_border
  5. from skimage.color import label2rgb
  6. from skimage.measure import label, regionprops
  7. from skimage import filters, io
  8. from image_features_extraction import Regions
  9. from image_features_extraction import MyException
  10. from image_features_extraction import Features
  11. from image_features_extraction import Utils
  12. import Voronoi_Features.Voronoi as VF
  13. class Image(object):
  14. """
  15. This class instantiate an object Image through the :class:`Images` and refers to a specific file image
  16. :example:
  17. >>> import image_features_extraction as fe
  18. >>> imgs = fe.Images(folder_name)
  19. >>> img = imgs.item(1)
  20. """
  21. def __init__(self, full_name):
  22. self.__full_file_name = full_name
  23. self.__regions = None
  24. self.__regionsprops = None
  25. self.__image_intensity = None
  26. self.__image = None
  27. self.__image_semented = None
  28. try:
  29. # load image and segment
  30. self.__image = io.imread(self.__full_file_name)
  31. self.__image_semented = self.__get_regions()
  32. self.__regionsprops = self.__get_regionsprop()
  33. self.__centroids = self.prop_values('centroid')
  34. except MyException.MyException as e:
  35. print(e.args)
  36. def Voronoi(self):
  37. """
  38. Image Voronoi diagram (refer to documentaiton of my package Voronoi_Features in my github )
  39. :return: Voronoi object for the current image
  40. :rtype: Voronoi object
  41. >>> import matplotlib.pyplot as plt
  42. >>>
  43. >>> import image_features_extraction as fe
  44. >>>
  45. >>> imgs = fe.Images(folder_name)
  46. >>> img = imgs.item(1)
  47. >>>
  48. >>> voro = img.Voronoi()
  49. >>> # show voronoi diagram
  50. >>> fig = plt.figure(figsize=(20,20))
  51. >>> plt.imshow(vor.get_voronoi_map(), cmap=plt.get_cmap('jet'))
  52. """
  53. return VF.Voronoi(self.__centroids, self.__image.shape[1], self.__image.shape[0])
  54. def width(self):
  55. return self.__image.shape[1]
  56. def height(self):
  57. return self.__image.shape[0]
  58. def file_name(self):
  59. """
  60. full file name of the image
  61. :returns: file name
  62. :rtype: string
  63. """
  64. return self.__full_file_name
  65. def set_image_intensity(self, image_intensity):
  66. """
  67. Sets the image to measurs image's region intensity properties (e.g, mean_intensity)
  68. : param image_intensity: Image object for intensity measurement
  69. : type image_intensity: Object Image
  70. :returns: the set Image object for intensity measurement
  71. :rtype: Object Image
  72. >>> import image_features_extraction as fe
  73. >>> imgs = fe.Images(folder_name)
  74. >>> img = imgs.item(1) # this is the binary image used for segmentation
  75. >>> img_intensity = imgs.item(0) # this is the original image on which to measure intensities
  76. >>> img.set_image_intensity(img_intensity)
  77. >>> features = IMG.features(['label', 'area','perimeter', 'centroid','major_axis_length', 'moments','mean_intensity'], class_value=5)
  78. """
  79. self.__image_intensity = image_intensity.__image
  80. self.__regionsprops = self.__get_regionsprop()
  81. def regions(self):
  82. """
  83. regions(...) returns the Object Regions
  84. :returns: :class:`Regions`
  85. :rtype: string
  86. >>> import image_features_extraction as fe
  87. >>> imgs = fe.Images(folder_name)
  88. >>> img = imgs.item(1)
  89. >>> regs = img.Regions()
  90. """
  91. try:
  92. return Regions.Regions(self.__image_semented) # (self.__get_regions())
  93. except MyException.MyException as e:
  94. print(e.args)
  95. return None
  96. def __get_regions(self):
  97. # apply thresholding
  98. val = filters.threshold_otsu(self.__image)
  99. # segmentation
  100. image_thresh = self.__image > val
  101. # returns the single segmented elements of the image
  102. image_segment = label(image_thresh)
  103. # removes the image elements at the borde
  104. return clear_border(image_segment)
  105. #def __get_mask(self, redo=False):
  106. # if redo == False:
  107. # return self.__mask
  108. # # ithresholding to build the map
  109. # val = filters.threshold_otsu(self.__image)
  110. # # cretes the mask
  111. # return self.__image > val
  112. def __get_regionsprop(self):
  113. return regionprops(self.__get_regions(), intensity_image=self.__image_intensity)
  114. def get_image_segmentation(self):
  115. """
  116. Builds the image with mask overlay to show the segmentation
  117. :returns: The image in RGB format, in a 3-D array of shape (.., .., 3).
  118. :rtype: ndarray
  119. """
  120. try:
  121. return label2rgb(self.__get_regions(), image=self.__image)
  122. except MyException.MyException as e:
  123. print(e.args)
  124. return None
  125. def features(self, features_list, prefix='', suffix=''):
  126. """
  127. Returns a table with all values for the property names given in input, and supplies an
  128. additional parameter for feature classification
  129. :param features_list: list of property/measure names (e.g, 'area', 'centroid', etc )
  130. :type features_list: List
  131. :param prefix: prefix for features name
  132. :type prefix: string
  133. :param suffix: prefix for features name
  134. :type suffix: string
  135. :returns: Features Object
  136. :rtype: Features Object
  137. :example:
  138. >>> import image_features_extraction as fe
  139. >>> imgs = fe.Images(folder_name)
  140. >>> img = imgs.item(1)
  141. >>> feature = img.get_features(['label', 'area','perimeter', 'centroid'])
  142. """
  143. df = pd.DataFrame()
  144. try:
  145. #self.__regionsprops = self.__get_regionsprop()
  146. n = len(self.__regionsprops)
  147. df['id'] = range(0,n)
  148. for feature_name in features_list:
  149. values = self.prop_values(feature_name)
  150. Utils.insert_values(prefix + feature_name + suffix, df, values)
  151. return Features.Features(df)
  152. except Exception as e:
  153. print("one or more input labels might be wrong:{}".format(e))
  154. return None
  155. def prop_values(self, prop_name):
  156. """
  157. Measure the values of the specified property/measure name (e.g., 'area') for all
  158. elements contained in the object Regions.
  159. :param prop_name: name of the property to measure (e.g, 'area')
  160. :type prop_name: string
  161. :returns: property name values
  162. :rtype: List
  163. :example:
  164. >>> import image_features_extraction as fe
  165. >>> imgs = fe.Images(folder_name)
  166. >>> img = imgs.item(1)
  167. >>> regs = img.Regions()
  168. >>> areas = regs.prop_values('area')
  169. The following properties can be accessed as attributes or keys:
  170. **area** : int
  171. Number of pixels of region.
  172. **bbox** : tuple
  173. Bounding box ``(min_row, min_col, max_row, max_col)``.
  174. Pixels belonging to the bounding box are in the half-open interval
  175. ``[min_row; max_row)`` and ``[min_col; max_col)``.
  176. **bbox_area** : int
  177. Number of pixels of bounding box.
  178. **centroid** : array
  179. Centroid coordinate tuple ``(row, col)``.
  180. **convex_area** : int
  181. Number of pixels of convex hull image.
  182. **convex_image** : (H, J) ndarray
  183. Binary convex hull image which has the same size as bounding box.
  184. **coords** : (N, 2) ndarray
  185. Coordinate list ``(row, col)`` of the region.
  186. **eccentricity** : float
  187. Eccentricity of the ellipse that has the same second-moments as the
  188. region. The eccentricity is the ratio of the focal distance
  189. (distance between focal points) over the major axis length.
  190. The value is in the interval [0, 1).
  191. When it is 0, the ellipse becomes a circle.
  192. **equivalent_diameter** : float
  193. The diameter of a circle with the same area as the region.
  194. **euler_number** : int
  195. Euler characteristic of region. Computed as number of objects (= 1)
  196. subtracted by number of holes (8-connectivity).
  197. **extent** : float
  198. Ratio of pixels in the region to pixels in the total bounding box.
  199. Computed as ``area / (rows * cols)``
  200. **filled_area** : int
  201. Number of pixels of filled region.
  202. **filled_image** : (H, J) ndarray
  203. Binary region image with filled holes which has the same size as
  204. bounding box.
  205. **image** : (H, J) ndarray
  206. Sliced binary region image which has the same size as bounding box.
  207. **inertia_tensor** : (2, 2) ndarray
  208. Inertia tensor of the region for the rotation around its mass.
  209. **inertia_tensor_eigvals** : tuple
  210. The two eigen values of the inertia tensor in decreasing order.
  211. **intensity_image** : ndarray
  212. Image inside region bounding box.
  213. **label** : int
  214. The label in the labeled input image.
  215. **local_centroid** : array
  216. Centroid coordinate tuple ``(row, col)``, relative to region bounding
  217. box.
  218. **major_axis_length** : float
  219. The length of the major axis of the ellipse that has the same
  220. normalized second central moments as the region.
  221. **max_intensity** : float
  222. Value with the greatest intensity in the region.
  223. **mean_intensity** : float
  224. Value with the mean intensity in the region.
  225. **min_intensity** : float
  226. Value with the least intensity in the region.
  227. **minor_axis_length** : float
  228. The length of the minor axis of the ellipse that has the same
  229. normalized second central moments as the region.
  230. **moments** : (3, 3) ndarray
  231. Spatial moments up to 3rd order::
  232. m_ji = sum{ array(x, y) * x^j * y^i }
  233. where the sum is over the `x`, `y` coordinates of the region.
  234. **moments_central** : (3, 3) ndarray
  235. Central moments (translation invariant) up to 3rd order::
  236. mu_ji = sum{ array(x, y) * (x - x_c)^j * (y - y_c)^i }
  237. where the sum is over the `x`, `y` coordinates of the region,
  238. and `x_c` and `y_c` are the coordinates of the region's centroid.
  239. **moments_hu** : tuple
  240. Hu moments (translation, scale and rotation invariant).
  241. **moments_normalized** : (3, 3) ndarray
  242. Normalized moments (translation and scale invariant) up to 3rd order::
  243. nu_ji = mu_ji / m_00^[(i+j)/2 + 1]
  244. where `m_00` is the zeroth spatial moment.
  245. **orientation** : float
  246. Angle between the X-axis and the major axis of the ellipse that has
  247. the same second-moments as the region. Ranging from `-pi/2` to
  248. `pi/2` in counter-clockwise direction.
  249. **perimeter** : float
  250. Perimeter of object which approximates the contour as a line
  251. through the centers of border pixels using a 4-connectivity.
  252. **solidity** : float
  253. Ratio of pixels in the region to pixels of the convex hull image.
  254. **weighted_centroid** : array
  255. Centroid coordinate tuple ``(row, col)`` weighted with intensity
  256. image.
  257. **weighted_local_centroid** : array
  258. Centroid coordinate tuple ``(row, col)``, relative to region bounding
  259. box, weighted with intensity image.
  260. **weighted_moments** : (3, 3) ndarray
  261. Spatial moments of intensity image up to 3rd order::
  262. wm_ji = sum{ array(x, y) * x^j * y^i }
  263. where the sum is over the `x`, `y` coordinates of the region.
  264. **weighted_moments_central** : (3, 3) ndarray
  265. Central moments (translation invariant) of intensity image up to
  266. 3rd order::
  267. wmu_ji = sum{ array(x, y) * (x - x_c)^j * (y - y_c)^i }
  268. where the sum is over the `x`, `y` coordinates of the region,
  269. and `x_c` and `y_c` are the coordinates of the region's weighted
  270. centroid.
  271. **weighted_moments_hu** : tuple
  272. Hu moments (translation, scale and rotation invariant) of intensity
  273. image.
  274. **weighted_moments_normalized** : (3, 3) ndarray
  275. Normalized moments (translation and scale invariant) of intensity
  276. image up to 3rd order::
  277. wnu_ji = wmu_ji / wm_00^[(i+j)/2 + 1]
  278. where ``wm_00`` is the zeroth spatial moment (intensity-weighted area).
  279. .. [1] http://scikit-image.org/docs/dev/api/skimage.measure.html#skimage.measure.regionprops
  280. """
  281. try:
  282. vals = []
  283. for i in self.__regionsprops:
  284. vals.append(getattr(i, prop_name))
  285. return vals
  286. except Exception as e:
  287. print(e.args)
  288. return None