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.

illParkingUtils.py 9.9KB

1 year ago
1 year ago
1 year ago
10 months ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  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 illParking_postprocess_N(predList,pars):
  185. pred=predList[0]
  186. cvMask=None
  187. return illParking_postprocess(pred,cvMask,pars)
  188. def AI_process(model, args1,path1):
  189. '''对原图进行目标检测'''
  190. '''输入:检测模型、配置参数、路径
  191. 返回:返回目标检测结果、原图像,
  192. '''
  193. '''检测图片'''
  194. t3=time.time()
  195. _img_cv = cv2.imread(path1) # 将这里的送入yolov5
  196. t4 = time.time()
  197. pred = model.detect(_img_cv) # 检测结果
  198. t5 = time.time()
  199. #print('t5-t4', t5-t4)
  200. #print('t4-t3', t4-t3)
  201. return pred, _img_cv #返回目标检测结果、原图像
  202. def main():
  203. '''配置参数'''
  204. args1={'cuda':'0','input_dir':'input_dir','output_dir':'output_dir'}
  205. dete_weights='weights/weiting20230727.pt'
  206. '''分割模型权重路径'''
  207. '''初始化目标检测模型'''
  208. model = Detector(dete_weights)
  209. names=['vehicle', 'TCorner', 'LCorner']
  210. t1=time.time()
  211. '''图像测试'''
  212. folders = os.listdir(args1['input_dir'])
  213. for i in range(len(folders)):
  214. path1 = args1['input_dir'] + '/' + folders[i]
  215. print('-'*100,path1)
  216. '''对原图进行目标检测'''
  217. pred, _img_cv=AI_process(model, args1,path1)
  218. H,W = _img_cv.shape[0:2]
  219. imgSize = (W,H);pars={'imgSize':imgSize}
  220. #preds = [[ names.index(x[4]),*x[0:4], float(x[5].cpu()) ] for x in pred[1]]
  221. preds = [[ *x[0:4], names.index(x[4]),float(x[5].cpu()) ] for x in pred[1]]
  222. # print('pred', pred)
  223. final_weiting,timeStr = illParking_postprocess(preds,None,pars)
  224. '''进入后处理,判断是否有违章停车'''
  225. #final_img,final_weiting=AI_postprocess(pred, _img_cv)
  226. #cv2.imwrite('./outdir/final_result'+str(i)+'.png', final_img)
  227. t2=time.time()
  228. print('耗时',t2-t1)
  229. if __name__ == "__main__":
  230. main()