You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

metrics.py 10 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. import numpy as np
  2. import cv2
  3. class Evaluator(object):
  4. def __init__(self, num_class):
  5. self.num_class = num_class
  6. self.confusion_matrix = np.zeros((self.num_class,)*2) # shape:(num_class, num_class)
  7. self.curr_confusion_matrix = np.zeros((self.num_class,)*2)
  8. self.future_confusion_matrix = np.zeros((self.num_class,)*2)
  9. def Pixel_Accuracy(self):
  10. Acc = np.diag(self.confusion_matrix).sum() / self.confusion_matrix.sum()
  11. return Acc
  12. def Pixel_Accuracy_Class_Curb(self):
  13. Acc = np.diag(self.confusion_matrix) / self.confusion_matrix.sum(axis=1)
  14. print('-----------Acc of each classes-----------')
  15. print("road : %.6f" % (Acc[0] * 100.0), "%\t")
  16. print("sidewalk : %.6f" % (Acc[1] * 100.0), "%\t")
  17. Acc = np.nanmean(Acc[:2])
  18. return Acc
  19. def Pixel_Accuracy_Class(self):
  20. Acc = np.diag(self.confusion_matrix) / self.confusion_matrix.sum(axis=1)
  21. print('-----------Acc of each classes-----------')
  22. print("road : %.6f" % (Acc[0] * 100.0), "%\t")
  23. print("sidewalk : %.6f" % (Acc[1] * 100.0), "%\t")
  24. print("building : %.6f" % (Acc[2] * 100.0), "%\t")
  25. print("wall : %.6f" % (Acc[3] * 100.0), "%\t")
  26. print("fence : %.6f" % (Acc[4] * 100.0), "%\t")
  27. print("pole : %.6f" % (Acc[5] * 100.0), "%\t")
  28. print("traffic light: %.6f" % (Acc[6] * 100.0), "%\t")
  29. print("traffic sign : %.6f" % (Acc[7] * 100.0), "%\t")
  30. print("vegetation : %.6f" % (Acc[8] * 100.0), "%\t")
  31. print("terrain : %.6f" % (Acc[9] * 100.0), "%\t")
  32. print("sky : %.6f" % (Acc[10] * 100.0), "%\t")
  33. print("person : %.6f" % (Acc[11] * 100.0), "%\t")
  34. print("rider : %.6f" % (Acc[12] * 100.0), "%\t")
  35. print("car : %.6f" % (Acc[13] * 100.0), "%\t")
  36. print("truck : %.6f" % (Acc[14] * 100.0), "%\t")
  37. print("bus : %.6f" % (Acc[15] * 100.0), "%\t")
  38. print("train : %.6f" % (Acc[16] * 100.0), "%\t")
  39. print("motorcycle : %.6f" % (Acc[17] * 100.0), "%\t")
  40. print("bicycle : %.6f" % (Acc[18] * 100.0), "%\t")
  41. print("dynamic : %.6f" % (Acc[19] * 100.0), "%\t")
  42. print("stair : %.6f" % (Acc[20] * 100.0), "%\t")
  43. if self.num_class == 20:
  44. print("small obstacles: %.6f" % (Acc[19] * 100.0), "%\t")
  45. Acc = np.nanmean(Acc)
  46. return Acc
  47. def Mean_Intersection_over_Union(self):
  48. # print(np.shape(self.confusion_matrix))
  49. MIoU = np.diag(self.confusion_matrix) / (
  50. np.sum(self.confusion_matrix, axis=1) + np.sum(self.confusion_matrix, axis=0) -
  51. np.diag(self.confusion_matrix))
  52. # print MIoU of each class
  53. print('-----------IoU of each classes-----------')
  54. print("road : %.6f" % (MIoU[0] * 100.0), "%\t")
  55. print("sidewalk : %.6f" % (MIoU[1] * 100.0), "%\t")
  56. print("building : %.6f" % (MIoU[2] * 100.0), "%\t")
  57. print("wall : %.6f" % (MIoU[3] * 100.0), "%\t")
  58. print("fence : %.6f" % (MIoU[4] * 100.0), "%\t")
  59. print("pole : %.6f" % (MIoU[5] * 100.0), "%\t")
  60. print("traffic light: %.6f" % (MIoU[6] * 100.0), "%\t")
  61. print("traffic sign : %.6f" % (MIoU[7] * 100.0), "%\t")
  62. print("vegetation : %.6f" % (MIoU[8] * 100.0), "%\t")
  63. print("terrain : %.6f" % (MIoU[9] * 100.0), "%\t")
  64. print("sky : %.6f" % (MIoU[10] * 100.0), "%\t")
  65. print("person : %.6f" % (MIoU[11] * 100.0), "%\t")
  66. print("rider : %.6f" % (MIoU[12] * 100.0), "%\t")
  67. print("car : %.6f" % (MIoU[13] * 100.0), "%\t")
  68. print("truck : %.6f" % (MIoU[14] * 100.0), "%\t")
  69. print("bus : %.6f" % (MIoU[15] * 100.0), "%\t")
  70. print("train : %.6f" % (MIoU[16] * 100.0), "%\t")
  71. print("motorcycle : %.6f" % (MIoU[17] * 100.0), "%\t")
  72. print("bicycle : %.6f" % (MIoU[18] * 100.0), "%\t")
  73. print("stair : %.6f" % (MIoU[19] * 100.0), "%\t")
  74. print("curb : %.6f" % (MIoU[20] * 100.0), "%\t")
  75. print("ramp : %.6f" % (MIoU[21] * 100.0), "%\t")
  76. if self.num_class == 20:
  77. print("small obstacles: %.6f" % (MIoU[19] * 100.0), "%\t")
  78. MIoU = np.nanmean(MIoU)
  79. return MIoU
  80. def Mean_Intersection_over_Union_Curb(self):
  81. MIoU = np.diag(self.confusion_matrix) / (
  82. np.sum(self.confusion_matrix, axis=1) + np.sum(self.confusion_matrix, axis=0) -
  83. np.diag(self.confusion_matrix))
  84. # print MIoU of each class
  85. print('-----------IoU of each classes-----------')
  86. print("road : %.6f" % (MIoU[0] * 100.0), "%\t")
  87. print("sidewalk : %.6f" % (MIoU[1] * 100.0), "%\t")
  88. print("stair : %.6f" % (MIoU[19] * 100.0), "%\t")
  89. if self.num_class == 20:
  90. print("small obstacles: %.6f" % (MIoU[19] * 100.0), "%\t")
  91. MIoU = np.nanmean(MIoU[[0, 1, 19]])
  92. return MIoU
  93. def Frequency_Weighted_Intersection_over_Union(self):
  94. freq = np.sum(self.confusion_matrix, axis=1) / np.sum(self.confusion_matrix)
  95. iu = np.diag(self.confusion_matrix) / (
  96. np.sum(self.confusion_matrix, axis=1) + np.sum(self.confusion_matrix, axis=0) -
  97. np.diag(self.confusion_matrix))
  98. FWIoU = (freq[freq > 0] * iu[freq > 0]).sum()
  99. return FWIoU
  100. def Frequency_Weighted_Intersection_over_Union_Curb(self):
  101. freq = np.sum(self.confusion_matrix, axis=1) / np.sum(self.confusion_matrix)
  102. iu = np.diag(self.confusion_matrix) / (
  103. np.sum(self.confusion_matrix, axis=1) + np.sum(self.confusion_matrix, axis=0) -
  104. np.diag(self.confusion_matrix))
  105. # FWIoU = (freq[freq > 0] * iu[freq > 0]).sum()
  106. CFWIoU = freq[freq > 0] * iu[freq > 0]
  107. print('-----------FWIoU of each classes-----------')
  108. print("road : %.6f" % (CFWIoU[0] * 100.0), "%\t")
  109. print("sidewalk : %.6f" % (CFWIoU[1] * 100.0), "%\t")
  110. return np.nanmean(CFWIoU[:2])
  111. def Current_Intersection_over_Union(self):
  112. MIoU = np.diag(self.curr_confusion_matrix) / (
  113. np.sum(self.curr_confusion_matrix, axis=1) + np.sum(self.curr_confusion_matrix, axis=0) -
  114. np.diag(self.curr_confusion_matrix))
  115. MIoU = np.nanmean(MIoU[[0, 1, 19]])
  116. return MIoU
  117. def Future_Intersection_over_Union(self):
  118. MIoU = np.diag(self.future_confusion_matrix) / (
  119. np.sum(self.future_confusion_matrix, axis=1) + np.sum(self.future_confusion_matrix, axis=0) -
  120. np.diag(self.future_confusion_matrix))
  121. MIoU = np.nanmean(MIoU[[0, 1, 19]])
  122. return MIoU
  123. def _generate_current_matrix(self, gt_image, pre_image):
  124. _, input_height, input_width = np.shape(pre_image)
  125. closest = np.array([
  126. [0, int(input_height)],
  127. [int(input_width),
  128. int(input_height)],
  129. [int(0.882 * input_width + .5),
  130. int(.8 * input_height + .5)],
  131. [int(0.118 * input_width + .5),
  132. int(.8 * input_height + .5)]
  133. ])
  134. mask_current = np.zeros((input_height, input_width), dtype=np.int8)
  135. mask_current = cv2.fillPoly(mask_current, [closest], 1)
  136. mask = (gt_image >= 0) & (gt_image < self.num_class) & (mask_current == 1)
  137. label = self.num_class * gt_image[mask].astype('int') + pre_image[mask]
  138. count = np.bincount(label, minlength=self.num_class**2)
  139. confusion_matrix = count.reshape(self.num_class, self.num_class)
  140. return confusion_matrix
  141. def _generate_future_matrix(self, gt_image, pre_image):
  142. _, input_height, input_width = np.shape(pre_image)
  143. future = np.array([
  144. [int(0.118 * input_width + .5),
  145. int(.8 * input_height + .5)],
  146. [int(0.882 * input_width + .5),
  147. int(.8 * input_height + .5)],
  148. [int(.765 * input_width + .5),
  149. int(.66 * input_height + .5)],
  150. [int(.235 * input_width + .5),
  151. int(.66 * input_height + .5)]
  152. ])
  153. mask_future = np.zeros((input_height, input_width), dtype=np.int8)
  154. mask_future = cv2.fillPoly(mask_future, [future], 1)
  155. mask = (gt_image >= 0) & (gt_image < self.num_class) & (mask_future == 1)
  156. label = self.num_class * gt_image[mask].astype('int') + pre_image[mask]
  157. count = np.bincount(label, minlength=self.num_class**2)
  158. confusion_matrix = count.reshape(self.num_class, self.num_class)
  159. return confusion_matrix
  160. def _generate_matrix(self, gt_image, pre_image):
  161. mask = (gt_image >= 0) & (gt_image < self.num_class)
  162. label = self.num_class * gt_image[mask].astype('int') + pre_image[mask]
  163. count = np.bincount(label, minlength=self.num_class**2)
  164. confusion_matrix = count.reshape(self.num_class, self.num_class)
  165. return confusion_matrix
  166. # def add_trape_batch(self, gt_image, pre_image):
  167. # assert gt_image.shape == pre_image.shape
  168. # self.trape_confusion_matrix += self._generate_trape_matrix(gt_image, pre_image)
  169. def add_batch(self, gt_image, pre_image):
  170. assert gt_image.shape == pre_image.shape
  171. self.confusion_matrix += self._generate_matrix(gt_image, pre_image)
  172. self.curr_confusion_matrix += self._generate_current_matrix(gt_image, pre_image)
  173. self.future_confusion_matrix += self._generate_future_matrix(gt_image, pre_image)
  174. def reset(self):
  175. self.confusion_matrix = np.zeros((self.num_class,) * 2)
  176. self.curr_confusion_matrix = np.zeros((self.num_class,)*2)
  177. self.future_confusion_matrix = np.zeros((self.num_class,)*2)