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.

520 lines
28KB

  1. # 设定开关,将最小外接矩形中心点间的距离作为vehicle之间的距离
  2. import numpy as np
  3. import math, cv2, time
  4. from copy import deepcopy
  5. def get_ms(time2, time1):
  6. return (time2 - time1) * 1000.0
  7. def two_points_distance(x1, y1, x2, y2):
  8. distance = math.sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2)
  9. return distance
  10. # 保存正常vehicle和非正常vehicle的信息(当contours顶点数小于6时,无法拟合最小外接矩形,定义为非正常vehicle)
  11. def saveVehicle1(traffic_dict, contours, normVehicleBD, normVehicle, count, i, unnormVehicle, normVehicleCOOR):
  12. if len(contours) >= 6:
  13. normVehicleBD.append(contours)
  14. normVehicle.append(traffic_dict['det'][count])
  15. rect = cv2.minAreaRect(contours)
  16. normVehicleCOOR.append(rect[0])
  17. else:
  18. traffic_dict['det'][int(i / 2)] = traffic_dict['det'][int(i / 2)] + [0, 0.3, 999, -1, 3]
  19. unnormVehicle.append(traffic_dict['det'][int(i / 2)])
  20. return normVehicleBD, normVehicle, unnormVehicle, normVehicleCOOR
  21. # saveVehicle2和saveVehicle1有区别
  22. def saveVehicle2(traffic_dict, contours, normVehicleBD, normVehicle, count, i, unnormVehicle, normVehicleCOOR, centerCOOR):
  23. if len(contours) >= 6:
  24. normVehicleBD.append(contours)
  25. normVehicle.append(traffic_dict['det'][count])
  26. normVehicleCOOR.append(centerCOOR)
  27. else:
  28. traffic_dict['det'][int(i / 2)] = traffic_dict['det'][int(i / 2)] + [0, 0.3, 999, -1, 3]
  29. unnormVehicle.append(traffic_dict['det'][int(i / 2)])
  30. return normVehicleBD, normVehicle, unnormVehicle, normVehicleCOOR
  31. # 对于不在道路上的vehicle,将输出信息补全
  32. def supplementInformation(traffic_dict, i, roundness, y_min, y_max, imgVehicle, rect):
  33. score = -1
  34. traffic_dict['det'][i] = traffic_dict['det'][i] + [0, roundness, 999, [-1, -1, -1], 666]
  35. if y_min > 0 and y_max < imgVehicle.shape[0] and roundness > traffic_dict['roundness']: # 过滤掉上下方被speedRoad的边界截断的vehicle
  36. score = (min(rect[1]) - max(rect[1]) * traffic_dict['roundness']) / (max(rect[1]) * (1 - traffic_dict['roundness']))
  37. return score
  38. # 判断交通事故类型
  39. def judgeAccidentType(traffic_dict, b):
  40. if max(traffic_dict['det'][b][9]) == traffic_dict['det'][b][9][0] and traffic_dict['det'][b][9][0] != -1:
  41. return 0
  42. elif max(traffic_dict['det'][b][9]) == traffic_dict['det'][b][9][1] and traffic_dict['det'][b][9][1] != -1:
  43. return 1
  44. elif max(traffic_dict['det'][b][9]) == traffic_dict['det'][b][9][2] and traffic_dict['det'][b][9][2] != -1:
  45. return 2
  46. else:
  47. return 3
  48. # 计算距离得分
  49. def distanceScore(vehicleWH, index1, index2, smallestDistance, traffic_dict):
  50. d1 = (min(vehicleWH[index1]) + min(vehicleWH[index2])) / 2
  51. d2 = min(min(vehicleWH[index1]), min(vehicleWH[index2])) + max(min(vehicleWH[index1]), min(vehicleWH[index2])) / 2
  52. if smallestDistance == d1:
  53. score1 = 1
  54. traffic_dict['det'][index2][9][2] = score1
  55. traffic_dict['det'][index2][10] = judgeAccidentType(traffic_dict, index2)
  56. elif smallestDistance < d2:
  57. score1 = 1 - (smallestDistance - d1) / (d2 - d1)
  58. if 0 < score1 < 1:
  59. traffic_dict['det'][index2][9][2] = score1
  60. traffic_dict['det'][index2][10] = judgeAccidentType(traffic_dict, index2)
  61. else:
  62. traffic_dict['det'][index2][10] = judgeAccidentType(traffic_dict, index2)
  63. else:
  64. traffic_dict['det'][index2][10] = judgeAccidentType(traffic_dict, index2)
  65. return traffic_dict['det']
  66. # 计算两个contours之间的最短距离
  67. def array_distance(arr1, arr2):
  68. '''
  69. 计算两个数组中,每任意两个点之间L2距离
  70. arr1和arr2都必须是numpy数组
  71. 且维度分别是mx2,nx2
  72. 输出数组维度为mxn
  73. '''
  74. m, _ = arr1.shape
  75. n, _ = arr2.shape
  76. arr1_power = np.power(arr1, 2)
  77. arr1_power_sum = arr1_power[:, 0] + arr1_power[:, 1] # 第1区域,x与y的平方和
  78. arr1_power_sum = np.tile(arr1_power_sum, (n, 1)) # 将arr1_power_sum沿着y轴复制n倍,沿着x轴复制1倍,这里用于与arr2进行计算。 n x m 维度
  79. arr1_power_sum = arr1_power_sum.T # 将arr1_power_sum进行转置
  80. arr2_power = np.power(arr2, 2)
  81. arr2_power_sum = arr2_power[:, 0] + arr2_power[:, 1] # 第2区域,x与y的平方和
  82. arr2_power_sum = np.tile(arr2_power_sum, (m, 1)) # 将arr1_power_sum沿着y轴复制m倍,沿着x轴复制1倍,这里用于与arr1进行计算。 m x n 维度
  83. dis = arr1_power_sum + arr2_power_sum - (2 * np.dot(arr1, arr2.T)) # np.dot(arr1, arr2.T)矩阵相乘,得到xy的值。
  84. dis = np.sqrt(dis)
  85. return dis
  86. # 存储所有道路的信息
  87. def storageRoad(contours, allRoadContent, traffic_dict):
  88. speedRoadAngle = 0
  89. for cnt in contours: # 道路
  90. rect = cv2.minAreaRect(cnt)
  91. if rect[1][0] * rect[1][1] > traffic_dict['RoadArea']: # 过滤掉面积小于阈值的speedRoad
  92. if rect[1][0] <= rect[1][1]:
  93. if rect[2] >= 0 and rect[2] < 90:
  94. speedRoadAngle = rect[2] + 90
  95. elif rect[2] == 90:
  96. speedRoadAngle = 0
  97. else:
  98. if rect[2] >= 0 and rect[2] <= 90:
  99. speedRoadAngle = rect[2]
  100. allRoadContent.append([cnt, speedRoadAngle, rect[1]])
  101. return allRoadContent
  102. # 存储所有vehicle的信息,方法1
  103. def storageVehicle1(traffic_dict, normVehicleBD, normVehicle, unnormVehicle, normVehicleCOOR, imgVehicle):
  104. #输入:
  105. #
  106. #输出:traffic_dict['det'], normVehicleBD, unnormVehicle, normVehicleCOOR
  107. # traffic_dict['det']:resize缩小之后的坐标,类别,得分.[cls,x0,y0,x1,y1,score]
  108. # normVehicleBD : 正常车辆的contours。(正常车辆指的是countrous定点数>=6)
  109. # unnormVehicle : resize缩小之后的异常车辆坐标,类别,得分.[cls,x0,y0,x1,y1,score]
  110. count = 0
  111. for i in range(0, len(traffic_dict['vehicleCOOR']), 2):
  112. mask = np.zeros(imgVehicle.shape[:2], dtype="uint8")
  113. x0 = int(traffic_dict['vehicleCOOR'][i][0] * traffic_dict['ZoomFactor']['y'])
  114. y0 = int(traffic_dict['vehicleCOOR'][i][1] * traffic_dict['ZoomFactor']['x'])
  115. x1 = int(traffic_dict['vehicleCOOR'][i + 1][0] * traffic_dict['ZoomFactor']['y'])
  116. y1 = int(traffic_dict['vehicleCOOR'][i + 1][1] * traffic_dict['ZoomFactor']['x'])
  117. cv2.rectangle(mask, (x0, y0), (x1, y1), 255, -1, lineType=cv2.LINE_AA)
  118. imgVehicle_masked = cv2.bitwise_and(imgVehicle, imgVehicle, mask=mask)
  119. img2 = cv2.cvtColor(imgVehicle_masked, cv2.COLOR_BGR2GRAY)
  120. contours2, hierarchy2 = cv2.findContours(img2, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
  121. if len(contours2) != 0:
  122. if len(contours2) > 1: # 这里我通过比较同一检测框内各个contours对应的最小外接矩形的面积,来剔除那些存在干扰的contours,最终只保留一个contours
  123. vehicleArea = [] # 存储vehicle的最小外接矩形的面积
  124. for j in range(len(contours2)):
  125. rect = cv2.minAreaRect(contours2[j])
  126. vehicleArea.append(rect[1][0] * rect[1][1])
  127. maxAreaIndex = vehicleArea.index(max(vehicleArea))
  128. maxAreaContours = contours2[maxAreaIndex]
  129. normVehicleBD, normVehicle, unnormVehicle, normVehicleCOOR = saveVehicle1(traffic_dict,maxAreaContours,normVehicleBD,normVehicle,count,i,unnormVehicle, normVehicleCOOR)
  130. elif len(contours2) == 1:
  131. normVehicleBD, normVehicle, unnormVehicle, normVehicleCOOR = saveVehicle1(traffic_dict,contours2[0],normVehicleBD,normVehicle,count,i,unnormVehicle, normVehicleCOOR)
  132. else:
  133. traffic_dict['det'][int(i / 2)] = traffic_dict['det'][int(i / 2)] + [0, 0.3, 999, -1, 3]
  134. unnormVehicle.append(traffic_dict['det'][int(i / 2)])
  135. count += 1
  136. traffic_dict['det'] = normVehicle
  137. return traffic_dict['det'], normVehicleBD, unnormVehicle, normVehicleCOOR
  138. # 存储所有vehicle的信息,方法2
  139. def storageVehicle2(traffic_dict, normVehicleBD, normVehicle, unnormVehicle, normVehicleCOOR, imgVehicle):
  140. img = cv2.cvtColor(imgVehicle, cv2.COLOR_BGR2GRAY)
  141. count = 0
  142. for i in range(0, len(traffic_dict['vehicleCOOR']), 2):
  143. row1 = int(traffic_dict['vehicleCOOR'][i][1] * traffic_dict['ZoomFactor']['x'])
  144. row2 = int(traffic_dict['vehicleCOOR'][i + 1][1] * traffic_dict['ZoomFactor']['x'])
  145. col1 = int(traffic_dict['vehicleCOOR'][i][0] * traffic_dict['ZoomFactor']['y'])
  146. col2 = int(traffic_dict['vehicleCOOR'][i + 1][0] * traffic_dict['ZoomFactor']['y'])
  147. if row1 >= 2:
  148. row1 = row1 - 2
  149. if row2 <= (traffic_dict['modelSize'][1] - 2):
  150. row2 = row2 + 2
  151. if col1 >= 2:
  152. col1 = col1 - 2
  153. if col2 <= (traffic_dict['modelSize'][0] - 2):
  154. col2 = col2 + 2
  155. centerCOOR = (int((col1 + col2) / 2), int((row1 + row2) / 2))
  156. img1 = img[row1:row2, col1:col2]
  157. up = np.zeros((20, (col2 - col1)), dtype='uint8')
  158. left = np.zeros(((40 + row2 - row1), 20), dtype='uint8')
  159. img1 = np.concatenate((up, img1), axis=0)
  160. img1 = np.concatenate((img1, up), axis=0)
  161. img1 = np.concatenate((left, img1), axis=1)
  162. img2 = np.concatenate((img1, left), axis=1)
  163. contours2, hierarchy = cv2.findContours(img2, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
  164. if len(contours2) != 0:
  165. if len(contours2) > 1:
  166. vehicleArea = [] # 存储vehicle的最小外接矩形的面积
  167. for j in range(len(contours2)):
  168. rect = cv2.minAreaRect(contours2[j])
  169. vehicleArea.append(rect[1][0] * rect[1][1])
  170. maxAreaIndex = vehicleArea.index(max(vehicleArea))
  171. maxAreaContours = contours2[maxAreaIndex]
  172. normVehicleBD, normVehicle, unnormVehicle, normVehicleCOOR = saveVehicle2(traffic_dict,maxAreaContours,normVehicleBD,normVehicle,count,i,unnormVehicle,normVehicleCOOR,centerCOOR)
  173. elif len(contours2) == 1:
  174. normVehicleBD, normVehicle, unnormVehicle, normVehicleCOOR = saveVehicle2(traffic_dict,contours2[0],normVehicleBD,normVehicle,count,i,unnormVehicle,normVehicleCOOR,centerCOOR)
  175. else:
  176. traffic_dict['det'][int(i / 2)] = traffic_dict['det'][int(i / 2)] + [0, 0.3, 999, -1, 3]
  177. unnormVehicle.append(traffic_dict['det'][int(i / 2)])
  178. count += 1
  179. traffic_dict['det'] = normVehicle
  180. return traffic_dict['det'], normVehicleBD, unnormVehicle, normVehicleCOOR
  181. # 计算角度和长宽比得分
  182. def angleRoundness(normVehicleBD, vehicleBox, vehicleWH, allRoadContent, traffic_dict, normVehicleCOOR, imgVehicle):
  183. ##输出:vehicleBox, vehicleWH, traffic_dict['det']
  184. # vehicleBox--正常车辆通过contours得出的box,[ (x0,y0),(x1,y1),(x2,y2),(x3,y3)]
  185. # vehicleWH--正常车辆通过contours得出的box,[ (w,h)]
  186. # traffic_dict['det']--[[cls, x0, y0, x1, y1, score, 角度, 长宽比, 最小距离, max([角度得分, 长宽比得分, 最小距离得分]), 交通事故类别], ...]
  187. for i in range(len(normVehicleBD)):
  188. ellipse = cv2.fitEllipse(normVehicleBD[i])
  189. vehicleAngle = 0
  190. if ellipse[2] >= 0 and ellipse[2] < 90:
  191. vehicleAngle = 90 + ellipse[2]
  192. elif ellipse[2] >= 90 and ellipse[2] < 180:
  193. vehicleAngle = ellipse[2] - 90
  194. elif ellipse[2] == 180:
  195. vehicleAngle = 90
  196. rect = cv2.minAreaRect(normVehicleBD[i])
  197. box = cv2.boxPoints(rect).astype(np.int32)
  198. center = normVehicleCOOR[i]
  199. vehicleBox.append(box)
  200. vehicleWH.append(rect[1])
  201. roundness = min(rect[1]) / max(rect[1])
  202. y_min = np.min(box[:, 1])
  203. y_max = np.max(box[:, 1])
  204. if len(allRoadContent) != 0:
  205. for j in range(len(allRoadContent)):
  206. flag = cv2.pointPolygonTest(allRoadContent[j][0], center, False)
  207. if flag >= 0:
  208. roadVehicleAngle = abs(vehicleAngle - allRoadContent[j][1])
  209. traffic_dict['det'][i] = traffic_dict['det'][i] + [roadVehicleAngle, roundness, 999, [-1, -1, -1], 666]
  210. if y_min > 0 and y_max < imgVehicle.shape[0]: # 过滤掉上下方被speedRoad的边界截断的vehicle
  211. if roadVehicleAngle >= traffic_dict['roadVehicleAngle']: # 当道路同水平方向的夹角与车辆同水平方向的夹角的差值在15°和75°之间时,需要将车辆框出来
  212. if roadVehicleAngle > 90:
  213. score1 = float((180 - roadVehicleAngle) / 90)
  214. else:
  215. score1 = float(roadVehicleAngle / 90)
  216. traffic_dict['det'][i][9][0] = score1
  217. if roundness > traffic_dict['roundness']:
  218. score2 = (min(rect[1]) - max(rect[1]) * traffic_dict['roundness']) / (max(rect[1]) * (1 - traffic_dict['roundness']))
  219. traffic_dict['det'][i][9][1] = score2
  220. break
  221. else:
  222. j += 1
  223. if len(traffic_dict['det'][i]) == 6:
  224. traffic_dict['det'][i][9][1] = supplementInformation(traffic_dict, i, roundness, y_min, y_max, imgVehicle, rect)
  225. else:
  226. traffic_dict['det'][i][9][1] = supplementInformation(traffic_dict, i, roundness, y_min, y_max, imgVehicle, rect)
  227. i += 1
  228. return vehicleBox, vehicleWH, traffic_dict['det']
  229. # 对于某一vehicle,以该vehicle的最小外接矩形的中心点为圆心O1,划定半径范围,求O1与半径范围内的其他vehicle的中心点之间的距离
  230. def vehicleDistance1(normVehicleCOOR, normVehicleBD, traffic_dict, vehicleWH):
  231. if len(normVehicleCOOR) > 1:
  232. for b in range(len(normVehicleCOOR)):
  233. contoursMinDistance = [] # 存储contours之间的最短距离
  234. tmp = normVehicleCOOR[b]
  235. normVehicleCOOR[b] = normVehicleCOOR[0]
  236. normVehicleCOOR[0] = tmp
  237. targetContours = [] # 存储目标vehicle和中心点同目标车辆中心点之间的距离小于traffic_dict['radius']的vehicle的box
  238. for c in range(1, len(normVehicleCOOR)):
  239. if two_points_distance(normVehicleCOOR[0][0], normVehicleCOOR[0][1], normVehicleCOOR[c][0], normVehicleCOOR[c][1]) <= traffic_dict['radius']:
  240. if normVehicleBD[b] not in targetContours:
  241. targetContours.append(normVehicleBD[b])
  242. if c == b:
  243. targetContours.append(normVehicleBD[0])
  244. else:
  245. targetContours.append(normVehicleBD[c])
  246. if len(targetContours) != 0:
  247. goalVehicleContour = np.squeeze(targetContours[0], 1)
  248. for d in range(1, len(targetContours)):
  249. elseVehicleContour = np.squeeze(targetContours[d], 1)
  250. dist_arr = array_distance(goalVehicleContour, elseVehicleContour)
  251. min_dist = dist_arr[dist_arr > 0].min()
  252. contoursMinDistance.append(min_dist)
  253. traffic_dict['det'][b][8] = min(contoursMinDistance)
  254. if traffic_dict['det'][b][8] < min(vehicleWH[b]) * traffic_dict['vehicleFactor']:
  255. score1 = 1 - traffic_dict['det'][b][8] / (min(vehicleWH[b]) * traffic_dict['vehicleFactor'])
  256. traffic_dict['det'][b][9][2] = score1
  257. traffic_dict['det'][b][10] = judgeAccidentType(traffic_dict, b)
  258. else:
  259. traffic_dict['det'][b][8] = 999
  260. traffic_dict['det'][b][10] = judgeAccidentType(traffic_dict, b)
  261. tmp = normVehicleCOOR[b]
  262. normVehicleCOOR[b] = normVehicleCOOR[0]
  263. normVehicleCOOR[0] = tmp
  264. else: # 路上只有一辆车
  265. if max(traffic_dict['det'][0][9]) == traffic_dict['det'][0][9][0] and traffic_dict['det'][0][9][0] != -1:
  266. traffic_dict['det'][0][10] = 0
  267. elif max(traffic_dict['det'][0][9]) == traffic_dict['det'][0][9][1] and traffic_dict['det'][0][9][1] != -1:
  268. traffic_dict['det'][0][10] = 1
  269. else:
  270. traffic_dict['det'][0][10] = 3
  271. return traffic_dict['det']
  272. # 计算vehicle的最小外接矩形中心点之间的距离和距离得分
  273. def vehicleDistance2(normVehicleCOOR, traffic_dict, vehicleWH):
  274. if len(normVehicleCOOR) > 1: # 有多辆车
  275. for b in range(len(normVehicleCOOR)):
  276. centerDistance = [] # 存储contours之间的最短距离
  277. tmp = normVehicleCOOR[b]
  278. normVehicleCOOR[b] = normVehicleCOOR[0]
  279. normVehicleCOOR[0] = tmp
  280. for c in range(1, len(normVehicleCOOR)):
  281. centerDistance.append(two_points_distance(normVehicleCOOR[0][0], normVehicleCOOR[0][1], normVehicleCOOR[c][0], normVehicleCOOR[c][1]))
  282. smallestDistance = min(centerDistance)
  283. index = centerDistance.index(smallestDistance)
  284. traffic_dict['det'][b][8] = smallestDistance
  285. if index == b - 1: # 序号0和b对应的vehicle
  286. traffic_dict['det'] = distanceScore(vehicleWH, 0, b, smallestDistance, traffic_dict)
  287. else:
  288. traffic_dict['det'] = distanceScore(vehicleWH, index+1, b, smallestDistance, traffic_dict)
  289. tmp = normVehicleCOOR[b]
  290. normVehicleCOOR[b] = normVehicleCOOR[0]
  291. normVehicleCOOR[0] = tmp
  292. else: # 路上只有一辆车
  293. if max(traffic_dict['det'][0][9]) == traffic_dict['det'][0][9][0] and traffic_dict['det'][0][9][0] != -1:
  294. traffic_dict['det'][0][10] = 0
  295. elif max(traffic_dict['det'][0][9]) == traffic_dict['det'][0][9][1] and traffic_dict['det'][0][9][1] != -1:
  296. traffic_dict['det'][0][10] = 1
  297. else:
  298. traffic_dict['det'][0][10] = 3
  299. return traffic_dict['det']
  300. def PostProcessing( traffic_dict):
  301. """
  302. 对于字典traffic_dict中的各个键,说明如下:
  303. RoadArea:speedRoad的最小外接矩形的面积
  304. roadVehicleAngle:判定发生交通事故的speedRoad与vehicle间的最小夹角
  305. vehicleCOOR:是一个列表,用于存储被检测出的vehicle的坐标(vehicle检测模型)
  306. roundness:长宽比 ,vehicle的长与宽的比率,设置为0.7,若宽与长的比值大于0.7,则判定该vehicle发生交通事故
  307. ZoomFactor:存储的是图像在H和W方向上的缩放因子,其值小于1
  308. 'cls':类别号
  309. 'vehicleFactor':两辆车之间的安全距离被定义为:min(车辆1的宽,车辆2的宽) * vehicleFactor
  310. 'radius':半径,以某一vehicle的最小外接矩形的中点为圆心,以radius为半径,划定范围,过滤车辆
  311. 'distanceFlag':开关。计算vehicle之间的距离时,可选择不同的函数
  312. 'vehicleFlag':开关。存储vehicle的信息时,可选择不同的函数
  313. 未发生交通事故时,得分为-1,”事故类型“为3
  314. 最终输出格式:[[cls, x0, y0, x1, y1, score, 角度, 长宽比, 最小距离, max([角度得分, 长宽比得分, 最小距离得分]), 交通事故类别], ...]
  315. 交通事故类别:0表示角度,1表示长宽比,2表示最短距离,3表示未发生交通事故
  316. """
  317. det_cors = []
  318. #print('###line338:', traffic_dict['det'])
  319. for bb in traffic_dict['det']:
  320. det_cors.append((int(bb[1]), int(bb[2])))
  321. det_cors.append((int(bb[3]), int(bb[4])))
  322. traffic_dict['vehicleCOOR'] = det_cors
  323. #testImageArray = testImageArray[:, :, 0]
  324. #H, W = testImageArray.shape[0:2] # sourceImage的分辨率为1080x1920
  325. traffic_dict['modelSize']=[640,360]
  326. #traffic_dict['mask'] = cv2.resize(traffic_dict['mask'],(640,360))
  327. mask = traffic_dict['mask']
  328. H, W = mask.shape[0:2]
  329. #(640, 360) 720 1280 (720, 1280)
  330. ####line361: (1920, 1080) 720 1280 (720, 1280)
  331. ###line361: [640, 360] 360 640 (360, 640)
  332. #print('###line361:',traffic_dict['modelSize'], H,W ,mask.shape)
  333. scaleH = traffic_dict['modelSize'][1] / H # 自适应调整缩放比例
  334. scaleW = traffic_dict['modelSize'][0] / W
  335. traffic_dict['ZoomFactor'] = {'x': scaleH, 'y': scaleW}
  336. new_hw = [int(H * scaleH), int(W * scaleW)]
  337. mask = cv2.resize(mask, (new_hw[1], new_hw[0]))
  338. if len(mask.shape) == 3:
  339. mask = mask[:, :, 0]
  340. t1 = time.time()
  341. normVehicleBD = [] # 存储一副图像中合格vehicle的contours,合格vehicle,即:contours中的顶点数大于等于6
  342. imgRoad = mask.copy()
  343. imgVehicle = mask.copy()
  344. imgRoad[imgRoad == 2] = 0 # 将vehicle过滤掉,只包含背景和speedRoad
  345. imgVehicle[imgVehicle == 1] = 0 # 将speedRoad过滤掉,只包含背景和vehicle
  346. imgRoad = cv2.cvtColor(np.uint8(imgRoad), cv2.COLOR_RGB2BGR) # 道路
  347. imgVehicle = cv2.cvtColor(np.uint8(imgVehicle), cv2.COLOR_RGB2BGR) # 车辆
  348. t2 = time.time()
  349. img1 = cv2.cvtColor(imgRoad, cv2.COLOR_BGR2GRAY)
  350. contours, hierarchy = cv2.findContours(img1, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
  351. t3 = time.time()
  352. allRoadContent = [] # 存放所有的speedRoad信息,单个speedRoad的信息为:[cnt, speedRoadAngle, rect[1]]
  353. vehicleBox = [] # 存储合格vehicle的box参数,合格vehicle,即:contours顶点个数大于等于6
  354. vehicleWH = [] # 存储合格vehicle的宽高
  355. normVehicle = [] # 存储合格vehicle的信息
  356. unnormVehicle = [] # 存储不合格vehicle的信息,不合格vehicle,即:contours顶点个数小于6
  357. normVehicleCOOR = [] # 存储合格vehicle的中心点坐标
  358. allRoadContent = storageRoad(contours, allRoadContent, traffic_dict)
  359. t4 = time.time()
  360. # 开关。存储vehicle的信息时,可选择不同的函数
  361. if traffic_dict['vehicleFlag'] == True:
  362. traffic_dict['det'], normVehicleBD, unnormVehicle, normVehicleCOOR = storageVehicle1(traffic_dict, normVehicleBD, normVehicle, unnormVehicle, normVehicleCOOR, imgVehicle)
  363. #所有车辆的[cls,x0,y0,x1,y1,score]
  364. else:
  365. traffic_dict['det'], normVehicleBD, unnormVehicle, normVehicleCOOR = storageVehicle2(traffic_dict, normVehicleBD, normVehicle, unnormVehicle, normVehicleCOOR, imgVehicle)
  366. t5 = time.time()
  367. if len(normVehicleBD) != 0:
  368. t6 = time.time()
  369. vehicleBox, vehicleWH, traffic_dict['det'] = angleRoundness(normVehicleBD, vehicleBox, vehicleWH, allRoadContent, traffic_dict, normVehicleCOOR, imgVehicle)
  370. t7 = time.time()
  371. # 开关。计算vehicle之间的距离时,可选择不同的函数
  372. if traffic_dict['distanceFlag'] == True:
  373. traffic_dict['det'] = vehicleDistance1(normVehicleCOOR, normVehicleBD, traffic_dict, vehicleWH)
  374. else:
  375. traffic_dict['det'] = vehicleDistance2(normVehicleCOOR, traffic_dict, vehicleWH)
  376. t8 = time.time()
  377. targetList = traffic_dict['det']
  378. # print("line393", targetList)
  379. for i in range(len(targetList)):
  380. targetList[i][9] = max(targetList[i][9])
  381. if len(unnormVehicle) != 0:
  382. targetList = targetList + unnormVehicle
  383. t9 = time.time()
  384. # print("line462", targetList) # 目标对象list, [[cls, x0, y0, x1, y1, score, 角度, 长宽比, 最小距离, max([角度得分, 长宽比得分, 最小距离得分]), 类别], ...]
  385. ruleJudge='angle-rundness-distance:%.1f'%( get_ms(t9,t6) )
  386. else:
  387. targetList = unnormVehicle
  388. ruleJudge = 'No angle-rundness-distance judging'
  389. t10 = time.time()
  390. time_infos = '---test---nothing---'
  391. #time_infos = 'postTime:%.2f (分割时间:%.2f, findContours:%.2f, ruleJudge:%.2f, storageRoad:%.2f, storageVehicle:%.2f, angleRoundScore:%.2f, vehicleDistance:%.2f, mergeList:%.2f)' % (
  392. # 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))
  393. time_infos = 'postTime:%.2f , ( findContours:%.1f , carContourFilter:%.1f, %s )' %( get_ms(t10,t1), get_ms(t4,t1), get_ms(t5,t4),ruleJudge)
  394. return targetList, time_infos
  395. def tracfficAccidentMixFunction(preds,seg_pred_mulcls,pars):
  396. tjime0=time.time()
  397. roadIou = pars['roadIou'] if 'roadIou' in pars.keys() else 0.5
  398. preds = np.array(preds)
  399. #area_factors= np.array([np.sum(seg_pred_mulcls[int(x[2]):int(x[4]), int(x[1]):int(x[3])] )*1.0/(1.0*(x[3]-x[1])*(x[4]-x[2])+0.00001) for x in preds] )
  400. area_factors= np.array([np.sum(seg_pred_mulcls[int(x[1]):int(x[3]), int(x[0]):int(x[2])] )*1.0/(1.0*(x[2]-x[0])*(x[3]-x[1])+0.00001) for x in preds] )#2023.08.03修改数据格式
  401. water_flag = np.array(area_factors>roadIou)
  402. #print('##line936:',preds )
  403. dets = preds[water_flag]##如果是水上目标,则需要与水的iou超过0.1;如果是岸坡目标,则直接保留。
  404. dets = dets.tolist()
  405. #label_info = get_label_info(pars['label_csv'])
  406. imH,imW = seg_pred_mulcls.shape[0:2]
  407. seg_pred = cv2.resize(seg_pred_mulcls,( pars['modelSize'][0] , pars['modelSize'] [1]) )
  408. mmH,mmW = seg_pred.shape[0:2]
  409. fx=mmW/imW;fy=mmH/imH
  410. det_coords=[]
  411. det_coords_original=[]
  412. for box in dets:
  413. #b_0 = box[1:5];b_0.insert(0,box[0]);b_0.append(box[5] )
  414. b_0 = box[0:4];b_0.insert(0,box[5]);b_0.append(box[4])
  415. det_coords_original.append( box )
  416. if int(box[5]) != 1: continue
  417. det_coords.append(b_0)
  418. #print('##line957:',det_coords_original )
  419. pars['ZoomFactor']={'x':mmW/imW ,'y':mmH/imH}
  420. #pars['mask']=seg_pred;
  421. pars['mask']=seg_pred_mulcls;
  422. pars['det']=deepcopy(det_coords)
  423. #pars['label_info']=label_info
  424. tlist = list(pars.keys()); tlist.sort()
  425. if len(det_coords)> 0:
  426. #print('###line459:',pars['mask'].shape, pars['det'])
  427. list8,time_infos = PostProcessing(pars)
  428. #print('###line461:',list8 )
  429. Accident_results = np.array(list8,dtype=object)
  430. acc_det=[]
  431. #[1.0, 1692.0, 169.0, 1803.0, 221.0, 0.494875431060791, 30, 0.5, 3.0, 0.3, 0]
  432. #[0 , 1 , 2 , 3 , 4 , 5 , 6, 7 , 8 , 9 , 10]
  433. for bpoints in list8:
  434. if bpoints[9]>pars['confThres']:
  435. xyxy=bpoints[1:5];xyxy=[int(x) for x in xyxy]
  436. cls=9;conf=bpoints[9];
  437. box_acc = [*xyxy,conf,cls]
  438. acc_det.append(box_acc)
  439. #if cls in allowedList:
  440. # p_result[1] = draw_painting_joint(xyxy,p_result[1],label_arraylist[int(cls)],score=conf,color=rainbows[int(cls)%20],font=font,socre_location="leftBottom")
  441. #print('###line475:',acc_det )
  442. #去掉被定为事故的车辆
  443. carCorslist = [ [ int(x[0]),int(x[1]), int(x[2]), int(x[3]) ] for x in det_coords_original ]
  444. #print('##line81:',det_coords_original )
  445. accidentCarIndexs = [ carCorslist.index( [ int(x[0]),int(x[1]), int(x[2]), int(x[3]) ] ) for x in acc_det ]
  446. accidentCarIndexsKeep = set(list(range(len(det_coords_original)))) - set(accidentCarIndexs)
  447. det_coords_original_tmp = [ det_coords_original[x] for x in accidentCarIndexsKeep ]
  448. det_coords_original = det_coords_original_tmp
  449. #print('##line85:',det_coords_original )
  450. det_coords_original.extend(acc_det)
  451. #4.0, 961.0, 275.0, 1047.0, 288.0, 0.26662659645080566, 0.0, 0.0
  452. #0 , 1 , 2 , 3 , 4 , 5 , 6 , 7
  453. #det_coords_original =[ [ *x[1:6], x[0],*x[6:8] ] for x in det_coords_original]
  454. else:
  455. time_infos=" no tracfficAccidentMix process"
  456. #p_result[2]= deepcopy(det_coords_original)
  457. return deepcopy(det_coords_original),time_infos
  458. def tracfficAccidentMixFunction_N(predList,pars):
  459. preds,seg_pred_mulcls = predList[0:2]
  460. return tracfficAccidentMixFunction(preds,seg_pred_mulcls,pars)