choice_m_row_column.py 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. # @Author : liu fan
  2. import numpy as np
  3. import tensorflow as tf
  4. from segment.sheet_resolve.lib.ssd_model.utils import label_map_util, ops as utils_ops
  5. from segment.sheet_resolve.tools import tf_settings
  6. from segment.sheet_resolve.tools.tf_sess import SsdSess
  7. from PIL import Image
  8. tf_sess_dict = {
  9. 'choice_ssd': SsdSess('choice_ssd'),
  10. }
  11. choice_ssd_sess = tf_sess_dict['choice_ssd']
  12. sess = choice_ssd_sess.sess
  13. detection_graph = choice_ssd_sess.graph
  14. def load_image_into_numpy_array(image):
  15. # print(image)
  16. image = image.convert('RGB')
  17. (im_width, im_height) = image.size
  18. return np.array(image.getdata()).reshape((im_height, im_width, 3)).astype(np.uint8)
  19. def run_inference_for_single_image(image):
  20. ops = detection_graph.get_operations()
  21. all_tensor_names = {output.name for op in ops for output in op.outputs}
  22. tensor_dict = {}
  23. for key in [
  24. 'num_detections', 'detection_boxes', 'detection_scores',
  25. 'detection_classes', 'detection_masks'
  26. ]:
  27. tensor_name = key + ':0'
  28. if tensor_name in all_tensor_names:
  29. tensor_dict[key] = detection_graph.get_tensor_by_name(
  30. tensor_name)
  31. if 'detection_masks' in tensor_dict:
  32. # The following processing is only for single image
  33. detection_boxes = tf.squeeze(tensor_dict['detection_boxes'], [0])
  34. detection_masks = tf.squeeze(tensor_dict['detection_masks'], [0])
  35. # Reframe is required to translate mask from box coordinates to image coordinates and fit the image size.
  36. real_num_detection = tf.cast(tensor_dict['num_detections'][0], tf.int32)
  37. detection_boxes = tf.slice(detection_boxes, [0, 0], [real_num_detection, -1])
  38. detection_masks = tf.slice(detection_masks, [0, 0, 0], [real_num_detection, -1, -1])
  39. detection_masks_reframed = utils_ops.reframe_box_masks_to_image_masks(
  40. detection_masks, detection_boxes, image.shape[0], image.shape[1])
  41. detection_masks_reframed = tf.cast(
  42. tf.greater(detection_masks_reframed, 0.5), tf.uint8)
  43. # Follow the convention by adding back the batch dimension
  44. tensor_dict['detection_masks'] = tf.expand_dims(
  45. detection_masks_reframed, 0)
  46. image_tensor = detection_graph.get_tensor_by_name('image_tensor:0')
  47. # Run inference
  48. # start = time.time()
  49. output_dict = sess.run(tensor_dict,
  50. feed_dict={image_tensor: np.expand_dims(image, 0)})
  51. # print(time.time()-start)
  52. # all outputs are float32 numpy arrays, so convert types as appropriate
  53. output_dict['num_detections'] = int(output_dict['num_detections'][0])
  54. output_dict['detection_classes'] = output_dict[
  55. 'detection_classes'][0].astype(np.uint8)
  56. output_dict['detection_boxes'] = output_dict['detection_boxes'][0]
  57. output_dict['detection_scores'] = output_dict['detection_scores'][0]
  58. if 'detection_masks' in output_dict:
  59. output_dict['detection_masks'] = output_dict['detection_masks'][0]
  60. return output_dict
  61. def image_detect(image_np, category, score_threshold):
  62. image_np = load_image_into_numpy_array(image_np)
  63. detections = []
  64. w, h = image_np.shape[1], image_np.shape[0]
  65. with tf.device("/device:GPU:{}".format(0)):
  66. output_dict = run_inference_for_single_image(image_np)
  67. boxes = output_dict['detection_boxes']
  68. scores = output_dict['detection_scores']
  69. labels = output_dict['detection_classes']
  70. indices = np.where(scores > score_threshold)
  71. image_scores = scores[indices]
  72. image_boxes = boxes[indices]
  73. image_labels = labels[indices]
  74. image_detections = np.concatenate(
  75. [image_boxes, np.expand_dims(image_scores, axis=1), np.expand_dims(image_labels, axis=1)], axis=1)
  76. for detection in image_detections:
  77. y0 = int(detection[0] * h)
  78. x0 = int(detection[1] * w)
  79. y1 = int(detection[2] * h)
  80. x1 = int(detection[3] * w)
  81. label_index = int(detection[5])
  82. label_name = category[label_index]['name']
  83. detections.append((x0, y0, x1, y1, label_index, detection[4], label_name))
  84. return detections
  85. def get_choice_m_row_and_col(left, top, image):
  86. im_resize = 300
  87. ''' choice_m resize to 300*300'''
  88. image_src = Image.fromarray(image)
  89. if image_src.mode == 'RGB':
  90. image_src = image_src.convert("L")
  91. w, h = image_src.size
  92. if h > w:
  93. image_src = image_src.resize((int(im_resize / h * w), im_resize))
  94. else:
  95. image_src = image_src.resize((im_resize, int(im_resize / w * h)))
  96. w_, h_ = image_src.size
  97. image_300 = Image.new(image_src.mode, (im_resize, im_resize), (255))
  98. image_300.paste(image_src, [0, 0, w_, h_])
  99. category_index = label_map_util.create_category_index_from_labelmap(tf_settings.choice_m_ssd_label,
  100. use_display_name=True)
  101. detections = image_detect(image_300, category_index, 0.5)
  102. if len(detections) > 1:
  103. box_xmin = []
  104. box_ymin = []
  105. box_xmax = []
  106. box_ymax = []
  107. x_distance_all = []
  108. y_distance_all = []
  109. x_width_all = []
  110. y_height_all = []
  111. all_small_coordinate = []
  112. ssd_column = 1
  113. ssd_row = 1
  114. count_x = 0
  115. count_y = 0
  116. for index, box in enumerate(detections):
  117. if box[-1] != 'T' and box[2] <= w_ and box[3] <= h_:
  118. box0 = round(box[0] * (w / w_)) # Map to the original image
  119. box1 = round(box[1] * (h / h_))
  120. box2 = round(box[2] * (w / w_))
  121. box3 = round(box[3] * (h / h_))
  122. box_xmin.append(box0)
  123. box_ymin.append(box1)
  124. box_xmax.append(box2)
  125. box_ymax.append(box3)
  126. small_coordinate = {'xmin': box0 + left,
  127. 'ymin': box1 + top,
  128. 'xmax': box2 + left,
  129. 'ymax': box3 + top}
  130. all_small_coordinate.append(small_coordinate)
  131. x_width = box2 - box0
  132. y_height = box3 - box1
  133. x_width_all.append(x_width)
  134. y_height_all.append(y_height)
  135. sorted_xmin = sorted(box_xmin)
  136. sorted_ymin = sorted(box_ymin)
  137. sorted_xmax = sorted(box_xmax)
  138. sorted_ymax = sorted(box_ymax)
  139. x_width_all_sorted = sorted(x_width_all, reverse=True)
  140. y_height_all_sorted = sorted(y_height_all, reverse=True)
  141. len_x = len(x_width_all)
  142. len_y = len(y_height_all)
  143. x_width_median = np.median(x_width_all_sorted)
  144. y_height_median = np.median(y_height_all_sorted)
  145. for i in range(len(sorted_xmin) - 1):
  146. x_distance = abs(sorted_xmin[i + 1] - sorted_xmin[i])
  147. y_distance = abs(sorted_ymin[i + 1] - sorted_ymin[i])
  148. if x_distance > 20:
  149. ssd_column = ssd_column + 1
  150. x_distance_all.append(x_distance)
  151. if x_distance > 2 * x_width_median + 4:
  152. count_x = count_x + 1
  153. if y_distance > 10:
  154. ssd_row = ssd_row + 1
  155. y_distance_all.append(y_distance)
  156. if y_distance > 2 * y_height_median + 3:
  157. count_y = count_y + 1
  158. if x_width_all_sorted[i] - x_width_median > 40:
  159. ssd_column = ssd_column - 1
  160. elif x_width_median - x_width_all_sorted[i] > 40:
  161. ssd_column = ssd_column - 1
  162. if y_height_all_sorted[i] - y_height_median > 20:
  163. ssd_row = ssd_row - 1
  164. elif y_height_median - y_height_all_sorted[i] > 20:
  165. ssd_row = ssd_row - 1
  166. if count_x < len(x_distance_all) / 2 + 1:
  167. ssd_column = ssd_column + count_x
  168. elif count_y < len(y_distance_all) / 2 + 1:
  169. ssd_row = ssd_row + count_y
  170. average_height = int(np.mean(y_height_all))
  171. average_width = int(np.mean(x_width_all))
  172. # average_height = format(np.mean(y_height_all), '.2f')
  173. # average_width = format(np.mean(x_width_all), '.2f')
  174. # average_height = int(np.mean(y_distance_all))
  175. # average_width = int(np.mean(x_distance_all))
  176. location_ssd = {'xmin': sorted_xmin[0] + left,
  177. 'ymin': sorted_ymin[0] + top,
  178. 'xmax': sorted_xmax[-1] + left,
  179. 'ymax': sorted_ymax[-1] + top}
  180. choice_m_ssd = {'bounding_box': location_ssd,
  181. "single_height": average_height,
  182. "single_width": average_width,
  183. "rows": ssd_row,
  184. "cols": ssd_column,
  185. 'class_name': 'choice_m',
  186. 'all_small_coordinate': all_small_coordinate
  187. }
  188. else:
  189. choice_m_ssd = {}
  190. return choice_m_ssd