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

257 lines
8.8 KiB

6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
  1. from modules import utils
  2. from flask import Flask, request, Response
  3. from flask_restful import Resource, Api
  4. from PIL import Image
  5. import cv2
  6. import base64
  7. import json
  8. import sys
  9. import os
  10. import io
  11. import itertools
  12. import pickle
  13. import copy
  14. from urllib.parse import urlencode
  15. from urllib.request import Request, urlopen
  16. import ssl
  17. from object_detection.utils import label_map_util
  18. import face_recognition
  19. VEHICLE_CLASSES = [3, 6, 8]
  20. MIN_AREA_RATIO = 0.9
  21. import numpy as np
  22. MIN_SCORE_THRESH = 0.6
  23. if sys.platform == "win32":
  24. sys.path.insert(0, r'C:\Users\Tednokent01\Downloads\MyCity\traffic_analyzer')
  25. PATH_TO_LABELS = os.path.join('object_detection/data', 'mscoco_label_map.pbtxt')
  26. category_index = label_map_util.create_category_index_from_labelmap(PATH_TO_LABELS, use_display_name=True)
  27. app = Flask(__name__)
  28. api = Api(app)
  29. db_path = os.path.join(app.root_path, 'databases', 'crashes.json')
  30. with open(db_path, 'r') as f:
  31. crashes = json.load(f)
  32. users_path = os.path.join(app.root_path, 'databases', 'users.json')
  33. with open(users_path, 'r') as f:
  34. users = json.load(f)
  35. def load_image_into_numpy_array(image):
  36. (im_width, im_height) = image.size
  37. return np.array(image.getdata()).reshape(
  38. (im_height, im_width, 3)).astype(np.uint8)
  39. context = ssl._create_unverified_context()
  40. def find_name(image):
  41. known_faces = []
  42. known_face_names = []
  43. for v in users.values():
  44. known_faces.append(np.array(v['face_encoding']))
  45. known_face_names.append(v['realname'])
  46. face_encoding = face_recognition.face_encodings(image)[0]
  47. results = face_recognition.compare_faces(known_faces, face_encoding)
  48. name = "Unknown"
  49. face_distances = face_recognition.face_distance(known_faces, face_encoding)
  50. best_match_index = np.argmin(face_distances)
  51. if results[best_match_index]:
  52. name = known_face_names[best_match_index]
  53. return name
  54. def process_img(img_base64):
  55. if 1:
  56. url = 'https://10.10.26.161:5000/ai' # Set destination URL here
  57. post_fields = {'img': img_base64,"type":"coco"} # Set POST fields here
  58. request = Request(url, urlencode(post_fields).encode())
  59. data = urlopen(request, context=context).read().decode("ascii")
  60. output_dict = json.loads(json.loads(data))
  61. image_np = load_image_into_numpy_array(Image.open(io.BytesIO(base64.b64decode(img_base64))))
  62. else:
  63. with open('image_1_data.pkl', 'rb') as f:
  64. output_dict = pickle.load(f)
  65. image_np = cv2.imread("image_1.jpg")
  66. output_dict_processed = {"detection_classes":[], "detection_scores":[], "detection_boxes":[]}
  67. im_height, im_width, _ = image_np.shape
  68. cars_involved = 0
  69. injured_people = 0
  70. prev_cars = []
  71. boxes = []
  72. spam_boxes = []
  73. for index, i in enumerate(output_dict['detection_classes']):
  74. score = output_dict['detection_scores'][index]
  75. if score > MIN_SCORE_THRESH:
  76. if i in VEHICLE_CLASSES:
  77. box = output_dict['detection_boxes'][index]
  78. boxes.append(Box((box[1] * im_width, box[3] * im_width,
  79. box[0] * im_height, box[2] * im_height),
  80. i,index))
  81. box_combinations = itertools.combinations(boxes,r=2)
  82. for combination in box_combinations:
  83. big = combination[0].get_bigger(combination[1])
  84. if big and not big in spam_boxes:
  85. spam_boxes.append(big)
  86. for spam in spam_boxes:
  87. boxes.remove(spam)
  88. for box in boxes:
  89. output_dict_processed["detection_classes"].append(output_dict["detection_classes"][box.index])
  90. output_dict_processed["detection_scores"].append(output_dict["detection_scores"][box.index])
  91. output_dict_processed["detection_boxes"].append(output_dict["detection_boxes"][box.index])
  92. people = {}
  93. for index, i in enumerate(output_dict['detection_classes']):
  94. score = output_dict['detection_scores'][index]
  95. if score > MIN_SCORE_THRESH:
  96. if i in VEHICLE_CLASSES:
  97. box = output_dict['detection_boxes'][index]
  98. (left, right, top, bottom) = (box[1] * im_width, box[3] * im_width,
  99. box[0] * im_height, box[2] * im_height)
  100. avg_x = left+right/2
  101. avg_y = top+bottom/2
  102. same = False
  103. for prev_x, prev_y in prev_cars:
  104. if abs(prev_x-avg_x) < 130 and abs(prev_y-avg_y) < 130:
  105. same = True
  106. break
  107. if not same:
  108. cars_involved += 1
  109. prev_cars.append((avg_x, avg_y))
  110. elif i == 1:
  111. box = output_dict['detection_boxes'][index]
  112. (left, right, top, bottom) = (box[1] * im_width, box[3] * im_width,
  113. box[0] * im_height, box[2] * im_height)
  114. person = image_np[top:bottom,left:right]
  115. if right-left > bottom-top:
  116. face_locs = face_recognition.face_locations(person)
  117. name = find_name(person)
  118. people[index] = [0, face_locs, name]
  119. else:
  120. face_locs = face_recognition.face_locations(person)
  121. name = find_name(person)
  122. people[index] = [1, face_locs, name]
  123. _, buffer = cv2.imencode('.jpg', image_np)
  124. # image_process = image_np[:]
  125. # vis_util.visualize_boxes_and_labels_on_image_array(
  126. # image_process,
  127. # output_dict_processed["detection_boxes"],
  128. # output_dict_processed["detection_classes"],
  129. # output_dict_processed["detection_scores"],
  130. # category_index,
  131. # min_score_thresh=MIN_SCORE_THRESH,
  132. # use_normalized_coordinates=True,
  133. # line_thickness=8)
  134. # cv2.imshow("a",image_process)
  135. # cv2.waitKey(0)
  136. for i in range(len(output_dict_processed["detection_classes"])):
  137. output_dict_processed["detection_classes"][i] = category_index[output_dict_processed["detection_classes"][i]]["name"]
  138. return base64.b64encode(buffer).decode('ascii'), cars_involved, injured_people,output_dict_processed,people
  139. class Crash(Resource):
  140. def post(self):
  141. message = request.form['message']
  142. base64_img = request.form['img']
  143. id = request.form['id']
  144. lat, long = request.form['lat'], request.form['long']
  145. image, car_count, injured,out,people = process_img(base64_img)
  146. print(people)
  147. priority = car_count + injured
  148. if priority > 10:
  149. priority = 10
  150. crash = {
  151. 'img': image,
  152. 'message': message,
  153. 'priority': priority,
  154. 'stats': {
  155. 'cars': car_count,
  156. 'injured': injured
  157. },
  158. 'location': {
  159. 'latitude': lat,
  160. 'longitude': long
  161. },
  162. "output_dict": out
  163. }
  164. if id in crashes:
  165. crashes[id].append(crash)
  166. else:
  167. crashes[id] = [crash]
  168. with open(db_path, 'w') as f:
  169. json.dump(crashes, f, indent=4)
  170. return crash
  171. class Crashes(Resource):
  172. def post(self):
  173. process_dict = copy.deepcopy(crashes)
  174. return_dict = {}
  175. for id in process_dict:
  176. for i in range(len(process_dict[id])):
  177. del process_dict[id][i]["img"]
  178. for id in process_dict:
  179. for i in range(len(process_dict[id])):
  180. location = process_dict[id][i]['location']
  181. lat, lng = float(request.form['lat']), float(request.form['lng'])
  182. if abs(float(location['latitude']) - lat) < 0.3 and abs(float(location['longitude']) - lng) < 0.3:
  183. if id in return_dict:
  184. return_dict[id].append(process_dict[id][i])
  185. else:
  186. return_dict[id] = [process_dict[id][i]]
  187. return return_dict
  188. class Box:
  189. def __init__(self,coords, type,index):
  190. self.x1 = coords[0]
  191. self.y1 = coords[2]
  192. self.x2 = coords[1]
  193. self.y2 = coords[3]
  194. self.area = (self.x2-self.x1) * (self.y2-self.y1)
  195. self.type = type
  196. self.index = index
  197. def get_bigger(self,box):
  198. if box.type != self.type:
  199. return None
  200. left = max(box.x1, self.x1)
  201. right = min(box.x2, self.x2)
  202. bottom = max(box.y2, self.y2)
  203. top = min(box.y1, self.y1)
  204. if not left < right and bottom < top:
  205. return None
  206. area_temp = abs((right-left)*(top-bottom))
  207. if abs((right-left)*(top-bottom))/((box.area * (box.area < self.area)) + (self.area * (box.area > self.area))) < MIN_AREA_RATIO:
  208. return None
  209. if box.area > self.area:
  210. return box
  211. else:
  212. return self