Skip to content

Commit

Permalink
修改截图+FOV
Browse files Browse the repository at this point in the history
  • Loading branch information
chiaki-1999 committed Apr 13, 2023
1 parent 223669e commit ed6d019
Show file tree
Hide file tree
Showing 27 changed files with 2,866 additions and 760 deletions.
10 changes: 0 additions & 10 deletions SetUI.py → FirstUI.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,3 @@
# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'Apex1.5.ui'
#
# Created by: PyQt5 UI code generator 5.15.9
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.


from PyQt5 import QtCore, QtGui, QtWidgets


Expand Down
343 changes: 193 additions & 150 deletions ShowUI.py → SecondUI.py

Large diffs are not rendered by default.

133 changes: 101 additions & 32 deletions export.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,44 @@
# YOLOv5 🚀 by Ultralytics, GPL-3.0 license
"""
Export a YOLOv5 PyTorch model to other formats. TensorFlow exports authored by https://github.com/zldrobit
Format | `export.py --include` | Model
--- | --- | ---
PyTorch | - | yolov5s.pt
TorchScript | `torchscript` | yolov5s.torchscript
ONNX | `onnx` | yolov5s.onnx
OpenVINO | `openvino` | yolov5s_openvino_model/
TensorRT | `engine` | yolov5s.engine
CoreML | `coreml` | yolov5s.mlmodel
TensorFlow SavedModel | `saved_model` | yolov5s_saved_model/
TensorFlow GraphDef | `pb` | yolov5s.pb
TensorFlow Lite | `tflite` | yolov5s.tflite
TensorFlow Edge TPU | `edgetpu` | yolov5s_edgetpu.tflite
TensorFlow.js | `tfjs` | yolov5s_web_model/
PaddlePaddle | `paddle` | yolov5s_paddle_model/
Requirements:
$ pip install -r requirements.txt coremltools onnx onnx-simplifier onnxruntime openvino-dev tensorflow-cpu # CPU
$ pip install -r requirements.txt coremltools onnx onnx-simplifier onnxruntime-gpu openvino-dev tensorflow # GPU
Usage:
$ python export.py --weights yolov5s.pt --include torchscript onnx openvino engine coreml tflite ...
Inference:
$ python detect.py --weights yolov5s.pt # PyTorch
yolov5s.torchscript # TorchScript
yolov5s.onnx # ONNX Runtime or OpenCV DNN with --dnn
yolov5s_openvino_model # OpenVINO
yolov5s.engine # TensorRT
yolov5s.mlmodel # CoreML (macOS-only)
yolov5s_saved_model # TensorFlow SavedModel
yolov5s.pb # TensorFlow GraphDef
yolov5s.tflite # TensorFlow Lite
yolov5s_edgetpu.tflite # TensorFlow Edge TPU
yolov5s_paddle_model # PaddlePaddle
TensorFlow.js:
$ cd .. && git clone https://github.com/zldrobit/tfjs-yolov5-example.git && cd tfjs-yolov5-example
$ npm install
$ ln -s ../../yolov5/yolov5s_web_model public/yolov5s_web_model
$ npm start
"""

import argparse
import contextlib
import json
Expand All @@ -12,14 +53,6 @@

import pandas as pd
import torch
from torch.utils.mobile_optimizer import optimize_for_mobile

from models.experimental import attempt_load
from models.yolo import ClassificationModel, Detect, DetectionModel, SegmentationModel
from utils.dataloaders import LoadImages
from utils.general import (LOGGER, Profile, check_dataset, check_img_size, check_requirements, check_version,
check_yaml, colorstr, file_size, get_default_args, print_args, url2file, yaml_save)
from utils.torch_utils import select_device, smart_inference_mode

FILE = Path(__file__).resolve()
ROOT = FILE.parents[0] # YOLOv5 root directory
Expand All @@ -28,6 +61,13 @@
if platform.system() != 'Windows':
ROOT = Path(os.path.relpath(ROOT, Path.cwd())) # relative

from models.experimental import attempt_load
from models.yolo import ClassificationModel, Detect, DetectionModel, SegmentationModel
from utils.dataloaders import LoadImages
from utils.general import (LOGGER, Profile, check_dataset, check_img_size, check_requirements, check_version,
check_yaml, colorstr, file_size, get_default_args, print_args, url2file, yaml_save)
from utils.torch_utils import select_device, smart_inference_mode

MACOS = platform.system() == 'Darwin' # macOS environment


Expand Down Expand Up @@ -74,7 +114,7 @@ def export_torchscript(model, im, file, optimize, prefix=colorstr('TorchScript:'
f = file.with_suffix('.torchscript')

ts = torch.jit.trace(model, im, strict=False)
d = {"shape": im.shape, "stride": int(max(model.stride)), "names": model.names}
d = {'shape': im.shape, 'stride': int(max(model.stride)), 'names': model.names}
extra_files = {'config.txt': json.dumps(d)} # torch._C.ExtraFilesMap()
if optimize: # https://pytorch.org/tutorials/recipes/mobile_interpreter.html
optimize_for_mobile(ts)._save_for_lite_interpreter(str(f), _extra_files=extra_files)
Expand All @@ -86,7 +126,7 @@ def export_torchscript(model, im, file, optimize, prefix=colorstr('TorchScript:'
@try_export
def export_onnx(model, im, file, opset, dynamic, simplify, prefix=colorstr('ONNX:')):
# YOLOv5 ONNX export
check_requirements('onnx')
check_requirements('onnx>=1.12.0')
import onnx

LOGGER.info(f'\n{prefix} starting export with onnx {onnx.__version__}...')
Expand All @@ -107,7 +147,7 @@ def export_onnx(model, im, file, opset, dynamic, simplify, prefix=colorstr('ONNX
f,
verbose=False,
opset_version=opset,
do_constant_folding=True,
do_constant_folding=True, # WARNING: DNN inference with torch>=1.12 may require do_constant_folding=False
input_names=['images'],
output_names=output_names,
dynamic_axes=dynamic or None)
Expand Down Expand Up @@ -148,8 +188,15 @@ def export_openvino(file, metadata, half, prefix=colorstr('OpenVINO:')):
LOGGER.info(f'\n{prefix} starting export with openvino {ie.__version__}...')
f = str(file).replace('.pt', f'_openvino_model{os.sep}')

cmd = f"mo --input_model {file.with_suffix('.onnx')} --output_dir {f} --data_type {'FP16' if half else 'FP32'}"
subprocess.run(cmd.split(), check=True, env=os.environ) # export
args = [
'mo',
'--input_model',
str(file.with_suffix('.onnx')),
'--output_dir',
f,
'--data_type',
('FP16' if half else 'FP32'), ]
subprocess.run(args, check=True, env=os.environ) # export
yaml_save(Path(f) / file.with_suffix('.yaml').name, metadata) # add metadata.yaml
return f, None

Expand Down Expand Up @@ -184,7 +231,7 @@ def export_coreml(model, im, file, int8, half, prefix=colorstr('CoreML:')):
if bits < 32:
if MACOS: # quantization only supported on macOS
with warnings.catch_warnings():
warnings.filterwarnings("ignore", category=DeprecationWarning) # suppress numpy==1.20 float warning
warnings.filterwarnings('ignore', category=DeprecationWarning) # suppress numpy==1.20 float warning
ct_model = ct.models.neural_network.quantization_utils.quantize_weights(ct_model, bits, mode)
else:
print(f'{prefix} quantization only supported on macOS, skipping...')
Expand Down Expand Up @@ -240,7 +287,7 @@ def export_engine(model, im, file, half, dynamic, simplify, workspace=4, verbose

if dynamic:
if im.shape[0] <= 1:
LOGGER.warning(f"{prefix} WARNING ⚠️ --dynamic model requires maximum --batch-size argument")
LOGGER.warning(f'{prefix} WARNING ⚠️ --dynamic model requires maximum --batch-size argument')
profile = builder.create_optimization_profile()
for inp in inputs:
profile.set_shape(inp.name, (1, *im.shape[1:]), (max(1, im.shape[0] // 2), *im.shape[1:]), im.shape)
Expand Down Expand Up @@ -350,7 +397,7 @@ def export_tflite(keras_model, im, file, int8, data, nms, agnostic_nms, prefix=c
converter.target_spec.supported_ops.append(tf.lite.OpsSet.SELECT_TF_OPS)

tflite_model = converter.convert()
open(f, "wb").write(tflite_model)
open(f, 'wb').write(tflite_model)
return f, None


Expand All @@ -360,7 +407,7 @@ def export_edgetpu(file, prefix=colorstr('Edge TPU:')):
cmd = 'edgetpu_compiler --version'
help_url = 'https://coral.ai/docs/edgetpu/compiler/'
assert platform.system() == 'Linux', f'export only supported on Linux. See {help_url}'
if subprocess.run(f'{cmd} >/dev/null', shell=True).returncode != 0:
if subprocess.run(f'{cmd} > /dev/null 2>&1', shell=True).returncode != 0:
LOGGER.info(f'\n{prefix} export requires Edge TPU compiler. Attempting install from {help_url}')
sudo = subprocess.run('sudo --version >/dev/null', shell=True).returncode == 0 # sudo installed on system
for c in (
Expand All @@ -374,13 +421,20 @@ def export_edgetpu(file, prefix=colorstr('Edge TPU:')):
f = str(file).replace('.pt', '-int8_edgetpu.tflite') # Edge TPU model
f_tfl = str(file).replace('.pt', '-int8.tflite') # TFLite model

cmd = f"edgetpu_compiler -s -d -k 10 --out_dir {file.parent} {f_tfl}"
subprocess.run(cmd.split(), check=True)
subprocess.run([
'edgetpu_compiler',
'-s',
'-d',
'-k',
'10',
'--out_dir',
str(file.parent),
f_tfl, ], check=True)
return f, None


@try_export
def export_tfjs(file, prefix=colorstr('TensorFlow.js:')):
def export_tfjs(file, int8, prefix=colorstr('TensorFlow.js:')):
# YOLOv5 TensorFlow.js export
check_requirements('tensorflowjs')
import tensorflowjs as tfjs
Expand All @@ -390,9 +444,14 @@ def export_tfjs(file, prefix=colorstr('TensorFlow.js:')):
f_pb = file.with_suffix('.pb') # *.pb path
f_json = f'{f}/model.json' # *.json path

cmd = f'tensorflowjs_converter --input_format=tf_frozen_model ' \
f'--output_node_names=Identity,Identity_1,Identity_2,Identity_3 {f_pb} {f}'
subprocess.run(cmd.split())
args = [
'tensorflowjs_converter',
'--input_format=tf_frozen_model',
'--quantize_uint8' if int8 else '',
'--output_node_names=Identity,Identity_1,Identity_2,Identity_3',
str(f_pb),
str(f), ]
subprocess.run([arg for arg in args if arg], check=True)

json = Path(f_json).read_text()
with open(f_json, 'w') as j: # sort JSON Identity_* in ascending order
Expand Down Expand Up @@ -447,7 +506,7 @@ def run(
weights=ROOT / 'yolov5s.pt', # weights path
imgsz=(640, 640), # image (height, width)
batch_size=1, # batch size
device='0', # cuda device, i.e. 0 or 0,1,2,3 or cpu
device='cpu', # cuda device, i.e. 0 or 0,1,2,3 or cpu
include=('torchscript', 'onnx'), # include formats
half=False, # FP16 half-precision export
inplace=False, # set YOLOv5 Detect() inplace=True
Expand All @@ -466,7 +525,6 @@ def run(
iou_thres=0.45, # TF.js NMS: IoU threshold
conf_thres=0.25, # TF.js NMS: confidence threshold
):
global y
t = time.time()
include = [x.lower() for x in include] # to lowercase
fmts = tuple(export_formats()['Argument'][1:]) # --include arguments
Expand Down Expand Up @@ -543,28 +601,29 @@ def run(
f[8], _ = export_edgetpu(file)
add_tflite_metadata(f[8] or f[7], metadata, num_outputs=len(s_model.outputs))
if tfjs:
f[9], _ = export_tfjs(file)
f[9], _ = export_tfjs(file, int8)
if paddle: # PaddlePaddle
f[10], _ = export_paddle(model, im, file, metadata)

# Finish
f = [str(x) for x in f if x] # filter out '' and None
if any(f):
cls, det, seg = (isinstance(model, x) for x in (ClassificationModel, DetectionModel, SegmentationModel)) # type
det &= not seg # segmentation models inherit from SegmentationModel(DetectionModel)
dir = Path('segment' if seg else 'classify' if cls else '')
h = '--half' if half else '' # --half FP16 inference arg
s = "# WARNING ⚠️ ClassificationModel not yet supported for PyTorch Hub AutoShape inference" if cls else \
"# WARNING ⚠️ SegmentationModel not yet supported for PyTorch Hub AutoShape inference" if seg else ''
s = '# WARNING ⚠️ ClassificationModel not yet supported for PyTorch Hub AutoShape inference' if cls else \
'# WARNING ⚠️ SegmentationModel not yet supported for PyTorch Hub AutoShape inference' if seg else ''
LOGGER.info(f'\nExport complete ({time.time() - t:.1f}s)'
f"\nResults saved to {colorstr('bold', file.parent.resolve())}"
f"\nDetect: python {dir / ('detect.py' if det else 'predict.py')} --weights {f[-1]} {h}"
f"\nValidate: python {dir / 'val.py'} --weights {f[-1]} {h}"
f"\nPyTorch Hub: model = torch.hub.load('ultralytics/yolov5', 'custom', '{f[-1]}') {s}"
f"\nVisualize: https://netron.app")
f'\nVisualize: https://netron.app')
return f # return list of exported files/dirs


def parse_opt():
def parse_opt(known=False):
parser = argparse.ArgumentParser()
parser.add_argument('--data', type=str, default=ROOT / 'data/coco128.yaml', help='dataset.yaml path')
parser.add_argument('--weights', nargs='+', type=str, default=ROOT / 'yolov5s.pt', help='model.pt path(s)')
Expand All @@ -578,7 +637,7 @@ def parse_opt():
parser.add_argument('--int8', action='store_true', help='CoreML/TF INT8 quantization')
parser.add_argument('--dynamic', action='store_true', help='ONNX/TF/TensorRT: dynamic axes')
parser.add_argument('--simplify', action='store_true', help='ONNX: simplify model')
parser.add_argument('--opset', type=int, default=12, help='ONNX: opset version')
parser.add_argument('--opset', type=int, default=17, help='ONNX: opset version')
parser.add_argument('--verbose', action='store_true', help='TensorRT: verbose log')
parser.add_argument('--workspace', type=int, default=4, help='TensorRT: workspace size (GB)')
parser.add_argument('--nms', action='store_true', help='TF: add NMS to model')
Expand All @@ -592,6 +651,16 @@ def parse_opt():
nargs='+',
default=['torchscript'],
help='torchscript, onnx, openvino, engine, coreml, saved_model, pb, tflite, edgetpu, tfjs, paddle')
opt = parser.parse_args()
opt = parser.parse_known_args()[0] if known else parser.parse_args()
print_args(vars(opt))
return opt


def main(opt):
for opt.weights in (opt.weights if isinstance(opt.weights, list) else [opt.weights]):
run(**vars(opt))


if __name__ == '__main__':
opt = parse_opt()
main(opt)
33 changes: 17 additions & 16 deletions function/detect_object.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,39 +3,40 @@
import sys
from pathlib import Path

import cv2
import numpy as np
import torch

from models.common import DetectMultiBackend
from utils.augmentations import (letterbox)
from utils.general import (Profile, cv2,
non_max_suppression, scale_boxes, xyxy2xywh)
from utils.general import (non_max_suppression, scale_boxes, xyxy2xywh)
from utils.torch_utils import select_device


def load_model():
global weights
model_trt = TRTModule()
model_trt.load_state_dict(torch.load(weights))
device = select_device('cuda:0')
model_trt = model_trt.to(device)
model_trt.half()
return model_trt
def load_model(img_size):
device = select_device('')
model = DetectMultiBackend(weights, device=device, dnn=False, data=data, fp16=True)
model.warmup(imgsz=(1, 3, *[img_size, img_size])) # warmup
return model


def interface_img(img, model):
stride, names = model.stride, model.names
h, w = img.shape[:2]
img = cv2.resize(img, (w, h), interpolation=cv2.INTER_LINEAR)

im = letterbox(img, 416, stride=stride, auto=True)[0]
im = im.transpose((2, 0, 1))[::-1]
im = np.ascontiguousarray(im)
im = torch.tensor(im).to(model.device, dtype=torch.float16)

im = torch.from_numpy(im).to(model.device)
im = im.half() if model.fp16 else im.float()
im = im.div(255.0).clamp(0.0, 1.0) # 使用 .div() 方法进行除法操作,并使用 .clamp() 方法限制数据范围在 [0, 1] 之间
if len(im.shape) == 3:
im = im.unsqueeze(0)
im = im[None]

with torch.no_grad():
pred = model(im, augment=False, visualize=False)
pred = pred.float()
pred = non_max_suppression(pred, conf_thres, iou_thres, max_det=max_det)

box_list = []
Expand All @@ -44,7 +45,7 @@ def interface_img(img, model):
if len(det):
det[:, :4] = scale_boxes(im.shape[2:], det[:, :4], img.shape).round()
for *xyxy, conf, cls in reversed(det):
xywh = ((torch.tensor(xyxy).float() + 0.5).int() / gn).tolist()
xywh = (xyxy2xywh(torch.tensor(xyxy).view(1, 4)) / gn).view(-1).tolist()
line = (names[int(cls)], *xywh)
if 0.1 < (xywh[2] / xywh[3]) < 0.9 and xywh[3] < 0.8:
box_list.append(line)
Expand All @@ -57,8 +58,8 @@ def interface_img(img, model):
sys.path.append(str(ROOT))
info_dir = os.path.join(ROOT, 'information.csv')

conf_thres = 0.5
iou_thres = 0.5
conf_thres = 0.55
iou_thres = 0.45
max_det = 1000

with open(info_dir, 'r', encoding='utf-8', newline='') as fr:
Expand Down
Loading

0 comments on commit ed6d019

Please sign in to comment.