detect_demo.py 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. import argparse
  2. import time
  3. import os
  4. import cv2
  5. import torch
  6. import copy
  7. import numpy as np
  8. from models.experimental import attempt_load
  9. from utils.datasets import letterbox
  10. from utils.general import check_img_size, non_max_suppression_face, scale_coords
  11. from utils.torch_utils import time_synchronized
  12. from plate_recognition.plate_rec import allFilePath,cv_imread
  13. clors = [(255,0,0),(0,255,0),(0,0,255),(255,255,0),(0,255,255)]
  14. def load_model(weights, device):
  15. model = attempt_load(weights, map_location=device) # load FP32 model
  16. return model
  17. def scale_coords_landmarks(img1_shape, coords, img0_shape, ratio_pad=None):
  18. # Rescale coords (xyxy) from img1_shape to img0_shape
  19. if ratio_pad is None: # calculate from img0_shape
  20. gain = min(img1_shape[0] / img0_shape[0], img1_shape[1] / img0_shape[1]) # gain = old / new
  21. pad = (img1_shape[1] - img0_shape[1] * gain) / 2, (img1_shape[0] - img0_shape[0] * gain) / 2 # wh padding
  22. else:
  23. gain = ratio_pad[0][0]
  24. pad = ratio_pad[1]
  25. coords[:, [0, 2, 4, 6]] -= pad[0] # x padding
  26. coords[:, [1, 3, 5, 7]] -= pad[1] # y padding
  27. coords[:, :10] /= gain
  28. #clip_coords(coords, img0_shape)
  29. coords[:, 0].clamp_(0, img0_shape[1]) # x1
  30. coords[:, 1].clamp_(0, img0_shape[0]) # y1
  31. coords[:, 2].clamp_(0, img0_shape[1]) # x2
  32. coords[:, 3].clamp_(0, img0_shape[0]) # y2
  33. coords[:, 4].clamp_(0, img0_shape[1]) # x3
  34. coords[:, 5].clamp_(0, img0_shape[0]) # y3
  35. coords[:, 6].clamp_(0, img0_shape[1]) # x4
  36. coords[:, 7].clamp_(0, img0_shape[0]) # y4
  37. # coords[:, 8].clamp_(0, img0_shape[1]) # x5
  38. # coords[:, 9].clamp_(0, img0_shape[0]) # y5
  39. return coords
  40. def get_plate_rec_landmark(img, xyxy, conf, landmarks, class_num,device):
  41. h,w,c = img.shape
  42. result_dict={}
  43. tl = 1 or round(0.002 * (h + w) / 2) + 1 # line/font thickness
  44. x1 = int(xyxy[0])
  45. y1 = int(xyxy[1])
  46. x2 = int(xyxy[2])
  47. y2 = int(xyxy[3])
  48. landmarks_np=np.zeros((4,2))
  49. rect=[x1,y1,x2,y2]
  50. for i in range(4):
  51. point_x = int(landmarks[2 * i])
  52. point_y = int(landmarks[2 * i + 1])
  53. landmarks_np[i]=np.array([point_x,point_y])
  54. class_label= int(class_num) #车牌的的类型0代表单牌,1代表双层车牌
  55. result_dict['rect']=rect
  56. result_dict['landmarks']=landmarks_np.tolist()
  57. result_dict['class']=class_label
  58. return result_dict
  59. def detect_plate(model, orgimg, device,img_size):
  60. # Load model
  61. # img_size = opt_img_size
  62. conf_thres = 0.3
  63. iou_thres = 0.5
  64. dict_list=[]
  65. # orgimg = cv2.imread(image_path) # BGR
  66. img0 = copy.deepcopy(orgimg)
  67. assert orgimg is not None, 'Image Not Found '
  68. h0, w0 = orgimg.shape[:2] # orig hw
  69. r = img_size / max(h0, w0) # resize image to img_size
  70. if r != 1: # always resize down, only resize up if training with augmentation
  71. interp = cv2.INTER_AREA if r < 1 else cv2.INTER_LINEAR
  72. img0 = cv2.resize(img0, (int(w0 * r), int(h0 * r)), interpolation=interp)
  73. imgsz = check_img_size(img_size, s=model.stride.max()) # check img_size
  74. img = letterbox(img0, new_shape=imgsz)[0]
  75. # img =process_data(img0)
  76. # Convert
  77. img = img[:, :, ::-1].transpose(2, 0, 1).copy() # BGR to RGB, to 3x416x416
  78. # Run inference
  79. t0 = time.time()
  80. img = torch.from_numpy(img).to(device)
  81. img = img.float() # uint8 to fp16/32
  82. img /= 255.0 # 0 - 255 to 0.0 - 1.0
  83. if img.ndimension() == 3:
  84. img = img.unsqueeze(0)
  85. # Inference
  86. t1 = time_synchronized()
  87. pred = model(img)[0]
  88. t2=time_synchronized()
  89. # print(f"infer time is {(t2-t1)*1000} ms")
  90. # Apply NMS
  91. pred = non_max_suppression_face(pred, conf_thres, iou_thres)
  92. # print('img.shape: ', img.shape)
  93. # print('orgimg.shape: ', orgimg.shape)
  94. # Process detections
  95. for i, det in enumerate(pred): # detections per image
  96. if len(det):
  97. # Rescale boxes from img_size to im0 size
  98. det[:, :4] = scale_coords(img.shape[2:], det[:, :4], orgimg.shape).round()
  99. # Print results
  100. for c in det[:, -1].unique():
  101. n = (det[:, -1] == c).sum() # detections per class
  102. det[:, 5:13] = scale_coords_landmarks(img.shape[2:], det[:, 5:13], orgimg.shape).round()
  103. for j in range(det.size()[0]):
  104. xyxy = det[j, :4].view(-1).tolist()
  105. conf = det[j, 4].cpu().numpy()
  106. landmarks = det[j, 5:13].view(-1).tolist()
  107. class_num = det[j, 13].cpu().numpy()
  108. result_dict = get_plate_rec_landmark(orgimg, xyxy, conf, landmarks, class_num,device)
  109. dict_list.append(result_dict)
  110. return dict_list
  111. # cv2.imwrite('result.jpg', orgimg)
  112. def draw_result(orgimg,dict_list):
  113. result_str =""
  114. for result in dict_list:
  115. rect_area = result['rect']
  116. x,y,w,h = rect_area[0],rect_area[1],rect_area[2]-rect_area[0],rect_area[3]-rect_area[1]
  117. padding_w = 0.05*w
  118. padding_h = 0.11*h
  119. rect_area[0]=max(0,int(x-padding_w))
  120. rect_area[1]=max(0,int(y-padding_h))
  121. rect_area[2]=min(orgimg.shape[1],int(rect_area[2]+padding_w))
  122. rect_area[3]=min(orgimg.shape[0],int(rect_area[3]+padding_h))
  123. landmarks=result['landmarks']
  124. label=result['class']
  125. # result_str+=result+" "
  126. for i in range(4): #关键点
  127. cv2.circle(orgimg, (int(landmarks[i][0]), int(landmarks[i][1])), 5, clors[i], -1)
  128. cv2.rectangle(orgimg,(rect_area[0],rect_area[1]),(rect_area[2],rect_area[3]),clors[label],2) #画框
  129. cv2.putText(img,str(label),(rect_area[0],rect_area[1]),cv2.FONT_HERSHEY_SIMPLEX,0.5,clors[label],2)
  130. # orgimg=cv2ImgAddText(orgimg,label,rect_area[0]-height_area,rect_area[1]-height_area-10,(0,255,0),height_area)
  131. # print(result_str)
  132. return orgimg
  133. if __name__ == '__main__':
  134. parser = argparse.ArgumentParser()
  135. parser.add_argument('--detect_model', nargs='+', type=str, default='runs/train/exp32/weights/last.pt', help='model.pt path(s)') #检测模型
  136. parser.add_argument('--image_path', type=str, default='/mnt/Gpan/Mydata/pytorchPorject/datasets/ccpd/train_detect/gangao', help='source')
  137. parser.add_argument('--img_size', type=int, default=640, help='inference size (pixels)')
  138. parser.add_argument('--output', type=str, default='result1', help='source')
  139. device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
  140. opt = parser.parse_args()
  141. print(opt)
  142. save_path = opt.output
  143. count=0
  144. if not os.path.exists(save_path):
  145. os.mkdir(save_path)
  146. detect_model = load_model(opt.detect_model, device) #初始化检测模型
  147. time_all = 0
  148. time_begin=time.time()
  149. if not os.path.isfile(opt.image_path): #目录
  150. file_list=[]
  151. allFilePath(opt.image_path,file_list)
  152. for img_path in file_list:
  153. print(count,img_path)
  154. time_b = time.time()
  155. img =cv_imread(img_path)
  156. if img is None:
  157. continue
  158. if img.shape[-1]==4:
  159. img=cv2.cvtColor(img,cv2.COLOR_BGRA2BGR)
  160. # detect_one(model,img_path,device)
  161. dict_list=detect_plate(detect_model, img, device,opt.img_size)
  162. ori_img=draw_result(img,dict_list)
  163. img_name = os.path.basename(img_path)
  164. save_img_path = os.path.join(save_path,img_name)
  165. time_e=time.time()
  166. time_gap = time_e-time_b
  167. if count:
  168. time_all+=time_gap
  169. cv2.imwrite(save_img_path,ori_img)
  170. count+=1
  171. else: #单个图片
  172. print(count,opt.image_path,end=" ")
  173. img =cv_imread(opt.image_path)
  174. if img.shape[-1]==4:
  175. img=cv2.cvtColor(img,cv2.COLOR_BGRA2BGR)
  176. # detect_one(model,img_path,device)
  177. dict_list=detect_plate(detect_model, img, device,opt.img_size)
  178. ori_img=draw_result(img,dict_list)
  179. img_name = os.path.basename(opt.image_path)
  180. save_img_path = os.path.join(save_path,img_name)
  181. cv2.imwrite(save_img_path,ori_img)
  182. print(f"sumTime time is {time.time()-time_begin} s, average pic time is {time_all/(len(file_list)-1)}")