text: # -*- coding: UTF-8 -*-
  import argparse
  import time
  from pathlib import Path
  
  import cv2
  import torch
  import torch.backends.cudnn as cudnn
  from numpy import random
  import copy
  
  from models.experimental import attempt_load
  from utils.datasets import letterbox
  from utils.general import check_img_size, non_max_suppression_plate, apply_classifier, scale_coords, xyxy2xywh, \
      strip_optimizer, set_logging, increment_path
  from utils.plots import plot_one_box
  from utils.torch_utils import select_device, load_classifier, time_synchronized
  import os
  
  
  cv2.namedWindow("img", 0);
  cv2.resizeWindow("img", 1280,720);
  
  def load_model(weights, device):
      model = attempt_load(weights, map_location=device)  # load FP32 model
      return model
  
  
  def scale_coords_landmarks(img1_shape, coords, img0_shape, ratio_pad=None):
      # Rescale coords (xyxy) from img1_shape to img0_shape
      if ratio_pad is None:  # calculate from img0_shape
          gain = min(img1_shape[0] / img0_shape[0], img1_shape[1] / img0_shape[1])  # gain  = old / new
          pad = (img1_shape[1] - img0_shape[1] * gain) / 2, (img1_shape[0] - img0_shape[0] * gain) / 2  # wh padding
      else:
          gain = ratio_pad[0][0]
          pad = ratio_pad[1]
  
      coords[:, [0, 2, 4, 6]] -= pad[0]  # x padding
      coords[:, [1, 3, 5, 7]] -= pad[1]  # y padding
      coords[:, :8] /= gain
      #clip_coords(coords, img0_shape)
      coords[:, 0].clamp_(0, img0_shape[1])  # x1
      coords[:, 1].clamp_(0, img0_shape[0])  # y1
      coords[:, 2].clamp_(0, img0_shape[1])  # x2
      coords[:, 3].clamp_(0, img0_shape[0])  # y2
      coords[:, 4].clamp_(0, img0_shape[1])  # x3
      coords[:, 5].clamp_(0, img0_shape[0])  # y3
      coords[:, 6].clamp_(0, img0_shape[1])  # x4
      coords[:, 7].clamp_(0, img0_shape[0])  # y4
  
      return coords
  
  def show_results(img, xywh, conf, landmarks, class_num):
      h,w,c = img.shape
      #tl = 1 or round(0.002 * (h + w) / 2) + 1  # line/font thickness
      x1 = int(xywh[0] * w - 0.5 * xywh[2] * w)
      y1 = int(xywh[1] * h - 0.5 * xywh[3] * h)
      x2 = int(xywh[0] * w + 0.5 * xywh[2] * w)
      y2 = int(xywh[1] * h + 0.5 * xywh[3] * h)
      cv2.rectangle(img, (x1,y1), (x2, y2), (0,255,0), thickness=3, lineType=cv2.LINE_AA)
  
      clors = [(255,0,0),(0,255,0),(0,0,255),(255,255,0),(0,255,255)]
  
      for i in range(4):
          point_x = int(landmarks[2 * i] * w)
          point_y = int(landmarks[2 * i + 1] * h)
          cv2.circle(img, (point_x, point_y), 3, clors[i], -1)
  
      label = str(conf)[:5]
      return img
  
  
  
  def detect_one(model, image_path, device):
      # Load model
      img_size = 800
      conf_thres = 0.3
      iou_thres = 0.5
  
      orgimg = cv2.imread(image_path)  # BGR
      sp = orgimg.shape
      h = sp[0]
      w = sp[1]
      #img_size = h
      print(w,h)
      img0 = copy.deepcopy(orgimg)
      assert orgimg is not None, 'Image Not Found ' + image_path
      h0, w0 = orgimg.shape[:2]  # orig hw
      r = img_size / max(h0, w0)  # resize image to img_size
      if r != 1:  # always resize down, only resize up if training with augmentation
          interp = cv2.INTER_AREA if r < 1  else cv2.INTER_LINEAR
          img0 = cv2.resize(img0, (int(w0 * r), int(h0 * r)), interpolation=interp)
  
      imgsz = check_img_size(img_size, s=model.stride.max())  # check img_size
  
      img = letterbox(img0, new_shape=imgsz)[0]
      # Convert
      img = img[:, :, ::-1].transpose(2, 0, 1).copy()  # BGR to RGB, to 3x416x416
  
      # Run inference
      t0 = time.time()
  
      img = torch.from_numpy(img).to(device)
      img = img.float()  # uint8 to fp16/32
      img /= 255.0  # 0 - 255 to 0.0 - 1.0
      if img.ndimension() == 3:
          img = img.unsqueeze(0)
  
      # Inference
      t1 = time_synchronized()
      pred = model(img)[0]
  
      # Apply NMS
      pred = non_max_suppression_plate(pred, conf_thres, iou_thres)
  
      print('img.shape: ', img.shape)
      print('orgimg.shape: ', orgimg.shape)
  
      # Process detections
      for i, det in enumerate(pred):  # detections per image
          gn = torch.tensor(orgimg.shape)[[1, 0, 1, 0]].to(device)  # normalization gain whwh
          gn_lks = torch.tensor(orgimg.shape)[[1, 0, 1, 0, 1, 0, 1, 0]].to(device)  # normalization gain landmarks
          if len(det):
              # Rescale boxes from img_size to im0 size
              det[:, :4] = scale_coords(img.shape[2:], det[:, :4], orgimg.shape).round()
  
              # Print results
              for c in det[:, -1].unique():
                  n = (det[:, -1] == c).sum()  # detections per class
  
              det[:, 5:13] = scale_coords_landmarks(img.shape[2:], det[:, 5:13], orgimg.shape).round()
  
              for j in range(det.size()[0]):
                  xywh = (xyxy2xywh(det[j, :4].view(1, 4)) / gn).view(-1).tolist()
                  conf = det[j, 4].cpu().numpy()
                  landmarks = (det[j, 5:13].view(1, 8) / gn_lks).view(-1).tolist()
                  class_num = det[j, 13].cpu().numpy()
                  orgimg = show_results(orgimg, xywh, conf, landmarks, class_num)
     
      cv2.imshow("img",orgimg)
      cv2.waitKey(0)
  
  def show_files(path, all_files):
      # 首先遍历当前目录所有文件及文件夹
      file_list = os.listdir(path)
      # 准备循环判断每个元素是否是文件夹还是文件，是文件的话，把名称传入list，是文件夹的话，递归
      for file in file_list:
          # 利用os.path.join()方法取得路径全名，并存入cur_path变量，否则每次只能遍历一层目录
          cur_path = os.path.join(path, file)
          # 判断是否是文件夹
          if os.path.isdir(cur_path):
              show_files(cur_path, all_files)
          else:
              if not cur_path.endswith(('jpg')):
                  continue
              else:
                  all_files.append(cur_path )
  
      return all_files
  
  f = show_files("imgs", [])
  
  
  if __name__ == '__main__':
      parser = argparse.ArgumentParser()
      parser.add_argument('--weights', nargs='+', type=str, default='weights/best.pt', help='model.pt path(s)')
      parser.add_argument('--image', type=str, default='data/images/test.jpg', help='source')  # file/folder, 0 for webcam
      parser.add_argument('--img-size', type=int, default=640, help='inference size (pixels)')
      opt = parser.parse_args()
      print(opt)
      device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
      model = load_model(opt.weights, device)
  
      for filename in f:
          
          print(filename)
          detect_one(model, filename, device)
  