yolov5検出コードの詳細な説明

import argparse 
import time 
from pathlib import Path 

import cv2 
import torch 
import torch.backends.cudnn as cudnn 
from numpy import random 

from models.experimental import try_load 
from utils.datasets import LoadStreams、
LoadImages from utils.general import check_img_size、check_requirements、non_max_classifier、apply 、scale_coords、\ 
    xyxy2xywh、strip_optimizer、set_logging、utils.plots
からのincrement_path import plot_one_box 
from utils.torch_utils import select_device、load_classifier、time_synchronized defdetect 


(save_img = False):
    #source:テストデータ、または画像/ビデオパスにすることができます「0」(コンピューターにはカメラが付属しています)、またはrtspなどのビデオストリームにすることができます。
    です。#view_img表示/ビデオ、デフォルトはFalseかどうかの予測後、画像
    #save_txt予測されたフレーム座標がtxtファイルとして保存されるかどうかにかかわらず、デフォルトはFalse
    です。#imgszネットワーク入力画像
    ソースのサイズ、重み、view_img、save_txt、imgsz = opt.source、opt.weights、opt.view_img、opt .save_txt、opt。img_size isnumeric ()メソッドは、文字列が数字のみで構成されているかどうかを検出します
    #lower()大文字は小文字に変換されます。指定された文字列
    webcam = source.isnumeric()またはsourceで始まります。 extendswith( '。txt')またはsource.lower()。startswith(
        ( 'rtsp://'、 'rtmp://'、 'http://'))
    #ディレクトリ
    save_dir = Path(increment_path(Path(opt .project)/ opt.name、exist_ok = opt.exist_ok))#増分実行
    (save_dir / 'labels' if save_txt else save_dir).mkdir(parents = True、exist_ok = True)
    #make dir 
    #初期化set_logging()Select
    端末
    device = select_device(opt.device) 
        modelc.load_state_dict(torch.load(' weights / resnet101.pt '、map_location = device)[' model '])。to(device).eval()をデータローダーを
    設定します
    half = device.type!= 'cpu'#CUDAでのみサポートされる半精度

    #モデルのロード
    model = try_load(weights、map_location = device)#FP32モデルのロード
    stride = int(model.stride.max())#モデルのストライド
    imgsz = check_img_size(imgsz、s = stride)#
    半分の場合はimg_sizeをチェック
        model.half()#FP16へ

    #第2段階の分類子
    classify =分類する
    場合はFalse 
        modelc = load_classifier(name = 'resnet101'、n = 2)#初期化

    vid_path、vid_writer = None、None 
    #ウェブ
    サイトの場合:#view_img = True 
    #cudnn.benchmark = True#一定の画像サイズの推測を高速化するためにTrueを設定
    #dataset = LoadStreams(source、img_size = imgsz、stride = stride)
    #else save_img =真の
    データセット= LoadImages(source、img_size = imgsz、stride = stride)
    print(dataset)
    #名前と色を取得
    names = model.module.names if hasattr(model、 'module')else model.names 
    colors = [[random .randint(0、255)for _ in range(3)] for _ in names] 

    device.type!= 'cpu'の場合に推論を実行します
        model(torch.zeros(1、3、imgsz、imgsz).to(device).type_as(next(model.parameters())))#1回実行
    t0 = time.time()
    #img0 = cv2.imread(path )
    #path〉片/视频路径#img進む行
    サイズ+ pad之后的
    #img0原サイズ図片
    #キャップのは、画像を読み取る場合はNoneであり、ビデオを読み取る場合はビデオソースです。
    〉データセット内のパス、img、im0s、vid_capの場合:
        img = torch.from_numpy(img).to(device)
        img = img.half()if half else img.float()#uint8〜fp16 / 32 
        img / = 255.0#0-255〜0.0-1.0 
        if img.ndimension()== 3:
            img = img.unsqueeze(0)

        #推論
        t1 = time_synchronized()
        pred = model(img、augment = opt.augment)[0] #NMSを

        適用する#NMSを
        適用する
        "" "
        pred:順伝播の出力
        conf_thres:信頼しきい値
        iou_thres:iouしきい値
        クラス:特定のカテゴリのみを保持するかどうかし、enumerate(pred)でdet:#画像ごとの検出
        依存しない:nmsを実行し、異なるカテゴリ間のボックスを削除するかどうかnmsの
        後、予測ボックスの形式:xywh-> xyxy(左上隅と右下隅)
        predはリストリスト[torch.tensor]、長さはbatch_size 
        、各torch.tensorの形状は(num_boxes、6)、内容はbox + conf + cls 
        "" " 
        pred = non_max_suppression(pred、opt。 conf_thres、opt。iou_thres、classes = opt.classes、agnostic = opt.agnostic_nms)
        t2 = time_synchronized()

        #分類子の適用
        二次分類を追加します
            。classifyの
        場合はデフォルトでは使用されませんpred = apply_classifier(pred、modelc、img、im0s)

        #検出を処理する
                サイトの各画像を処理する#batch_size p、s、im0、frame = path [i]、 '%g:'%i、im0s [i] .copy()、dataset.count 
            else:
            ウェブ場合: > = 1
                座標形式はxyxyです
                #getattr(dataset、 'frame'、0)获取dataset中的文字列值frame、不存在戻る回0 
                p、s、im0、frame = path、 ''、im0s、getattr(dataset、 'frame'、0)

            p = Path(p)
            #to Path #画像固定save_path = str(save_dir / p.name)#img.jpg 
            txt_path = str(save_dir / 'labels' / p.stem)+( '' ifdataset.mode == ' image'else f'_ {frame} ')#img.txt 
            s + ='%gx%g '%img.shape [2:]#文字列を出力
            gn = torch.tensor(im0.shape)[[1、0 、1、0]]#正規化ゲインwhhh 
            if len(det):
                #ボックスをimg_sizeからim0サイズに再スケールします
                det [:、:4] = scale_coords(img.shape [2:]、det [:、:4]、im0.shape).round()
 
                #結果を
                出力し
                ます、-1] .unique():
                    n =(det [:、-1] == c).sum()#クラスごとの検出
                    s + = f "{n} {names [int(c)]} {' s '*(n> 1)}、 "#文字列に追加

                * xyxy、conf、clsの結果をreversed(det)に
                    書き込むif save_txt:#ファイルに
                        書き込むxywh =(xyxy2xywh(torch.tensor(xyxy))。 view(1、4))/ gn).view(-1).tolist()#正規化されたxywh 
                        line =(cls、* xywh、conf)if opt.save_conf else(cls、* xywh)#ラベル形式 
                        open(txt_path + '。txt'、 ' a ')as f:
                            f.write(('%g '* len(line))。rstrip()%line +' \ n ')
 
                    if save_img or view_img:#画像にbboxを追加#出力
                        ラベルとスコア値
                        label = f '{names [int(cls)]} {conf:.2f}' 
                        カテゴリとスコアボックス情報を描画plot_one_box(xyxy、im0、label = label、color = colors [int(cls)]、line_thickness = 5)

            #印刷時間(推論+ NMS)
            print(f '{s}完了。({t2-t1:.3f} s)')

            view_img:
                cv2。imshowの場合に結果をストリーミング(str(p)、im0) 

            #結果を保存します(検出された画像)
            if save_img: 
                if dataset.mode == 'image':
                    cv2.imwrite(save_path、im0)
                else:# 'video'
                    if vid_path!= save_path:#新しいビデオ
                        vid_path = save_path 
                        if isinstance(vid_writer、cv2.VideoWriter):
                            vid_writer.release()#前のビデオライターを

                        解放するfourcc = 'mp4v'#出力ビデオコーデック
                        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))
                        vid_writer = cv2.VideoWriter(save_path、cv2.VideoWriter_fourcc(* fourcc)、fps、(w、 )
                    save_txt

    またはsave_imgの場合はvid_writer.write(im0)
        s = f "\ n {len(list(save_dir.glob( 'labels / *。txt')))}ラベルを{save_dir / 'labels'}"に
        保存ifsave_txt else '' print(f "結果を{に保存save_dir} {s} ")

    print(f'Done。({time.time()-t0:.3f} s) ')


if __name__ ==' __ main __ ':
    parser = argparse.ArgumentParser()
    #parser.add_argument( '--weights'、nargs = '+'、type = str、default = 'yolov5s.pt'、help = 'model.pt path(s)')
    parser.add_argument( '-weights'、nargs = '+ '、type = str、default ='。/ runs / train / exp29 / weights / best.pt '、help =' model.pt path(s) ') 
    parser.add_argument( ' ' 、type = str、default = 'data / images'、help = 'ソース ')#ファイル/フォルダー、ウェブカメラの場合は0
    parser.add_argument('-img-size '、type = int、default = 640、help = '推論サイズ(ピクセル)') 
    #Confidence 
    output threshold parser.add_argument( '-conf-thres'、type = float、default = 0.25、help = 'objectconfidencethreshold')
    parser.add_argument( '-iou-thres'、type = float、default = 0.45、help = 'NMSのIOUしきい値')
    parser.add_argument( '-device'、default = ''、help = 'cuda device、つまり、0または0,1,2,3またはcpu ')
    parser.add_argument('-view-img '、action =' store_true '、help =' display results ')
    parser.add_argument('-save-txt ' 、action = 'store_true'、help = '結果を* .txtに保存')
    parser.add_argument( '-save-conf'、action = 'store_true'、help = '信頼性を--save-txtラベルに保存') 
    parser.add_argument( '-augment'、action = 'store_true'、help = '拡張推論 ') 
    parser.add_argument('-update '、action =' store_true '、help ='すべてのモデルを更新 ') 
    parser.add_argument( '-classes'、nargs = '+'、type = int、 help = 'クラスでフィルタリング:-class 0、または--class 0 2 3 ')
    parser.add_argument( '-agnostic-nms'、action = 'store_true'、help = 'class-agnostic NMS') -project #重みの
                optおよびその他の情報を削除します
    parser.add_argument( '-project'、default = 'runs / detect'、help = '結果をプロジェクト/名前に保存')
    parser.add_argument( '-name'、default = 'exp'、help = '結果を保存to project / name ')
    parser.add_argument('-exist-ok '、action =' store_true '、help =' existing project / name ok、do not incremental ')
    opt = parser.parse_args()
    print(opt)
    check_requirements ()

    with torch.no_grad():
        if opt.update:#
            ['yolov5s.pt'、 'yolov5m.pt'、 'yolov5l.pt'、 'yolov5xのopt.weightsのすべてのモデルを(SourceChangeWarningを修正するために)更新します。 pt ']:
                detect()
                strip_optimizer(opt.weights)
        else:
            detect()

おすすめ

転載: blog.csdn.net/qq_16792139/article/details/114025854