2024-06-09 04:29:29 +08:00
# Ultralytics YOLOv5 🚀, AGPL-3.0 license
2021-08-15 03:17:51 +08:00
"""
2022-08-23 23:54:51 +08:00
Run YOLOv5 detection inference on images , videos , directories , globs , YouTube , webcam , streams , etc .
2021-06-21 23:25:04 +08:00
2022-01-03 08:09:45 +08:00
Usage - sources :
2022-08-22 07:06:29 +08:00
$ python detect . py - - weights yolov5s . pt - - source 0 # webcam
img . jpg # image
vid . mp4 # video
2022-11-19 06:48:47 +08:00
screen # screenshot
2022-08-22 07:06:29 +08:00
path / # directory
2022-12-04 06:58:58 +08:00
list . txt # list of images
list . streams # list of streams
2022-08-22 07:06:29 +08:00
' path/*.jpg ' # glob
2023-09-10 10:59:27 +08:00
' https://youtu.be/LNwODJXcvt4 ' # YouTube
2022-08-22 07:06:29 +08:00
' rtsp://example.com/media.mp4 ' # RTSP, RTMP, HTTP stream
2022-01-03 08:09:45 +08:00
Usage - formats :
2022-08-22 07:06:29 +08:00
$ python detect . py - - weights yolov5s . pt # PyTorch
yolov5s . torchscript # TorchScript
yolov5s . onnx # ONNX Runtime or OpenCV DNN with --dnn
2022-10-21 01:54:07 +08:00
yolov5s_openvino_model # OpenVINO
2022-08-22 07:06:29 +08:00
yolov5s . engine # TensorRT
2024-07-29 08:09:57 +08:00
yolov5s . mlpackage # CoreML (macOS-only)
2022-08-22 07:06:29 +08:00
yolov5s_saved_model # TensorFlow SavedModel
yolov5s . pb # TensorFlow GraphDef
yolov5s . tflite # TensorFlow Lite
yolov5s_edgetpu . tflite # TensorFlow Edge TPU
2022-09-10 18:25:01 +08:00
yolov5s_paddle_model # PaddlePaddle
2021-06-21 23:25:04 +08:00
"""
2020-05-30 08:04:54 +08:00
import argparse
2023-09-04 18:52:33 +08:00
import csv
2021-10-12 00:47:24 +08:00
import os
2022-07-25 19:57:05 +08:00
import platform
2021-06-21 23:25:04 +08:00
import sys
2020-08-03 06:47:36 +08:00
from pathlib import Path
2020-05-30 08:04:54 +08:00
2020-08-03 06:47:36 +08:00
import torch
2020-06-17 09:56:26 +08:00
2021-09-12 04:46:33 +08:00
FILE = Path ( __file__ ) . resolve ( )
2021-09-18 21:02:08 +08:00
ROOT = FILE . parents [ 0 ] # YOLOv5 root directory
if str ( ROOT ) not in sys . path :
sys . path . append ( str ( ROOT ) ) # add ROOT to PATH
2021-10-12 00:47:24 +08:00
ROOT = Path ( os . path . relpath ( ROOT , Path . cwd ( ) ) ) # relative
2021-06-21 23:25:04 +08:00
2023-08-02 02:56:35 +08:00
from ultralytics . utils . plotting import Annotator , colors , save_one_box
2021-11-09 23:45:02 +08:00
from models . common import DetectMultiBackend
2022-09-23 05:58:14 +08:00
from utils . dataloaders import IMG_FORMATS , VID_FORMATS , LoadImages , LoadScreenshots , LoadStreams
2024-01-08 08:29:14 +08:00
from utils . general import (
LOGGER ,
Profile ,
check_file ,
check_img_size ,
check_imshow ,
check_requirements ,
colorstr ,
cv2 ,
increment_path ,
non_max_suppression ,
print_args ,
scale_boxes ,
strip_optimizer ,
xyxy2xywh ,
)
2022-08-19 01:55:38 +08:00
from utils . torch_utils import select_device , smart_inference_mode
2020-05-30 08:04:54 +08:00
2022-08-14 02:38:51 +08:00
@smart_inference_mode ( )
2022-03-31 22:52:34 +08:00
def run (
2024-01-08 08:29:14 +08:00
weights = ROOT / " yolov5s.pt " , # model path or triton URL
source = ROOT / " data/images " , # file/dir/URL/glob/screen/0(webcam)
data = ROOT / " data/coco128.yaml " , # dataset.yaml path
imgsz = ( 640 , 640 ) , # inference size (height, width)
conf_thres = 0.25 , # confidence threshold
iou_thres = 0.45 , # NMS IOU threshold
max_det = 1000 , # maximum detections per image
device = " " , # cuda device, i.e. 0 or 0,1,2,3 or cpu
view_img = False , # show results
save_txt = False , # save results to *.txt
2024-08-22 17:24:47 +08:00
save_format = 0 , # save boxes coordinates in YOLO format or Pascal-VOC format (0 for YOLO and 1 for Pascal-VOC)
2024-01-08 08:29:14 +08:00
save_csv = False , # save results in CSV format
save_conf = False , # save confidences in --save-txt labels
save_crop = False , # save cropped prediction boxes
nosave = False , # do not save images/videos
classes = None , # filter by class: --class 0, or --class 0 2 3
agnostic_nms = False , # class-agnostic NMS
augment = False , # augmented inference
visualize = False , # visualize features
update = False , # update all models
project = ROOT / " runs/detect " , # save results to project/name
name = " exp " , # save results to project/name
exist_ok = False , # existing project/name ok, do not increment
line_thickness = 3 , # bounding box thickness (pixels)
hide_labels = False , # hide labels
hide_conf = False , # hide confidences
half = False , # use FP16 half-precision inference
dnn = False , # use OpenCV DNN for ONNX inference
vid_stride = 1 , # video frame-rate stride
2022-03-31 22:52:34 +08:00
) :
2024-07-09 03:19:04 +08:00
"""
Runs YOLOv5 detection inference on various sources like images , videos , directories , streams , etc .
Args :
2024-07-09 04:05:56 +08:00
weights ( str | Path ) : Path to the model weights file or a Triton URL . Default is ' yolov5s.pt ' .
2024-07-16 07:20:57 +08:00
source ( str | Path ) : Input source , which can be a file , directory , URL , glob pattern , screen capture , or webcam
index . Default is ' data/images ' .
2024-07-09 04:05:56 +08:00
data ( str | Path ) : Path to the dataset YAML file . Default is ' data/coco128.yaml ' .
imgsz ( tuple [ int , int ] ) : Inference image size as a tuple ( height , width ) . Default is ( 640 , 640 ) .
conf_thres ( float ) : Confidence threshold for detections . Default is 0.25 .
iou_thres ( float ) : Intersection Over Union ( IOU ) threshold for non - max suppression . Default is 0.45 .
max_det ( int ) : Maximum number of detections per image . Default is 1000.
2024-07-16 07:20:57 +08:00
device ( str ) : CUDA device identifier ( e . g . , ' 0 ' or ' 0,1,2,3 ' ) or ' cpu ' . Default is an empty string , which uses the
best available device .
2024-07-09 04:05:56 +08:00
view_img ( bool ) : If True , display inference results using OpenCV . Default is False .
save_txt ( bool ) : If True , save results in a text file . Default is False .
save_csv ( bool ) : If True , save results in a CSV file . Default is False .
save_conf ( bool ) : If True , include confidence scores in the saved results . Default is False .
save_crop ( bool ) : If True , save cropped prediction boxes . Default is False .
nosave ( bool ) : If True , do not save inference images or videos . Default is False .
classes ( list [ int ] ) : List of class indices to filter detections by . Default is None .
agnostic_nms ( bool ) : If True , perform class - agnostic non - max suppression . Default is False .
augment ( bool ) : If True , use augmented inference . Default is False .
visualize ( bool ) : If True , visualize feature maps . Default is False .
update ( bool ) : If True , update all models ' weights. Default is False.
project ( str | Path ) : Directory to save results . Default is ' runs/detect ' .
name ( str ) : Name of the current experiment ; used to create a subdirectory within ' project ' . Default is ' exp ' .
exist_ok ( bool ) : If True , existing directories with the same name are reused instead of being incremented . Default is
False .
line_thickness ( int ) : Thickness of bounding box lines in pixels . Default is 3.
hide_labels ( bool ) : If True , do not display labels on bounding boxes . Default is False .
hide_conf ( bool ) : If True , do not display confidence scores on bounding boxes . Default is False .
half ( bool ) : If True , use FP16 half - precision inference . Default is False .
dnn ( bool ) : If True , use OpenCV DNN backend for ONNX inference . Default is False .
vid_stride ( int ) : Stride for processing video frames , to skip frames between processing . Default is 1.
2024-07-09 03:19:04 +08:00
Returns :
2024-07-09 04:05:56 +08:00
None
2024-07-09 03:19:04 +08:00
Examples :
2024-07-16 07:20:57 +08:00
` ` ` python
from ultralytics import run
2024-07-09 03:19:04 +08:00
2024-07-16 07:20:57 +08:00
# Run inference on an image
run ( source = ' data/images/example.jpg ' , weights = ' yolov5s.pt ' , device = ' 0 ' )
2024-07-09 03:19:04 +08:00
2024-07-16 07:20:57 +08:00
# Run inference on a video with specific confidence threshold
run ( source = ' data/videos/example.mp4 ' , weights = ' yolov5s.pt ' , conf_thres = 0.4 , device = ' 0 ' )
` ` `
2024-07-09 03:19:04 +08:00
"""
2021-09-28 08:40:20 +08:00
source = str ( source )
2024-01-08 08:29:14 +08:00
save_img = not nosave and not source . endswith ( " .txt " ) # save inference images
2021-11-06 01:43:03 +08:00
is_file = Path ( source ) . suffix [ 1 : ] in ( IMG_FORMATS + VID_FORMATS )
2024-01-08 08:29:14 +08:00
is_url = source . lower ( ) . startswith ( ( " rtsp:// " , " rtmp:// " , " http:// " , " https:// " ) )
webcam = source . isnumeric ( ) or source . endswith ( " .streams " ) or ( is_url and not is_file )
screenshot = source . lower ( ) . startswith ( " screen " )
2021-11-06 01:43:03 +08:00
if is_url and is_file :
source = check_file ( source ) # download
2020-05-30 08:04:54 +08:00
2020-11-09 02:39:05 +08:00
# Directories
2021-06-10 04:19:34 +08:00
save_dir = increment_path ( Path ( project ) / name , exist_ok = exist_ok ) # increment run
2024-01-08 08:29:14 +08:00
( save_dir / " labels " if save_txt else save_dir ) . mkdir ( parents = True , exist_ok = True ) # make dir
2020-11-09 02:39:05 +08:00
2021-11-09 23:45:02 +08:00
# Load model
2021-06-10 04:19:34 +08:00
device = select_device ( device )
2022-03-11 23:31:52 +08:00
model = DetectMultiBackend ( weights , device = device , dnn = dnn , data = data , fp16 = half )
stride , names , pt = model . stride , model . names , model . pt
2021-11-09 23:45:02 +08:00
imgsz = check_img_size ( imgsz , s = stride ) # check image size
2020-05-30 08:04:54 +08:00
2021-07-04 18:55:57 +08:00
# Dataloader
2022-09-25 22:21:26 +08:00
bs = 1 # batch_size
2020-05-30 08:04:54 +08:00
if webcam :
2022-10-17 20:34:33 +08:00
view_img = check_imshow ( warn = True )
2022-09-04 23:15:53 +08:00
dataset = LoadStreams ( source , img_size = imgsz , stride = stride , auto = pt , vid_stride = vid_stride )
2022-09-25 22:21:26 +08:00
bs = len ( dataset )
2022-09-23 05:58:14 +08:00
elif screenshot :
dataset = LoadScreenshots ( source , img_size = imgsz , stride = stride , auto = pt )
2020-05-30 08:04:54 +08:00
else :
2022-09-04 23:15:53 +08:00
dataset = LoadImages ( source , img_size = imgsz , stride = stride , auto = pt , vid_stride = vid_stride )
2021-07-04 18:55:57 +08:00
vid_path , vid_writer = [ None ] * bs , [ None ] * bs
2020-05-30 08:04:54 +08:00
# Run inference
2022-09-24 06:56:42 +08:00
model . warmup ( imgsz = ( 1 if pt or model . triton else bs , 3 , * imgsz ) ) # warmup
2024-01-03 15:09:23 +08:00
seen , windows , dt = 0 , [ ] , ( Profile ( device = device ) , Profile ( device = device ) , Profile ( device = device ) )
2021-11-09 23:45:02 +08:00
for path , im , im0s , vid_cap , s in dataset :
2022-08-19 01:55:38 +08:00
with dt [ 0 ] :
2022-09-24 06:56:42 +08:00
im = torch . from_numpy ( im ) . to ( model . device )
2022-08-19 01:55:38 +08:00
im = im . half ( ) if model . fp16 else im . float ( ) # uint8 to fp16/32
im / = 255 # 0 - 255 to 0.0 - 1.0
if len ( im . shape ) == 3 :
im = im [ None ] # expand for batch dim
2024-01-03 15:10:10 +08:00
if model . xml and im . shape [ 0 ] > 1 :
ims = torch . chunk ( im , im . shape [ 0 ] , 0 )
2020-05-30 08:04:54 +08:00
# Inference
2022-08-19 01:55:38 +08:00
with dt [ 1 ] :
visualize = increment_path ( save_dir / Path ( path ) . stem , mkdir = True ) if visualize else False
2024-01-03 15:10:10 +08:00
if model . xml and im . shape [ 0 ] > 1 :
pred = None
for image in ims :
if pred is None :
pred = model ( image , augment = augment , visualize = visualize ) . unsqueeze ( 0 )
else :
pred = torch . cat ( ( pred , model ( image , augment = augment , visualize = visualize ) . unsqueeze ( 0 ) ) , dim = 0 )
pred = [ pred , None ]
else :
pred = model ( im , augment = augment , visualize = visualize )
2021-07-24 19:08:51 +08:00
# NMS
2022-08-19 01:55:38 +08:00
with dt [ 2 ] :
pred = non_max_suppression ( pred , conf_thres , iou_thres , classes , agnostic_nms , max_det = max_det )
2020-05-30 08:04:54 +08:00
2021-07-24 19:08:51 +08:00
# Second-stage classifier (optional)
2021-11-09 23:45:02 +08:00
# pred = utils.general.apply_classifier(pred, classifier_model, im, im0s)
2020-05-30 08:04:54 +08:00
2023-09-04 18:52:33 +08:00
# Define the path for the CSV file
2024-01-08 08:29:14 +08:00
csv_path = save_dir / " predictions.csv "
2023-09-04 18:52:33 +08:00
# Create or append to the CSV file
def write_to_csv ( image_name , prediction , confidence ) :
2024-02-25 21:04:01 +08:00
""" Writes prediction data for an image to a CSV file, appending if the file exists. """
2024-01-08 08:29:14 +08:00
data = { " Image Name " : image_name , " Prediction " : prediction , " Confidence " : confidence }
with open ( csv_path , mode = " a " , newline = " " ) as f :
2023-09-04 18:52:33 +08:00
writer = csv . DictWriter ( f , fieldnames = data . keys ( ) )
if not csv_path . is_file ( ) :
writer . writeheader ( )
writer . writerow ( data )
2021-07-24 19:08:51 +08:00
# Process predictions
2021-09-10 20:34:09 +08:00
for i , det in enumerate ( pred ) : # per image
seen + = 1
2020-05-30 08:04:54 +08:00
if webcam : # batch_size >= 1
2021-11-02 01:22:13 +08:00
p , im0 , frame = path [ i ] , im0s [ i ] . copy ( ) , dataset . count
2024-01-08 08:29:14 +08:00
s + = f " { i } : "
2020-05-30 08:04:54 +08:00
else :
2024-01-08 08:29:14 +08:00
p , im0 , frame = path , im0s . copy ( ) , getattr ( dataset , " frame " , 0 )
2020-05-30 08:04:54 +08:00
2020-12-18 09:20:20 +08:00
p = Path ( p ) # to Path
2021-11-09 23:45:02 +08:00
save_path = str ( save_dir / p . name ) # im.jpg
2024-01-08 08:29:14 +08:00
txt_path = str ( save_dir / " labels " / p . stem ) + ( " " if dataset . mode == " image " else f " _ { frame } " ) # im.txt
s + = " %g x %g " % im . shape [ 2 : ] # print string
2020-06-29 19:56:40 +08:00
gn = torch . tensor ( im0 . shape ) [ [ 1 , 0 , 1 , 0 ] ] # normalization gain whwh
2021-06-10 04:19:34 +08:00
imc = im0 . copy ( ) if save_crop else im0 # for save_crop
2021-09-28 04:48:15 +08:00
annotator = Annotator ( im0 , line_width = line_thickness , example = str ( names ) )
2020-11-17 06:09:55 +08:00
if len ( det ) :
2020-05-30 08:04:54 +08:00
# Rescale boxes from img_size to im0 size
2022-09-24 22:02:41 +08:00
det [ : , : 4 ] = scale_boxes ( im . shape [ 2 : ] , det [ : , : 4 ] , im0 . shape ) . round ( )
2020-05-30 08:04:54 +08:00
# Print results
YOLOv5 segmentation model support (#9052)
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Fix duplicate plots.py
* Fix check_font()
* # torch.use_deterministic_algorithms(True)
* update doc detect->predict
* Resolve precommit for segment/train and segment/val
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Resolve precommit for utils/segment
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Resolve precommit min_wh
* Resolve precommit utils/segment/plots
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Resolve precommit utils/segment/general
* Align NMS-seg closer to NMS
* restore deterministic init_seeds code
* remove easydict dependency
* update
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* restore output_to_target mask
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* update
* cleanup
* Remove unused ImageFont import
* Unified NMS
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* DetectMultiBackend compatibility
* segment/predict.py update
* update plot colors
* fix bbox shifted
* sort bbox by confidence
* enable overlap by default
* Merge detect/segment output_to_target() function
* Start segmentation CI
* fix plots
* Update ci-testing.yml
* fix training whitespace
* optimize process mask functions (can we merge both?)
* Update predict/detect
* Update plot_images
* Update plot_images_and_masks
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* fix
* Add train to CI
* fix precommit
* fix precommit CI
* fix precommit pycocotools
* fix val float issues
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* fix masks float float issues
* suppress errors
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* fix no-predictions plotting bug
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Add CSV Logger
* fix val len(plot_masks)
* speed up evaluation
* fix process_mask
* fix plots
* update segment/utils build_targets
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* optimize utils/segment/general crop()
* optimize utils/segment/general crop() 2
* minor updates
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* torch.where revert
* downsample only if different shape
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* loss cleanup
* loss cleanup 2
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* loss cleanup 3
* update project names
* Rename -seg yamls from _underscore to -dash
* prepare for yolov5n-seg.pt
* precommit space fix
* add coco128-seg.yaml
* update coco128-seg comments
* cleanup val.py
* Major val.py cleanup
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* precommit fix
* precommit fix
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* optional pycocotools
* remove CI pip install pycocotools (auto-installed now)
* seg yaml fix
* optimize mask_iou() and masks_iou()
* threaded fix
* Major train.py update
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Major segments/val/process_batch() update
* yolov5/val updates from segment
* process_batch numpy/tensor fix
* opt-in to pycocotools with --save-json
* threaded pycocotools ops for 2x speed increase
* Avoid permute contiguous if possible
* Add max_det=300 argument to both val.py and segment/val.py
* fix onnx_dynamic
* speed up pycocotools ops
* faster process_mask(upsample=True) for predict
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* eliminate permutations for process_mask(upsample=True)
* eliminate permute-contiguous in crop(), use native dimension order
* cleanup comment
* Add Proto() module
* fix class count
* fix anchor order
* broadcast mask_gti in loss for speed
* Cleanup seg loss
* faster indexing
* faster indexing fix
* faster indexing fix2
* revert faster indexing
* fix validation plotting
* Loss cleanup and mxyxy simplification
* Loss cleanup and mxyxy simplification 2
* revert validation plotting
* replace missing tanh
* Eliminate last permutation
* delete unneeded .float()
* Remove MaskIOULoss and crop(if HWC)
* Final v6.3 SegmentationModel architecture updates
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Add support for TF export
* remove debugger trace
* add call
* update
* update
* Merge master
* Merge master
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Update dataloaders.py
* Restore CI
* Update dataloaders.py
* Fix TF/TFLite export for segmentation model
* Merge master
* Cleanup predict.py mask plotting
* cleanup scale_masks()
* rename scale_masks to scale_image
* cleanup/optimize plot_masks
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Add Annotator.masks()
* Annotator.masks() fix
* Update plots.py
* Annotator mask optimization
* Rename crop() to crop_mask()
* Do not crop in predict.py
* crop always
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Merge master
* Add vid-stride from master PR
* Update seg model outputs
* Update seg model outputs
* Add segmentation benchmarks
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Add segmentation benchmarks
* Add segmentation benchmarks
* Add segmentation benchmarks
* Fix DetectMultiBackend for OpenVINO
* update Annotator.masks
* fix val plot
* revert val plot
* clean up
* revert pil
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Fix CI error
* fix predict log
* remove upsample
* update interpolate
* fix validation plot logging
* Annotator.masks() cleanup
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Remove segmentation_model definition
* Restore 0.99999 decimals
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com>
Co-authored-by: Laughing-q <1185102784@qq.com>
Co-authored-by: Jiacong Fang <zldrobit@126.com>
2022-09-16 06:12:46 +08:00
for c in det [ : , 5 ] . unique ( ) :
n = ( det [ : , 5 ] == c ) . sum ( ) # detections per class
2021-01-23 07:39:08 +08:00
s + = f " { n } { names [ int ( c ) ] } { ' s ' * ( n > 1 ) } , " # add to string
2020-05-30 08:04:54 +08:00
# Write results
2020-08-13 04:50:16 +08:00
for * xyxy , conf , cls in reversed ( det ) :
2023-09-04 18:52:33 +08:00
c = int ( cls ) # integer class
2024-01-08 08:29:14 +08:00
label = names [ c ] if hide_conf else f " { names [ c ] } "
2023-09-04 18:52:33 +08:00
confidence = float ( conf )
2024-01-08 08:29:14 +08:00
confidence_str = f " { confidence : .2f } "
2023-09-04 18:52:33 +08:00
if save_csv :
write_to_csv ( p . name , label , confidence_str )
2020-05-30 08:04:54 +08:00
if save_txt : # Write to file
2024-08-22 17:24:47 +08:00
if save_format == 0 :
coords = ( xyxy2xywh ( torch . tensor ( xyxy ) . view ( 1 , 4 ) ) / gn ) . view ( - 1 ) . tolist ( ) # normalized xywh
else :
coords = ( torch . tensor ( xyxy ) . view ( 1 , 4 ) / gn ) . view ( - 1 ) . tolist ( ) # xyxy
line = ( cls , * coords , conf ) if save_conf else ( cls , * coords ) # label format
2024-01-08 08:29:14 +08:00
with open ( f " { txt_path } .txt " , " a " ) as f :
f . write ( ( " %g " * len ( line ) ) . rstrip ( ) % line + " \n " )
2020-05-30 08:04:54 +08:00
2021-06-10 04:19:34 +08:00
if save_img or save_crop or view_img : # Add bbox to image
2021-04-21 05:51:08 +08:00
c = int ( cls ) # integer class
2024-01-08 08:29:14 +08:00
label = None if hide_labels else ( names [ c ] if hide_conf else f " { names [ c ] } { conf : .2f } " )
2021-08-29 22:46:13 +08:00
annotator . box_label ( xyxy , label , color = colors ( c , True ) )
2022-05-15 22:38:26 +08:00
if save_crop :
2024-01-08 08:29:14 +08:00
save_one_box ( xyxy , imc , file = save_dir / " crops " / names [ c ] / f " { p . stem } .jpg " , BGR = True )
2020-05-30 08:04:54 +08:00
# Stream results
2021-08-29 22:46:13 +08:00
im0 = annotator . result ( )
2020-05-30 08:04:54 +08:00
if view_img :
2024-01-08 08:29:14 +08:00
if platform . system ( ) == " Linux " and p not in windows :
2022-06-27 06:04:11 +08:00
windows . append ( p )
cv2 . namedWindow ( str ( p ) , cv2 . WINDOW_NORMAL | cv2 . WINDOW_KEEPRATIO ) # allow window resize (Linux)
cv2 . resizeWindow ( str ( p ) , im0 . shape [ 1 ] , im0 . shape [ 0 ] )
2020-11-18 17:03:41 +08:00
cv2 . imshow ( str ( p ) , im0 )
2021-02-17 05:56:47 +08:00
cv2 . waitKey ( 1 ) # 1 millisecond
2020-05-30 08:04:54 +08:00
# Save results (image with detections)
if save_img :
2024-01-08 08:29:14 +08:00
if dataset . mode == " image " :
2020-05-30 08:04:54 +08:00
cv2 . imwrite ( save_path , im0 )
2021-03-25 21:09:49 +08:00
else : # 'video' or 'stream'
2021-07-04 18:55:57 +08:00
if vid_path [ i ] != save_path : # new video
vid_path [ i ] = save_path
if isinstance ( vid_writer [ i ] , cv2 . VideoWriter ) :
vid_writer [ i ] . release ( ) # release previous video writer
2021-03-25 21:09:49 +08:00
if vid_cap : # video
fps = vid_cap . get ( cv2 . CAP_PROP_FPS )
w = int ( vid_cap . get ( cv2 . CAP_PROP_FRAME_WIDTH ) )
h = int ( vid_cap . get ( cv2 . CAP_PROP_FRAME_HEIGHT ) )
else : # stream
fps , w , h = 30 , im0 . shape [ 1 ] , im0 . shape [ 0 ]
2024-01-08 08:29:14 +08:00
save_path = str ( Path ( save_path ) . with_suffix ( " .mp4 " ) ) # force *.mp4 suffix on results videos
vid_writer [ i ] = cv2 . VideoWriter ( save_path , cv2 . VideoWriter_fourcc ( * " mp4v " ) , fps , ( w , h ) )
2021-07-04 18:55:57 +08:00
vid_writer [ i ] . write ( im0 )
2020-05-30 08:04:54 +08:00
2022-02-05 01:19:37 +08:00
# Print time (inference-only)
2022-08-19 01:55:38 +08:00
LOGGER . info ( f " { s } { ' ' if len ( det ) else ' (no detections), ' } { dt [ 1 ] . dt * 1E3 : .1f } ms " )
2022-02-05 01:19:37 +08:00
2021-09-10 20:34:09 +08:00
# Print results
2024-01-08 08:29:14 +08:00
t = tuple ( x . t / seen * 1e3 for x in dt ) # speeds per image
LOGGER . info ( f " Speed: %.1fms pre-process, %.1fms inference, %.1fms NMS per image at shape { ( 1 , 3 , * imgsz ) } " % t )
2020-05-30 08:04:54 +08:00
if save_txt or save_img :
2024-01-08 08:29:14 +08:00
s = f " \n { len ( list ( save_dir . glob ( ' labels/*.txt ' ) ) ) } labels saved to { save_dir / ' labels ' } " if save_txt else " "
2021-11-02 01:22:13 +08:00
LOGGER . info ( f " Results saved to { colorstr ( ' bold ' , save_dir ) } { s } " )
2021-06-10 04:19:34 +08:00
if update :
2022-07-29 23:07:24 +08:00
strip_optimizer ( weights [ 0 ] ) # update model (to fix SourceChangeWarning)
2021-06-10 04:19:34 +08:00
2020-05-30 08:04:54 +08:00
2021-06-19 18:06:59 +08:00
def parse_opt ( ) :
2024-07-09 03:19:04 +08:00
"""
2024-07-16 07:20:57 +08:00
Parse command - line arguments for YOLOv5 detection , allowing custom inference options and model configurations .
2024-07-09 03:19:04 +08:00
Args :
- - weights ( str | list [ str ] , optional ) : Model path or Triton URL . Defaults to ROOT / ' yolov5s.pt ' .
- - source ( str , optional ) : File / dir / URL / glob / screen / 0 ( webcam ) . Defaults to ROOT / ' data/images ' .
- - data ( str , optional ) : Dataset YAML path . Provides dataset configuration information .
- - imgsz ( list [ int ] , optional ) : Inference size ( height , width ) . Defaults to [ 640 ] .
- - conf - thres ( float , optional ) : Confidence threshold . Defaults to 0.25 .
- - iou - thres ( float , optional ) : NMS IoU threshold . Defaults to 0.45 .
- - max - det ( int , optional ) : Maximum number of detections per image . Defaults to 1000.
- - device ( str , optional ) : CUDA device , i . e . , ' 0 ' or ' 0,1,2,3 ' or ' cpu ' . Defaults to " " .
- - view - img ( bool , optional ) : Flag to display results . Defaults to False .
- - save - txt ( bool , optional ) : Flag to save results to * . txt files . Defaults to False .
- - save - csv ( bool , optional ) : Flag to save results in CSV format . Defaults to False .
- - save - conf ( bool , optional ) : Flag to save confidences in labels saved via - - save - txt . Defaults to False .
- - save - crop ( bool , optional ) : Flag to save cropped prediction boxes . Defaults to False .
- - nosave ( bool , optional ) : Flag to prevent saving images / videos . Defaults to False .
- - classes ( list [ int ] , optional ) : List of classes to filter results by , e . g . , ' --classes 0 2 3 ' . Defaults to None .
- - agnostic - nms ( bool , optional ) : Flag for class - agnostic NMS . Defaults to False .
- - augment ( bool , optional ) : Flag for augmented inference . Defaults to False .
- - visualize ( bool , optional ) : Flag for visualizing features . Defaults to False .
- - update ( bool , optional ) : Flag to update all models in the model directory . Defaults to False .
- - project ( str , optional ) : Directory to save results . Defaults to ROOT / ' runs/detect ' .
- - name ( str , optional ) : Sub - directory name for saving results within - - project . Defaults to ' exp ' .
- - exist - ok ( bool , optional ) : Flag to allow overwriting if the project / name already exists . Defaults to False .
- - line - thickness ( int , optional ) : Thickness ( in pixels ) of bounding boxes . Defaults to 3.
- - hide - labels ( bool , optional ) : Flag to hide labels in the output . Defaults to False .
- - hide - conf ( bool , optional ) : Flag to hide confidences in the output . Defaults to False .
- - half ( bool , optional ) : Flag to use FP16 half - precision inference . Defaults to False .
- - dnn ( bool , optional ) : Flag to use OpenCV DNN for ONNX inference . Defaults to False .
2024-07-16 07:20:57 +08:00
- - vid - stride ( int , optional ) : Video frame - rate stride , determining the number of frames to skip in between
consecutive frames . Defaults to 1.
2024-07-09 03:19:04 +08:00
Returns :
argparse . Namespace : Parsed command - line arguments as an argparse . Namespace object .
Example :
` ` ` python
from ultralytics import YOLOv5
args = YOLOv5 . parse_opt ( )
` ` `
"""
2020-05-30 08:04:54 +08:00
parser = argparse . ArgumentParser ( )
2024-01-08 08:29:14 +08:00
parser . add_argument ( " --weights " , nargs = " + " , type = str , default = ROOT / " yolov5s.pt " , help = " model path or triton URL " )
parser . add_argument ( " --source " , type = str , default = ROOT / " data/images " , help = " file/dir/URL/glob/screen/0(webcam) " )
parser . add_argument ( " --data " , type = str , default = ROOT / " data/coco128.yaml " , help = " (optional) dataset.yaml path " )
parser . add_argument ( " --imgsz " , " --img " , " --img-size " , nargs = " + " , type = int , default = [ 640 ] , help = " inference size h,w " )
parser . add_argument ( " --conf-thres " , type = float , default = 0.25 , help = " confidence threshold " )
parser . add_argument ( " --iou-thres " , type = float , default = 0.45 , help = " NMS IoU threshold " )
parser . add_argument ( " --max-det " , type = int , default = 1000 , help = " maximum detections per image " )
parser . add_argument ( " --device " , default = " " , help = " cuda device, i.e. 0 or 0,1,2,3 or cpu " )
parser . add_argument ( " --view-img " , action = " store_true " , help = " show results " )
parser . add_argument ( " --save-txt " , action = " store_true " , help = " save results to *.txt " )
2024-08-22 17:24:47 +08:00
parser . add_argument ( " --save-format " , type = int , default = 0 , help = " whether to save boxes coordinates in YOLO format or Pascal-VOC format when save-txt is True, 0 for YOLO and 1 for Pascal-VOC " )
2024-01-08 08:29:14 +08:00
parser . add_argument ( " --save-csv " , action = " store_true " , help = " save results in CSV format " )
parser . add_argument ( " --save-conf " , action = " store_true " , help = " save confidences in --save-txt labels " )
parser . add_argument ( " --save-crop " , action = " store_true " , help = " save cropped prediction boxes " )
parser . add_argument ( " --nosave " , action = " store_true " , help = " do not save images/videos " )
parser . add_argument ( " --classes " , nargs = " + " , type = int , help = " filter by class: --classes 0, or --classes 0 2 3 " )
parser . add_argument ( " --agnostic-nms " , action = " store_true " , help = " class-agnostic NMS " )
parser . add_argument ( " --augment " , action = " store_true " , help = " augmented inference " )
parser . add_argument ( " --visualize " , action = " store_true " , help = " visualize features " )
parser . add_argument ( " --update " , action = " store_true " , help = " update all models " )
parser . add_argument ( " --project " , default = ROOT / " runs/detect " , help = " save results to project/name " )
parser . add_argument ( " --name " , default = " exp " , help = " save results to project/name " )
parser . add_argument ( " --exist-ok " , action = " store_true " , help = " existing project/name ok, do not increment " )
parser . add_argument ( " --line-thickness " , default = 3 , type = int , help = " bounding box thickness (pixels) " )
parser . add_argument ( " --hide-labels " , default = False , action = " store_true " , help = " hide labels " )
parser . add_argument ( " --hide-conf " , default = False , action = " store_true " , help = " hide confidences " )
parser . add_argument ( " --half " , action = " store_true " , help = " use FP16 half-precision inference " )
parser . add_argument ( " --dnn " , action = " store_true " , help = " use OpenCV DNN for ONNX inference " )
parser . add_argument ( " --vid-stride " , type = int , default = 1 , help = " video frame-rate stride " )
2020-05-30 08:04:54 +08:00
opt = parser . parse_args ( )
Add TensorFlow and TFLite export (#1127)
* Add models/tf.py for TensorFlow and TFLite export
* Set auto=False for int8 calibration
* Update requirements.txt for TensorFlow and TFLite export
* Read anchors directly from PyTorch weights
* Add --tf-nms to append NMS in TensorFlow SavedModel and GraphDef export
* Remove check_anchor_order, check_file, set_logging from import
* Reformat code and optimize imports
* Autodownload model and check cfg
* update --source path, img-size to 320, single output
* Adjust representative_dataset
* Put representative dataset in tfl_int8 block
* detect.py TF inference
* weights to string
* weights to string
* cleanup tf.py
* Add --dynamic-batch-size
* Add xywh normalization to reduce calibration error
* Update requirements.txt
TensorFlow 2.3.1 -> 2.4.0 to avoid int8 quantization error
* Fix imports
Move C3 from models.experimental to models.common
* Add models/tf.py for TensorFlow and TFLite export
* Set auto=False for int8 calibration
* Update requirements.txt for TensorFlow and TFLite export
* Read anchors directly from PyTorch weights
* Add --tf-nms to append NMS in TensorFlow SavedModel and GraphDef export
* Remove check_anchor_order, check_file, set_logging from import
* Reformat code and optimize imports
* Autodownload model and check cfg
* update --source path, img-size to 320, single output
* Adjust representative_dataset
* detect.py TF inference
* Put representative dataset in tfl_int8 block
* weights to string
* weights to string
* cleanup tf.py
* Add --dynamic-batch-size
* Add xywh normalization to reduce calibration error
* Update requirements.txt
TensorFlow 2.3.1 -> 2.4.0 to avoid int8 quantization error
* Fix imports
Move C3 from models.experimental to models.common
* implement C3() and SiLU()
* Fix reshape dim to support dynamic batching
* Add epsilon argument in tf_BN, which is different between TF and PT
* Set stride to None if not using PyTorch, and do not warmup without PyTorch
* Add list support in check_img_size()
* Add list input support in detect.py
* sys.path.append('./') to run from yolov5/
* Add int8 quantization support for TensorFlow 2.5
* Add get_coco128.sh
* Remove --no-tfl-detect in models/tf.py (Use tf-android-tfl-detect branch for EdgeTPU)
* Update requirements.txt
* Replace torch.load() with attempt_load()
* Update requirements.txt
* Add --tf-raw-resize to set half_pixel_centers=False
* Add --agnostic-nms for TF class-agnostic NMS
* Cleanup after merge
* Cleanup2 after merge
* Cleanup3 after merge
* Add tf.py docstring with credit and usage
* pb saved_model and tflite use only one model in detect.py
* Add use cases in docstring of tf.py
* Remove redundant `stride` definition
* Remove keras direct import
* Fix `check_requirements(('tensorflow>=2.4.1',))`
Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com>
2021-08-17 19:18:16 +08:00
opt . imgsz * = 2 if len ( opt . imgsz ) == 1 else 1 # expand
2022-03-31 23:11:43 +08:00
print_args ( vars ( opt ) )
2021-06-19 18:06:59 +08:00
return opt
def main ( opt ) :
2024-07-09 03:19:04 +08:00
"""
Executes YOLOv5 model inference based on provided command - line arguments , validating dependencies before running .
Args :
2024-07-09 04:05:56 +08:00
opt ( argparse . Namespace ) : Command - line arguments for YOLOv5 detection . See function ` parse_opt ` for details .
2024-07-09 03:19:04 +08:00
Returns :
2024-07-09 04:05:56 +08:00
None
2024-07-09 03:19:04 +08:00
Note :
2024-07-16 07:20:57 +08:00
This function performs essential pre - execution checks and initiates the YOLOv5 detection process based on user - specified
options . Refer to the usage guide and examples for more information about different sources and formats at :
2024-07-09 04:05:56 +08:00
https : / / github . com / ultralytics / ultralytics
2024-07-09 03:19:04 +08:00
Example usage :
` ` ` python
if __name__ == " __main__ " :
opt = parse_opt ( )
main ( opt )
` ` `
"""
2024-01-08 08:29:14 +08:00
check_requirements ( ROOT / " requirements.txt " , exclude = ( " tensorboard " , " thop " ) )
2021-06-21 23:25:04 +08:00
run ( * * vars ( opt ) )
2021-06-19 18:06:59 +08:00
2024-01-08 08:29:14 +08:00
if __name__ == " __main__ " :
2021-06-19 18:06:59 +08:00
opt = parse_opt ( )
main ( opt )