交通事故检测代码
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.

419 lines
23KB

  1. # 设定开关,将最小外接矩形中心点间的距离作为vehicle之间的距离
  2. import numpy as np
  3. import math, cv2, time
  4. def get_ms(time2, time1):
  5. return (time2 - time1) * 1000.0
  6. def two_points_distance(x1, y1, x2, y2):
  7. distance = math.sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2)
  8. return distance
  9. # 保存正常vehicle和非正常vehicle的信息(当contours顶点数小于6时,无法拟合最小外接矩形,定义为非正常vehicle)
  10. def saveVehicle1(traffic_dict, contours, normVehicleBD, normVehicle, count, i, unnormVehicle, normVehicleCOOR):
  11. if len(contours) >= 6:
  12. normVehicleBD.append(contours)
  13. normVehicle.append(traffic_dict['det'][count])
  14. rect = cv2.minAreaRect(contours)
  15. normVehicleCOOR.append(rect[0])
  16. else:
  17. traffic_dict['det'][int(i / 2)] = traffic_dict['det'][int(i / 2)] + [0, 0.3, 999, -1, 3]
  18. unnormVehicle.append(traffic_dict['det'][int(i / 2)])
  19. return normVehicleBD, normVehicle, unnormVehicle, normVehicleCOOR
  20. # saveVehicle2和saveVehicle1有区别
  21. def saveVehicle2(traffic_dict, contours, normVehicleBD, normVehicle, count, i, unnormVehicle, normVehicleCOOR, centerCOOR):
  22. if len(contours) >= 6:
  23. normVehicleBD.append(contours)
  24. normVehicle.append(traffic_dict['det'][count])
  25. normVehicleCOOR.append(centerCOOR)
  26. else:
  27. traffic_dict['det'][int(i / 2)] = traffic_dict['det'][int(i / 2)] + [0, 0.3, 999, -1, 3]
  28. unnormVehicle.append(traffic_dict['det'][int(i / 2)])
  29. return normVehicleBD, normVehicle, unnormVehicle, normVehicleCOOR
  30. # 对于不在道路上的vehicle,将输出信息补全
  31. def supplementInformation(traffic_dict, i, roundness, y_min, y_max, imgVehicle, rect):
  32. score = -1
  33. traffic_dict['det'][i] = traffic_dict['det'][i] + [0, roundness, 999, [-1, -1, -1], 666]
  34. if y_min > 0 and y_max < imgVehicle.shape[0] and roundness > traffic_dict['roundness']: # 过滤掉上下方被speedRoad的边界截断的vehicle
  35. score = (min(rect[1]) - max(rect[1]) * traffic_dict['roundness']) / (max(rect[1]) * (1 - traffic_dict['roundness']))
  36. return score
  37. # 判断交通事故类型
  38. def judgeAccidentType(traffic_dict, b):
  39. if max(traffic_dict['det'][b][9]) == traffic_dict['det'][b][9][0] and traffic_dict['det'][b][9][0] != -1:
  40. return 0
  41. elif max(traffic_dict['det'][b][9]) == traffic_dict['det'][b][9][1] and traffic_dict['det'][b][9][1] != -1:
  42. return 1
  43. elif max(traffic_dict['det'][b][9]) == traffic_dict['det'][b][9][2] and traffic_dict['det'][b][9][2] != -1:
  44. return 2
  45. else:
  46. return 3
  47. # 计算距离得分
  48. def distanceScore(vehicleWH, index1, index2, smallestDistance, traffic_dict):
  49. d1 = (min(vehicleWH[index1]) + min(vehicleWH[index2])) / 2
  50. d2 = min(min(vehicleWH[index1]), min(vehicleWH[index2])) + max(min(vehicleWH[index1]), min(vehicleWH[index2])) / 2
  51. if smallestDistance == d1:
  52. score1 = 1
  53. traffic_dict['det'][index2][9][2] = score1
  54. traffic_dict['det'][index2][10] = judgeAccidentType(traffic_dict, index2)
  55. elif smallestDistance < d2:
  56. score1 = 1 - (smallestDistance - d1) / (d2 - d1)
  57. if 0 < score1 < 1:
  58. traffic_dict['det'][index2][9][2] = score1
  59. traffic_dict['det'][index2][10] = judgeAccidentType(traffic_dict, index2)
  60. else:
  61. traffic_dict['det'][index2][10] = judgeAccidentType(traffic_dict, index2)
  62. else:
  63. traffic_dict['det'][index2][10] = judgeAccidentType(traffic_dict, index2)
  64. return traffic_dict['det']
  65. # 计算两个contours之间的最短距离
  66. def array_distance(arr1, arr2):
  67. '''
  68. 计算两个数组中,每任意两个点之间L2距离
  69. arr1和arr2都必须是numpy数组
  70. 且维度分别是mx2,nx2
  71. 输出数组维度为mxn
  72. '''
  73. m, _ = arr1.shape
  74. n, _ = arr2.shape
  75. arr1_power = np.power(arr1, 2)
  76. arr1_power_sum = arr1_power[:, 0] + arr1_power[:, 1] # 第1区域,x与y的平方和
  77. arr1_power_sum = np.tile(arr1_power_sum, (n, 1)) # 将arr1_power_sum沿着y轴复制n倍,沿着x轴复制1倍,这里用于与arr2进行计算。 n x m 维度
  78. arr1_power_sum = arr1_power_sum.T # 将arr1_power_sum进行转置
  79. arr2_power = np.power(arr2, 2)
  80. arr2_power_sum = arr2_power[:, 0] + arr2_power[:, 1] # 第2区域,x与y的平方和
  81. arr2_power_sum = np.tile(arr2_power_sum, (m, 1)) # 将arr1_power_sum沿着y轴复制m倍,沿着x轴复制1倍,这里用于与arr1进行计算。 m x n 维度
  82. dis = arr1_power_sum + arr2_power_sum - (2 * np.dot(arr1, arr2.T)) # np.dot(arr1, arr2.T)矩阵相乘,得到xy的值。
  83. dis = np.sqrt(dis)
  84. return dis
  85. # 存储所有道路的信息
  86. def storageRoad(contours, allRoadContent, traffic_dict):
  87. speedRoadAngle = 0
  88. for cnt in contours: # 道路
  89. rect = cv2.minAreaRect(cnt)
  90. if rect[1][0] * rect[1][1] > traffic_dict['RoadArea']: # 过滤掉面积小于阈值的speedRoad
  91. if rect[1][0] <= rect[1][1]: # w <= h
  92. if rect[2] >= 0 and rect[2] < 90:
  93. speedRoadAngle = rect[2] + 90
  94. elif rect[2] == 90:
  95. speedRoadAngle = 0
  96. else:
  97. if rect[2] >= 0 and rect[2] <= 90:
  98. speedRoadAngle = rect[2]
  99. allRoadContent.append([cnt, speedRoadAngle, rect[1]])
  100. return allRoadContent
  101. # 存储所有vehicle的信息,方法1
  102. def storageVehicle1(traffic_dict, normVehicleBD, normVehicle, unnormVehicle, normVehicleCOOR, imgVehicle):
  103. count = 0
  104. for i in range(0, len(traffic_dict['vehicleCOOR']), 2):
  105. mask = np.zeros(imgVehicle.shape[:2], dtype="uint8")
  106. x0 = int(traffic_dict['vehicleCOOR'][i][0] * traffic_dict['ZoomFactor']['x'])
  107. y0 = int(traffic_dict['vehicleCOOR'][i][1] * traffic_dict['ZoomFactor']['y'])
  108. x1 = int(traffic_dict['vehicleCOOR'][i + 1][0] * traffic_dict['ZoomFactor']['x'])
  109. y1 = int(traffic_dict['vehicleCOOR'][i + 1][1] * traffic_dict['ZoomFactor']['y'])
  110. cv2.rectangle(mask, (x0, y0), (x1, y1), 255, -1, lineType=cv2.LINE_AA)
  111. imgVehicle_masked = cv2.bitwise_and(imgVehicle, imgVehicle, mask=mask)
  112. img2 = cv2.cvtColor(imgVehicle_masked, cv2.COLOR_BGR2GRAY)
  113. contours2, hierarchy2 = cv2.findContours(img2, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
  114. if len(contours2) != 0:
  115. if len(contours2) > 1: # 这里我通过比较同一检测框内各个contours对应的最小外接矩形的面积,来剔除那些存在干扰的contours,最终只保留一个contours
  116. vehicleArea = [] # 存储vehicle的最小外接矩形的面积
  117. for j in range(len(contours2)):
  118. rect = cv2.minAreaRect(contours2[j])
  119. vehicleArea.append(rect[1][0] * rect[1][1])
  120. maxAreaIndex = vehicleArea.index(max(vehicleArea))
  121. maxAreaContours = contours2[maxAreaIndex]
  122. normVehicleBD, normVehicle, unnormVehicle, normVehicleCOOR = saveVehicle1(traffic_dict,maxAreaContours,normVehicleBD,normVehicle,count,i,unnormVehicle, normVehicleCOOR)
  123. elif len(contours2) == 1:
  124. normVehicleBD, normVehicle, unnormVehicle, normVehicleCOOR = saveVehicle1(traffic_dict,contours2[0],normVehicleBD,normVehicle,count,i,unnormVehicle, normVehicleCOOR)
  125. else:
  126. traffic_dict['det'][int(i / 2)] = traffic_dict['det'][int(i / 2)] + [0, 0.3, 999, -1, 3]
  127. unnormVehicle.append(traffic_dict['det'][int(i / 2)])
  128. count += 1
  129. traffic_dict['det'] = normVehicle
  130. return traffic_dict['det'], normVehicleBD, unnormVehicle, normVehicleCOOR
  131. # 存储所有vehicle的信息,方法2
  132. def storageVehicle2(traffic_dict, normVehicleBD, normVehicle, unnormVehicle, normVehicleCOOR, imgVehicle):
  133. img = cv2.cvtColor(imgVehicle, cv2.COLOR_BGR2GRAY)
  134. count = 0
  135. for i in range(0, len(traffic_dict['vehicleCOOR']), 2):
  136. row1 = int(traffic_dict['vehicleCOOR'][i][1] * traffic_dict['ZoomFactor']['y'])
  137. row2 = int(traffic_dict['vehicleCOOR'][i + 1][1] * traffic_dict['ZoomFactor']['y'])
  138. col1 = int(traffic_dict['vehicleCOOR'][i][0] * traffic_dict['ZoomFactor']['x'])
  139. col2 = int(traffic_dict['vehicleCOOR'][i + 1][0] * traffic_dict['ZoomFactor']['x'])
  140. if row1 >= 2:
  141. row1 = row1 - 2
  142. if row2 <= (traffic_dict['modelSize'][1] - 2):
  143. row2 = row2 + 2
  144. if col1 >= 2:
  145. col1 = col1 - 2
  146. if col2 <= (traffic_dict['modelSize'][0] - 2):
  147. col2 = col2 + 2
  148. centerCOOR = (int((col1 + col2) / 2), int((row1 + row2) / 2))
  149. img1 = img[row1:row2, col1:col2]
  150. up = np.zeros((20, (col2 - col1)), dtype='uint8')
  151. left = np.zeros(((40 + row2 - row1), 20), dtype='uint8')
  152. img1 = np.concatenate((up, img1), axis=0)
  153. img1 = np.concatenate((img1, up), axis=0)
  154. img1 = np.concatenate((left, img1), axis=1)
  155. img2 = np.concatenate((img1, left), axis=1)
  156. contours2, hierarchy = cv2.findContours(img2, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
  157. if len(contours2) != 0:
  158. if len(contours2) > 1:
  159. vehicleArea = [] # 存储vehicle的最小外接矩形的面积
  160. for j in range(len(contours2)):
  161. rect = cv2.minAreaRect(contours2[j])
  162. vehicleArea.append(rect[1][0] * rect[1][1])
  163. maxAreaIndex = vehicleArea.index(max(vehicleArea))
  164. maxAreaContours = contours2[maxAreaIndex]
  165. normVehicleBD, normVehicle, unnormVehicle, normVehicleCOOR = saveVehicle2(traffic_dict,maxAreaContours,normVehicleBD,normVehicle,count,i,unnormVehicle,normVehicleCOOR,centerCOOR)
  166. elif len(contours2) == 1:
  167. normVehicleBD, normVehicle, unnormVehicle, normVehicleCOOR = saveVehicle2(traffic_dict,contours2[0],normVehicleBD,normVehicle,count,i,unnormVehicle,normVehicleCOOR,centerCOOR)
  168. else:
  169. traffic_dict['det'][int(i / 2)] = traffic_dict['det'][int(i / 2)] + [0, 0.3, 999, -1, 3]
  170. unnormVehicle.append(traffic_dict['det'][int(i / 2)])
  171. count += 1
  172. traffic_dict['det'] = normVehicle
  173. return traffic_dict['det'], normVehicleBD, unnormVehicle, normVehicleCOOR
  174. # 计算角度和长宽比得分
  175. def angleRoundness(normVehicleBD, vehicleBox, vehicleWH, allRoadContent, traffic_dict, normVehicleCOOR, imgVehicle):
  176. for i in range(len(normVehicleBD)):
  177. ellipse = cv2.fitEllipse(normVehicleBD[i])
  178. # print("line202", ellipse)
  179. vehicleAngle = 0
  180. if ellipse[2] >= 0 and ellipse[2] < 90:
  181. vehicleAngle = 90 + ellipse[2]
  182. elif ellipse[2] >= 90 and ellipse[2] < 180:
  183. vehicleAngle = ellipse[2] - 90
  184. elif ellipse[2] == 180:
  185. vehicleAngle = 90
  186. rect = cv2.minAreaRect(normVehicleBD[i])
  187. box = cv2.boxPoints(rect).astype(np.int32)
  188. center = normVehicleCOOR[i]
  189. vehicleBox.append(box)
  190. vehicleWH.append(rect[1])
  191. roundness = min(rect[1]) / max(rect[1])
  192. y_min = np.min(box[:, 1])
  193. y_max = np.max(box[:, 1])
  194. if len(allRoadContent) != 0:
  195. for j in range(len(allRoadContent)):
  196. flag = cv2.pointPolygonTest(allRoadContent[j][0], center, False)
  197. if flag >= 0:
  198. roadVehicleAngle = abs(vehicleAngle - allRoadContent[j][1])
  199. traffic_dict['det'][i] = traffic_dict['det'][i] + [roadVehicleAngle, roundness, 999, [-1, -1, -1], 666]
  200. if y_min > 0 and y_max < imgVehicle.shape[0]: # 过滤掉上下方被speedRoad的边界截断的vehicle
  201. if roadVehicleAngle >= traffic_dict['roadVehicleAngle']: # 当道路同水平方向的夹角与车辆同水平方向的夹角的差值在15°和75°之间时,需要将车辆框出来
  202. # print("line225 车辆角度,道路角度", vehicleAngle, allRoadContent[j][1])
  203. if roadVehicleAngle > 90:
  204. score1 = float((180 - roadVehicleAngle) / 90)
  205. else:
  206. score1 = float(roadVehicleAngle / 90)
  207. traffic_dict['det'][i][9][0] = score1
  208. if roundness > traffic_dict['roundness']:
  209. score2 = (min(rect[1]) - max(rect[1]) * traffic_dict['roundness']) / (max(rect[1]) * (1 - traffic_dict['roundness']))
  210. traffic_dict['det'][i][9][1] = score2
  211. break
  212. else:
  213. j += 1
  214. if len(traffic_dict['det'][i]) == 6:
  215. traffic_dict['det'][i][9][1] = supplementInformation(traffic_dict, i, roundness, y_min, y_max, imgVehicle, rect)
  216. else:
  217. traffic_dict['det'][i][9][1] = supplementInformation(traffic_dict, i, roundness, y_min, y_max, imgVehicle, rect)
  218. i += 1
  219. return vehicleBox, vehicleWH, traffic_dict['det']
  220. # 对于某一vehicle,以该vehicle的最小外接矩形的中心点为圆心O1,划定半径范围,求O1与半径范围内的其他vehicle的中心点之间的距离
  221. def vehicleDistance1(normVehicleCOOR, normVehicleBD, traffic_dict, vehicleWH):
  222. if len(normVehicleCOOR) > 1:
  223. for b in range(len(normVehicleCOOR)):
  224. contoursMinDistance = [] # 存储contours之间的最短距离
  225. tmp = normVehicleCOOR[b]
  226. normVehicleCOOR[b] = normVehicleCOOR[0]
  227. normVehicleCOOR[0] = tmp
  228. targetContours = [] # 存储目标vehicle和中心点同目标车辆中心点之间的距离小于traffic_dict['radius']的vehicle的box
  229. for c in range(1, len(normVehicleCOOR)):
  230. if two_points_distance(normVehicleCOOR[0][0], normVehicleCOOR[0][1], normVehicleCOOR[c][0], normVehicleCOOR[c][1]) <= traffic_dict['radius']:
  231. if normVehicleBD[b] not in targetContours:
  232. targetContours.append(normVehicleBD[b])
  233. if c == b:
  234. targetContours.append(normVehicleBD[0])
  235. else:
  236. targetContours.append(normVehicleBD[c])
  237. if len(targetContours) != 0:
  238. goalVehicleContour = np.squeeze(targetContours[0], 1)
  239. for d in range(1, len(targetContours)):
  240. elseVehicleContour = np.squeeze(targetContours[d], 1)
  241. dist_arr = array_distance(goalVehicleContour, elseVehicleContour)
  242. min_dist = dist_arr[dist_arr > 0].min()
  243. contoursMinDistance.append(min_dist)
  244. traffic_dict['det'][b][8] = min(contoursMinDistance)
  245. if traffic_dict['det'][b][8] < min(vehicleWH[b]) * traffic_dict['vehicleFactor']:
  246. score1 = 1 - traffic_dict['det'][b][8] / (min(vehicleWH[b]) * traffic_dict['vehicleFactor'])
  247. traffic_dict['det'][b][9][2] = score1
  248. traffic_dict['det'][b][10] = judgeAccidentType(traffic_dict, b)
  249. else:
  250. traffic_dict['det'][b][8] = 999
  251. traffic_dict['det'][b][10] = judgeAccidentType(traffic_dict, b)
  252. tmp = normVehicleCOOR[b]
  253. normVehicleCOOR[b] = normVehicleCOOR[0]
  254. normVehicleCOOR[0] = tmp
  255. else: # 路上只有一辆车
  256. if max(traffic_dict['det'][0][9]) == traffic_dict['det'][0][9][0] and traffic_dict['det'][0][9][0] != -1:
  257. traffic_dict['det'][0][10] = 0
  258. elif max(traffic_dict['det'][0][9]) == traffic_dict['det'][0][9][1] and traffic_dict['det'][0][9][1] != -1:
  259. traffic_dict['det'][0][10] = 1
  260. else:
  261. traffic_dict['det'][0][10] = 3
  262. return traffic_dict['det']
  263. # 计算vehicle的最小外接矩形中心点之间的距离和距离得分
  264. def vehicleDistance2(normVehicleCOOR, traffic_dict, vehicleWH):
  265. if len(normVehicleCOOR) > 1: # 有多辆车
  266. for b in range(len(normVehicleCOOR)):
  267. centerDistance = [] # 存储contours之间的最短距离
  268. tmp = normVehicleCOOR[b]
  269. normVehicleCOOR[b] = normVehicleCOOR[0]
  270. normVehicleCOOR[0] = tmp
  271. for c in range(1, len(normVehicleCOOR)):
  272. centerDistance.append(two_points_distance(normVehicleCOOR[0][0], normVehicleCOOR[0][1], normVehicleCOOR[c][0], normVehicleCOOR[c][1]))
  273. smallestDistance = min(centerDistance)
  274. index = centerDistance.index(smallestDistance)
  275. traffic_dict['det'][b][8] = smallestDistance
  276. if index == b - 1: # 序号0和b对应的vehicle
  277. traffic_dict['det'] = distanceScore(vehicleWH, 0, b, smallestDistance, traffic_dict)
  278. else:
  279. traffic_dict['det'] = distanceScore(vehicleWH, index+1, b, smallestDistance, traffic_dict)
  280. tmp = normVehicleCOOR[b]
  281. normVehicleCOOR[b] = normVehicleCOOR[0]
  282. normVehicleCOOR[0] = tmp
  283. else: # 路上只有一辆车
  284. if max(traffic_dict['det'][0][9]) == traffic_dict['det'][0][9][0] and traffic_dict['det'][0][9][0] != -1:
  285. traffic_dict['det'][0][10] = 0
  286. elif max(traffic_dict['det'][0][9]) == traffic_dict['det'][0][9][1] and traffic_dict['det'][0][9][1] != -1:
  287. traffic_dict['det'][0][10] = 1
  288. else:
  289. traffic_dict['det'][0][10] = 3
  290. return traffic_dict['det']
  291. def PostProcessing(mask, testImageArray, traffic_dict, file):
  292. """
  293. 对于字典traffic_dict中的各个键,说明如下:
  294. RoadArea:speedRoad的最小外接矩形的面积
  295. roadVehicleAngle:判定发生交通事故的speedRoad与vehicle间的最小夹角
  296. vehicleCOOR:是一个列表,用于存储被检测出的vehicle的坐标(vehicle检测模型)
  297. roundness:长宽比 ,vehicle的长与宽的比率,设置为0.7,若宽与长的比值大于0.7,则判定该vehicle发生交通事故
  298. ZoomFactor:存储的是图像在H和W方向上的缩放因子,其值小于1
  299. 'cls':类别号
  300. 'vehicleFactor':两辆车之间的安全距离被定义为:min(车辆1的宽,车辆2的宽) * vehicleFactor
  301. 'radius':半径,以某一vehicle的最小外接矩形的中点为圆心,以radius为半径,划定范围,过滤车辆
  302. 'distanceFlag':开关。计算vehicle之间的距离时,可选择不同的函数
  303. 'vehicleFlag':开关。存储vehicle的信息时,可选择不同的函数
  304. 未发生交通事故时,得分为-1,”事故类型“为3
  305. 最终输出格式:[[cls, x0, y0, x1, y1, score, 角度, 长宽比, 最小距离, max([角度得分, 长宽比得分, 最小距离得分]), 交通事故类别], ...]
  306. 交通事故类别:0表示交通事故是由角度原因判定的,1表示交通事故是由长宽比原因判定的,2表示交通事故是由最短距离原因判定的,3表示未发生交通事故。
  307. """
  308. det_cors = []
  309. for bb in traffic_dict['det']:
  310. det_cors.append((int(bb[1]), int(bb[2])))
  311. det_cors.append((int(bb[3]), int(bb[4])))
  312. traffic_dict['vehicleCOOR'] = det_cors
  313. testImageArray = testImageArray[:, :, 0]
  314. H, W = testImageArray.shape[0:2] # sourceImage的分辨率为1080x1920
  315. scaleH = traffic_dict['modelSize'][1] / H # 自适应调整缩放比例 # 360
  316. scaleW = traffic_dict['modelSize'][0] / W # 640
  317. # print("line354", scaleW, scaleH)
  318. traffic_dict['ZoomFactor'] = {'x': scaleW, 'y': scaleH}
  319. new_hw = [int(H * scaleH), int(W * scaleW)]
  320. mask = cv2.resize(mask, (new_hw[1], new_hw[0]))
  321. if len(mask.shape) == 3:
  322. mask = mask[:, :, 0]
  323. t1 = time.time()
  324. normVehicleBD = [] # 存储一副图像中合格vehicle的contours,合格vehicle,即:contours中的顶点数大于等于6
  325. imgRoad = mask.copy()
  326. imgVehicle = mask.copy()
  327. imgRoad[imgRoad == 2] = 0 # 将vehicle过滤掉,只包含背景和speedRoad
  328. imgVehicle[imgVehicle == 1] = 0 # 将speedRoad过滤掉,只包含背景和vehicle
  329. imgRoad = cv2.cvtColor(np.uint8(imgRoad), cv2.COLOR_RGB2BGR) # 道路
  330. imgVehicle = cv2.cvtColor(np.uint8(imgVehicle), cv2.COLOR_RGB2BGR) # 车辆
  331. # cv2.imwrite("./demo/" + file[:-4] + "_mask.png", mask * 50)
  332. # cv2.imwrite("./demo/" + file[:-4] + "_vehicle.png", imgVehicle*50)
  333. # cv2.imwrite("./demo/", + + file[:-4] + "_road.png", imgRoad*255)
  334. t2 = time.time()
  335. img1 = cv2.cvtColor(imgRoad, cv2.COLOR_BGR2GRAY)
  336. contours, hierarchy = cv2.findContours(img1, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
  337. t3 = time.time()
  338. allRoadContent = [] # 存放所有的speedRoad信息,单个speedRoad的信息为:[cnt, speedRoadAngle, rect[1]]
  339. vehicleBox = [] # 存储合格vehicle的box参数,合格vehicle,即:contours顶点个数大于等于6
  340. vehicleWH = [] # 存储合格vehicle的宽高
  341. normVehicle = [] # 存储合格vehicle的信息
  342. unnormVehicle = [] # 存储不合格vehicle的信息,不合格vehicle,即:contours顶点个数小于6
  343. normVehicleCOOR = [] # 存储合格vehicle的中心点坐标
  344. allRoadContent = storageRoad(contours, allRoadContent, traffic_dict)
  345. t4 = time.time()
  346. # 开关。存储vehicle的信息时,可选择不同的函数
  347. if traffic_dict['vehicleFlag'] == True:
  348. # normVehicleCOOR存储车辆分割区域的最小外接矩形的中心点坐标;提取车辆分割区域时,使用bitwise_and(),速度较慢.
  349. traffic_dict['det'], normVehicleBD, unnormVehicle, normVehicleCOOR = storageVehicle1(traffic_dict, normVehicleBD, normVehicle, unnormVehicle, normVehicleCOOR, imgVehicle)
  350. else:
  351. # normVehicleCOOR存储的是yolo检测框的中心点坐标;提取车辆分割区域时,根据x和y的坐标直接从分割图像中抠图,然后再填充边界,和bitwise_and()相比,速度较快
  352. traffic_dict['det'], normVehicleBD, unnormVehicle, normVehicleCOOR = storageVehicle2(traffic_dict, normVehicleBD, normVehicle, unnormVehicle, normVehicleCOOR, imgVehicle)
  353. t5 = time.time()
  354. if len(normVehicleBD) != 0:
  355. t6 = time.time()
  356. vehicleBox, vehicleWH, traffic_dict['det'] = angleRoundness(normVehicleBD, vehicleBox, vehicleWH, allRoadContent, traffic_dict, normVehicleCOOR, imgVehicle)
  357. t7 = time.time()
  358. # 开关。计算vehicle之间的距离时,可选择不同的函数
  359. if traffic_dict['distanceFlag'] == True:
  360. traffic_dict['det'] = vehicleDistance1(normVehicleCOOR, normVehicleBD, traffic_dict, vehicleWH)
  361. else:
  362. traffic_dict['det'] = vehicleDistance2(normVehicleCOOR, traffic_dict, vehicleWH)
  363. t8 = time.time()
  364. targetList = traffic_dict['det']
  365. # print("line393", targetList)
  366. for i in range(len(targetList)):
  367. targetList[i][9] = max(targetList[i][9])
  368. if len(unnormVehicle) != 0:
  369. targetList = targetList + unnormVehicle
  370. t9 = time.time()
  371. # print("line462", targetList) # 目标对象list, [[cls, x0, y0, x1, y1, score, 角度, 长宽比, 最小距离, max([角度得分, 长宽比得分, 最小距离得分]), 类别], ...]
  372. else:
  373. targetList = unnormVehicle
  374. t10 = time.time()
  375. time_infos = 'postTime:%.2f (分割时间:%.2f, findContours:%.2f, ruleJudge:%.2f, storageRoad:%.2f, storageVehicle:%.2f, angleRoundScore:%.2f, vehicleDistance:%.2f, mergeList:%.2f)' % (
  376. get_ms(t10, t1), get_ms(t2, t1), get_ms(t3, t2), get_ms(t10, t3), get_ms(t4, t3), get_ms(t5, t4), get_ms(t7, t6), get_ms(t8, t7), get_ms(t9, t8))
  377. # time_infos = 'postTime:%.2f (分割时间:%.2f, findContours:%.2f, ruleJudge:%.2f, storageRoad:%.2f, storageVehicle:%.2f)' % (
  378. # get_ms(t10, t1), get_ms(t2, t1), get_ms(t3, t2), get_ms(t10, t3), get_ms(t4, t3), get_ms(t5, t4))
  379. return targetList, time_infos