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.

273 lines
9.7KB

  1. '''
  2. 这个版本增加了船舶过滤功能
  3. '''
  4. import time
  5. import numpy as np
  6. import cv2
  7. def center_coordinate(boundbxs):
  8. '''
  9. 输入:两个对角坐标xyxy
  10. 输出:矩形框重点坐标xy
  11. '''
  12. boundbxs_x1=boundbxs[0]
  13. boundbxs_y1=boundbxs[1]
  14. boundbxs_x2=boundbxs[2]
  15. boundbxs_y2=boundbxs[3]
  16. center_x=0.5*(boundbxs_x1+boundbxs_x2)
  17. center_y=0.5*(boundbxs_y1+boundbxs_y2)
  18. return center_x,center_y
  19. def fourcorner_coordinate(boundbxs):
  20. '''
  21. 输入:两个对角坐标xyxy
  22. 输出:矩形框四个角点坐标,以contours顺序。
  23. '''
  24. boundbxs_x1=boundbxs[0]
  25. boundbxs_y1=boundbxs[1]
  26. boundbxs_x2=boundbxs[2]
  27. boundbxs_y2=boundbxs[3]
  28. wid=boundbxs_x2-boundbxs_x1
  29. hei=boundbxs_y2-boundbxs_y1
  30. boundbxs_x3=boundbxs_x1+wid
  31. boundbxs_y3=boundbxs_y1
  32. boundbxs_x4=boundbxs_x1
  33. boundbxs_y4 = boundbxs_y1+hei
  34. contours_rec=[[boundbxs_x1,boundbxs_y1],[boundbxs_x3,boundbxs_y3],[boundbxs_x2,boundbxs_y2],[boundbxs_x4,boundbxs_y4]]
  35. return contours_rec
  36. def expand_rectangle(rec,imgSize,ex_width,ex_height):
  37. '''
  38. 矩形框外扩,且不超过图像范围
  39. 输入:矩形框xyxy(左上和右下坐标),图像,外扩宽度大小,外扩高度大小
  40. 输出:扩后的矩形框坐标xyxy
  41. '''
  42. #img_height=img.shape[0];img_width=img.shape[1]
  43. img_width,img_height = imgSize[0:2]
  44. #print('高、宽',img_height,img_width)
  45. x1=rec[0]
  46. y1=rec[1]
  47. x3=rec[2]
  48. y3=rec[3]
  49. x1=x1-ex_width if x1-ex_width >= 0 else 0
  50. y1=y1-ex_height if y1-ex_height >= 0 else 0
  51. x3=x3+ex_width if x3+ex_width <= img_width else img_width
  52. y3=y3+ex_height if y3+ex_height <=img_height else img_height
  53. xyxy=[x1,y1,x3,y3]
  54. return xyxy
  55. def remove_simivalue(list1,list2):
  56. '''
  57. 将list1中属于list2的元素都删除。
  58. 输入:两个嵌套列表
  59. 返回:嵌套列表
  60. '''
  61. list33=list1.copy()
  62. for i in range(len(list1)):
  63. for j in range(len(list2)):
  64. if list2[j] == list1[i]:
  65. # list33.pop(list1[i])
  66. list33.remove(list1[i])
  67. return list33
  68. def remove_sameeleme_inalist(list3):
  69. '''
  70. 将list3中重复嵌套列表元素删除。
  71. 输入:嵌套列表
  72. 返回:嵌套列表
  73. '''
  74. list3=list3
  75. list4=[]
  76. list4.append(list3[0])
  77. for dict in list3:
  78. k=0
  79. for item in list4:
  80. if dict!=item:
  81. k=k+1
  82. else:
  83. break
  84. if k==len(list4):
  85. list4.append(dict)
  86. return list4
  87. def order_points(pts):
  88. ''' sort rectangle points by clockwise '''
  89. sort_x = pts[np.argsort(pts[:, 0]), :]
  90. Left = sort_x[:2, :]
  91. Right = sort_x[2:, :]
  92. # Left sort
  93. Left = Left[np.argsort(Left[:, 1])[::-1], :]
  94. # Right sort
  95. Right = Right[np.argsort(Right[:, 1]), :]
  96. return np.concatenate((Left, Right), axis=0)
  97. def ms(t2,t1):
  98. return '%.1f' %( (t2-t1)*1000.0)
  99. def illParking_postprocess(pred,cvMask,pars):
  100. #pred:直接预测结果,不要原图。预测结果[0,1,2,...],不是[车、T角点,L角点]
  101. #mask_cv:分割结果图,numpy格式(H,W),结果是int,[0,1,2,...]
  102. #pars: 其它参数,dict格式
  103. '''三个标签:车、T角点,L角点'''
  104. '''输入:落水人员的结果(类别+坐标)、原图
  105. 过程:将车辆识别框外扩,并按contours形成区域。
  106. T角点与L角点的坐标合并为列表。
  107. 判断每个车辆contours区域内有几个角点,少于2个则判断违停。
  108. 返回:最终违停车辆标记结果图、违停车辆信息(坐标、类别、置信度)。
  109. '''
  110. #输入的是[cls,x0,y0,x1,y1,score]---> [x0,y0,x1,y1,cls,score]
  111. #输出的也是[cls,x0,y0,x1,y1,score]
  112. #pred = [ [ int(x[4]) ,*x[1:5], x[5] ] for x in pred]
  113. #pred = [[ *x[1:5],x[0], x[5] ] for x in pred]
  114. pred = [[ *x[0:4],x[5], x[4] ] for x in pred]
  115. ##统一格式
  116. imgSize=pars['imgSize']
  117. '''1、pred中车辆识别框形成列表,T角点与L角点形成列表'''
  118. tW1=time.time()
  119. init_vehicle=[]
  120. init_corner = []
  121. for i in range(len(pred)):
  122. #if pred[i][4]=='TCorner' or pred[i][4]=='LCorner': #vehicle、TCorner、LCorner
  123. if pred[i][4]==1 or pred[i][4]==2: #vehicle、TCorner、LCorner
  124. init_corner.append(pred[i])
  125. else:
  126. init_vehicle.append(pred[i])
  127. '''2、init_corner中心点坐标计算,并形成列表。'''
  128. tW2 = time.time()
  129. center_corner=[]
  130. for i in range(len(init_corner)):
  131. center_corner.append(center_coordinate(init_corner[i]))
  132. '''3、遍历每个车辆识别框,扩充矩形区域,将矩形区域形成contours,判断扩充区域内的。'''
  133. tW3 = time.time()
  134. final_weiting=[] #违停车辆列表
  135. '''遍历车辆列表,扩大矩形框形成contours'''
  136. for i in range(len(init_vehicle)):
  137. boundbxs1=[init_vehicle[i][0],init_vehicle[i][1],init_vehicle[i][2],init_vehicle[i][3]]
  138. width_boundingbox=init_vehicle[i][2]-init_vehicle[i][0] #框宽度
  139. height_boundingbox=init_vehicle[i][2] - init_vehicle[i][0] #框长度
  140. #当框长大于宽,则是水平方向车辆;否则认为是竖向车辆
  141. if width_boundingbox>=height_boundingbox:
  142. ex_width=0.4*(init_vehicle[i][2]-init_vehicle[i][0]) #矩形扩充宽度,取车宽0.4倍 #膨胀系数小一些。角点设成1个。
  143. ex_height=0.2*(init_vehicle[i][2]-init_vehicle[i][0]) #矩形扩充宽度,取车长0.2倍
  144. boundbxs1 = expand_rectangle(boundbxs1, imgSize, ex_width, ex_height) # 扩充后矩形对角坐标
  145. else:
  146. ex_width=0.2*(init_vehicle[i][2]-init_vehicle[i][0]) #竖向,不需要改变变量名称,将系数对换下就行。(坐标点顺序还是1234不变)
  147. ex_height=0.4*(init_vehicle[i][2]-init_vehicle[i][0]) #
  148. boundbxs1 = expand_rectangle(boundbxs1, imgSize, ex_width, ex_height) # 扩充后矩形对角坐标
  149. contour_temp=fourcorner_coordinate(boundbxs1) #得到扩充后矩形框的contour
  150. contour_temp_=np.array(contour_temp)#contour转为array
  151. contour_temp_=np.float32(contour_temp_)
  152. '''遍历角点识别框中心坐标是否在contours内,在则计1'''
  153. zzz=0
  154. for j in range(len(center_corner)):
  155. flag = cv2.pointPolygonTest(contour_temp_, (center_corner[j][0], center_corner[j][1]), False) #若为False,会找点是否在内,外,或轮廓上(相应返回+1, -1, 0)。
  156. if flag==+1:
  157. zzz+=1
  158. '''contours框内小于等于1个角点,认为不在停车位内'''
  159. # if zzz<=1:
  160. if zzz<1:
  161. final_weiting.append(init_vehicle[i])
  162. #print('t7-t6',t7-t6)
  163. #print('final_weiting',final_weiting)
  164. '''4、绘制保存检违停车辆图像'''
  165. tW4=time.time()
  166. '''
  167. colors = Colors()
  168. if final_weiting is not None:
  169. for i in range(len(final_weiting)):
  170. lbl='illegal park'
  171. xyxy=[final_weiting[i][0],final_weiting[i][1],final_weiting[i][2],final_weiting[i][3]]
  172. c = int(5)
  173. plot_one_box(xyxy, _img_cv, label=lbl, color=colors(c, True), line_thickness=3)
  174. final_img=_img_cv
  175. '''
  176. tW5=time.time()
  177. # cv2.imwrite('final_result.png', _img_cv)
  178. timeStr = ' step1:%s step2:%s step3:%s save:%s'%( ms(tW2,tW1), ms(tW3,tW2),ms(tW4,tW3), ms(tW5,tW4) )
  179. #final_weiting-----[x0,y0,x1,y1,cls,score]
  180. #输出的也是outRe----[cls,x0,y0,x1,y1,score]
  181. #outRes = [ [ 3 ,*x[0:4], x[5] ] for x in final_weiting]###违停用3表示
  182. outRes = [ [ *x[0:4], x[5],3 ] for x in final_weiting]###违停用3表示
  183. return outRes,timeStr #返回最终绘制的结果图、违停车辆(坐标、类别、置信度)
  184. def AI_process(model, args1,path1):
  185. '''对原图进行目标检测'''
  186. '''输入:检测模型、配置参数、路径
  187. 返回:返回目标检测结果、原图像,
  188. '''
  189. '''检测图片'''
  190. t3=time.time()
  191. _img_cv = cv2.imread(path1) # 将这里的送入yolov5
  192. t4 = time.time()
  193. pred = model.detect(_img_cv) # 检测结果
  194. t5 = time.time()
  195. #print('t5-t4', t5-t4)
  196. #print('t4-t3', t4-t3)
  197. return pred, _img_cv #返回目标检测结果、原图像
  198. def main():
  199. '''配置参数'''
  200. args1={'cuda':'0','input_dir':'input_dir','output_dir':'output_dir'}
  201. dete_weights='weights/weiting20230727.pt'
  202. '''分割模型权重路径'''
  203. '''初始化目标检测模型'''
  204. model = Detector(dete_weights)
  205. names=['vehicle', 'TCorner', 'LCorner']
  206. t1=time.time()
  207. '''图像测试'''
  208. folders = os.listdir(args1['input_dir'])
  209. for i in range(len(folders)):
  210. path1 = args1['input_dir'] + '/' + folders[i]
  211. print('-'*100,path1)
  212. '''对原图进行目标检测'''
  213. pred, _img_cv=AI_process(model, args1,path1)
  214. H,W = _img_cv.shape[0:2]
  215. imgSize = (W,H);pars={'imgSize':imgSize}
  216. #preds = [[ names.index(x[4]),*x[0:4], float(x[5].cpu()) ] for x in pred[1]]
  217. preds = [[ *x[0:4], names.index(x[4]),float(x[5].cpu()) ] for x in pred[1]]
  218. # print('pred', pred)
  219. final_weiting,timeStr = illParking_postprocess(preds,None,pars)
  220. '''进入后处理,判断是否有违章停车'''
  221. #final_img,final_weiting=AI_postprocess(pred, _img_cv)
  222. #cv2.imwrite('./outdir/final_result'+str(i)+'.png', final_img)
  223. t2=time.time()
  224. print('耗时',t2-t1)
  225. if __name__ == "__main__":
  226. main()