国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

從零開始使用YOLOv5+PyQt5+OpenCV+爬蟲實(shí)現(xiàn)是否佩戴口罩檢測(cè)

這篇具有很好參考價(jià)值的文章主要介紹了從零開始使用YOLOv5+PyQt5+OpenCV+爬蟲實(shí)現(xiàn)是否佩戴口罩檢測(cè)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

從零開始使用YOLOv5+PyQt5+OpenCV+爬蟲實(shí)現(xiàn)是否佩戴口罩檢測(cè)

全流程教程,從數(shù)據(jù)采集到模型使用到最終展示。若有任何疑問和建議歡迎評(píng)論區(qū)討論。

先放上最終實(shí)現(xiàn)效果

圖片檢測(cè)效果圖
從零開始使用YOLOv5+PyQt5+OpenCV+爬蟲實(shí)現(xiàn)是否佩戴口罩檢測(cè)
視頻檢測(cè)效果圖
從零開始使用YOLOv5+PyQt5+OpenCV+爬蟲實(shí)現(xiàn)是否佩戴口罩檢測(cè)
攝像頭實(shí)時(shí)檢測(cè)效果圖
從零開始使用YOLOv5+PyQt5+OpenCV+爬蟲實(shí)現(xiàn)是否佩戴口罩檢測(cè)

1. 數(shù)據(jù)集的制作

我已經(jīng)處理了一份數(shù)據(jù)形成了對(duì)應(yīng)的數(shù)據(jù)集。獲取地址為百度網(wǎng)盤:
鏈接:https://pan.baidu.com/s/1SkraBsZXWCu1YxmoWgDePg
提取碼:0ghw
其中all_mask為全部圖片數(shù)據(jù)集。new_mask_data為一份較小的數(shù)據(jù)集??梢园葱璜@取
從零開始使用YOLOv5+PyQt5+OpenCV+爬蟲實(shí)現(xiàn)是否佩戴口罩檢測(cè)
文件組織形式為圖片和其對(duì)于的標(biāo)簽文件txt
從零開始使用YOLOv5+PyQt5+OpenCV+爬蟲實(shí)現(xiàn)是否佩戴口罩檢測(cè)
從零開始使用YOLOv5+PyQt5+OpenCV+爬蟲實(shí)現(xiàn)是否佩戴口罩檢測(cè)
以第一行五個(gè)數(shù)字為例,第一位為類別這里1代表戴口罩,0代表未帶口罩,后四位為目標(biāo)框的中心點(diǎn)x,y和大小h,w,其大小都是歸一化的即是目標(biāo)框的大小除以圖片的大小H,W。

自己制作數(shù)據(jù)集可以參考如下步驟

1.1 使用爬蟲采集數(shù)據(jù)集

可以通過爬蟲爬取一些佩戴口罩的圖片和一些未佩戴口罩的圖片。
這里直接上代碼,如果想詳細(xì)了解可以參考我的另外一篇文章python爬取百度圖片,可以大量批量爬?。▋H供學(xué)習(xí),很詳細(xì))

import requests#導(dǎo)入請(qǐng)求庫
import time
import re
#設(shè)定爬取的總數(shù)
total=90
batch_size=30
all_success=0
for i in range(total//batch_size):
    url='https://image.baidu.com/search/acjson?tn=resultjson_com&logid=10371129381236677678&ipn=rj&ct=201326592&is=&fp=result&fr=&word=口罩&queryWord=口罩&cl=2&lm=-1&ie=utf-8&oe=utf-8&adpicid=&st=&z=&ic=&hd=&latest=&copyright=&s=&se=&tab=&width=&height=&face=&istype=&qc=&nc=1&expermode=&nojc=&isAsync=&pn={0}&rn=30&gsm=3c&1682846532783='.format((i+1)*30)
    #添加請(qǐng)求頭,模擬瀏覽器,有些網(wǎng)站可以不加這個(gè),不過最好是加上,油多不壞菜這個(gè)道理
    headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36'}
    res=requests.get(url,headers=headers)#發(fā)送請(qǐng)求,返回?cái)?shù)據(jù)
    html=res.text#把返回的內(nèi)容解析
    # 使用正則表達(dá)式匹配圖片url
    img_url_list=re.findall('"thumbURL":"(.*?)"',html)
    #print(img_url_list)
    for j in range(len(img_url_list)):
        res_img=requests.get(img_url_list[j],headers=headers)
        img=res_img.content#這個(gè)里是圖片,我們需要返回二進(jìn)制數(shù)據(jù)
        # 圖片保存的路徑
        with open('D:\\code\\person\\mask\\'+str(j)+'mask_img.jpg','wb')as f:
            f.write(img)
        time.sleep(3)#每當(dāng)保存一張圖片,先暫停一下,不然太頻繁容易發(fā)現(xiàn)是機(jī)器爬蟲,導(dǎo)致無法獲取
        all_success=all_success+1
        print("爬取{}張圖片成功".format(all_success))
print("爬取{}張圖片成功".format(all_success))

一些爬取的效果圖如下。
從零開始使用YOLOv5+PyQt5+OpenCV+爬蟲實(shí)現(xiàn)是否佩戴口罩檢測(cè)

從零開始使用YOLOv5+PyQt5+OpenCV+爬蟲實(shí)現(xiàn)是否佩戴口罩檢測(cè)

1.2 使用labelme對(duì)圖片進(jìn)行標(biāo)注

labelme是圖形圖像注釋工具,它是用Python編寫的,并將Qt用于其圖形界面。說直白點(diǎn),它是有界面的, 像軟件一樣,可以交互,但是它又是由命令行啟動(dòng)的,比軟件的使用稍微麻煩點(diǎn)。其界面如下圖:

從零開始使用YOLOv5+PyQt5+OpenCV+爬蟲實(shí)現(xiàn)是否佩戴口罩檢測(cè)
github鏈接: labelme https://github.com/wkentaro/labelme
它的功能很多,包括:

  • 對(duì)圖像進(jìn)行多邊形,矩形,圓形,多段線,線段,點(diǎn)形式的標(biāo)注(可用于目標(biāo)檢-測(cè),圖像分割等任務(wù))。
  • 對(duì)圖像進(jìn)行進(jìn)行 flag形式的標(biāo)注(可用于圖像分類 和 清理 任務(wù))。
  • 視頻標(biāo)注 - 生成 VOC 格式的數(shù)據(jù)集(for semantic / instancesegmentation)
  • 生成 COCO 格式的數(shù)據(jù)集(for instance segmentation)

2. YOLOv5

2.1YOLO算法簡單介紹

YOLO框架(You Only Look Once)與RCNN系列算法不一樣,是以不同的方式處理對(duì)象檢測(cè)。它將整個(gè)圖像放在一個(gè)實(shí)例中,并預(yù)測(cè)這些框的邊界框坐標(biāo)和及所屬類別概率。使用YOLO算法最大優(yōu)的點(diǎn)是速度極快,每秒可處理45幀,也能夠理解一般的對(duì)象表示。

在本節(jié)中,將介紹YOLO用于檢測(cè)給定圖像中的對(duì)象的處理步驟。

首先,輸入圖像:
從零開始使用YOLOv5+PyQt5+OpenCV+爬蟲實(shí)現(xiàn)是否佩戴口罩檢測(cè)

然后,YOLO將輸入圖像劃分為網(wǎng)格形式(例如3 X 3):
從零開始使用YOLOv5+PyQt5+OpenCV+爬蟲實(shí)現(xiàn)是否佩戴口罩檢測(cè)

最后,對(duì)每個(gè)網(wǎng)格應(yīng)用圖像分類和定位處理,獲得預(yù)測(cè)對(duì)象的邊界框及其對(duì)應(yīng)的類概率。
整個(gè)過程是不是很清晰,下面逐一詳細(xì)介紹。首先需要將標(biāo)記數(shù)據(jù)傳遞給模型以進(jìn)行訓(xùn)練。假設(shè)已將圖像劃分為大小為3 X 3的網(wǎng)格,且總共只有3個(gè)類別,分別是行人(c1)、汽車(c2)和摩托車(c3)。因此,對(duì)于每個(gè)單元格,標(biāo)簽y將是一個(gè)八維向量:

從零開始使用YOLOv5+PyQt5+OpenCV+爬蟲實(shí)現(xiàn)是否佩戴口罩檢測(cè)

其中:
pc定義對(duì)象是否存在于網(wǎng)格中(存在的概率);
bx、by、bh、bw指定邊界框;
c1、c2、c3代表類別。如果檢測(cè)對(duì)象是汽車,則c2位置處的值將為1,c1和c3處的值將為0;
假設(shè)從上面的例子中選擇第一個(gè)網(wǎng)格:

從零開始使用YOLOv5+PyQt5+OpenCV+爬蟲實(shí)現(xiàn)是否佩戴口罩檢測(cè)

由于此網(wǎng)格中沒有對(duì)象,因此pc將為零,此網(wǎng)格的y標(biāo)簽將為:
從零開始使用YOLOv5+PyQt5+OpenCV+爬蟲實(shí)現(xiàn)是否佩戴口罩檢測(cè)

?意味著其它值是什么并不重要,因?yàn)榫W(wǎng)格中沒有對(duì)象。下面舉例另一個(gè)有車的網(wǎng)格(c2=1):
從零開始使用YOLOv5+PyQt5+OpenCV+爬蟲實(shí)現(xiàn)是否佩戴口罩檢測(cè)

在為此網(wǎng)格編寫y標(biāo)簽之前,首先要了解YOLO如何確定網(wǎng)格中是否存在實(shí)際對(duì)象。大圖中有兩個(gè)物體(兩輛車),因此YOLO將取這兩個(gè)物體的中心點(diǎn),物體將被分配到包含這些物體中心的網(wǎng)格中。中心點(diǎn)左側(cè)網(wǎng)格的y標(biāo)簽會(huì)是這樣的:
從零開始使用YOLOv5+PyQt5+OpenCV+爬蟲實(shí)現(xiàn)是否佩戴口罩檢測(cè)

由于此網(wǎng)格中存在對(duì)象,因此pc將等于1,bx、by、bh、bw將相對(duì)于正在處理的特定網(wǎng)格單元計(jì)算。由于檢測(cè)出的對(duì)象是汽車,所以c2=1,c1和c3均為0。對(duì)于9個(gè)網(wǎng)格中的每一個(gè)單元格,都具有八維輸出向量。最終的輸出形狀為3X3X8。
使用上面的例子(輸入圖像:100X100X3,輸出:3X3X8),模型將按如下方式進(jìn)行訓(xùn)練:
從零開始使用YOLOv5+PyQt5+OpenCV+爬蟲實(shí)現(xiàn)是否佩戴口罩檢測(cè)

使用經(jīng)典的CNN網(wǎng)絡(luò)構(gòu)建模型,并進(jìn)行模型訓(xùn)練。在測(cè)試階段,將圖像傳遞給模型,經(jīng)過一次前向傳播就得到輸出y。為了簡單起見,使用3X3網(wǎng)格解釋這一點(diǎn),但通常在實(shí)際場景中會(huì)采用更大的網(wǎng)格(比如19X19)。

即使一個(gè)對(duì)象跨越多個(gè)網(wǎng)格,它也只會(huì)被分配到其中點(diǎn)所在的單個(gè)網(wǎng)格。可以通過增加更多網(wǎng)格來減少多個(gè)對(duì)象出現(xiàn)在同一網(wǎng)格單元中的幾率。

2.2 YOLOv5獲取與調(diào)試

2.2.1 下載yolov5代碼

如果你有g(shù)it,則使用git clone

git clone https://github.com/ultralytics/yolov5  # clone 

如果你沒有g(shù)it,你可以使用Dwonload ZIP下載代碼項(xiàng)目。
yolov5代碼地址:yolov5
注意:yolov5的代碼是最新的v8.0版本
可以通過這個(gè)鏈接下載6.0版本https://github.com/ultralytics/yolov5/tree/v6.0

2.2.2 安裝yolov5訓(xùn)練所需的第三方庫:
  1. 檢查是否正確安裝好anaconda。
    windows+r打開cmd,輸入 conda -V。若出現(xiàn)版本號(hào),則安裝成功。
    從零開始使用YOLOv5+PyQt5+OpenCV+爬蟲實(shí)現(xiàn)是否佩戴口罩檢測(cè)
  2. 檢查是否正確安裝好pytorch
import torch
if __name__ == '__main__':
     print(torch.zeros(1))

從零開始使用YOLOv5+PyQt5+OpenCV+爬蟲實(shí)現(xiàn)是否佩戴口罩檢測(cè)

  1. 進(jìn)入yolov5文件夾目錄安裝第三方庫
    cd [path_to_yolov5]
    如下圖所示
    從零開始使用YOLOv5+PyQt5+OpenCV+爬蟲實(shí)現(xiàn)是否佩戴口罩檢測(cè)
    安裝第三方庫
pip install -r requirement.txt 

如下圖所示,等待安裝完成
從零開始使用YOLOv5+PyQt5+OpenCV+爬蟲實(shí)現(xiàn)是否佩戴口罩檢測(cè)

2.2.3 下載預(yù)訓(xùn)練的權(quán)重文件

我們需要下載其預(yù)訓(xùn)練的權(quán)重文件然后再此基礎(chǔ)上進(jìn)行調(diào)整訓(xùn)練,這樣在數(shù)據(jù)集數(shù)量較小時(shí)也能取得不錯(cuò)的檢測(cè)準(zhǔn)確率。

供選擇的有yolov5s,yolov5m,yolov5l,yolov5x。模型的大小逐漸增大,訓(xùn)練時(shí)間更長,準(zhǔn)確率提高。
從零開始使用YOLOv5+PyQt5+OpenCV+爬蟲實(shí)現(xiàn)是否佩戴口罩檢測(cè)

這里我們以yolov5s為例訓(xùn)練。下載地址為yolov5s.pt
所有權(quán)重下載地址可在https://github.com/ultralytics/yolov5/releases/tag/v6.0界面找到

2.2.4 配置自己的yaml文件

配置models/yolov5s_mask.yaml 可以直接復(fù)制yolov5s.yaml文件,然后在nc即類別出進(jìn)行修改,對(duì)于口罩檢測(cè)就是戴口罩和不帶口罩兩類其數(shù)量為2。其中anchors參數(shù)表示錨框的大小,可以通過對(duì)數(shù)據(jù)集進(jìn)行knn聚類得到,這里直接使用默認(rèn)即對(duì)COCO數(shù)據(jù)集進(jìn)行聚類的結(jié)果。
從零開始使用YOLOv5+PyQt5+OpenCV+爬蟲實(shí)現(xiàn)是否佩戴口罩檢測(cè)
配置mask.yaml 。這里train指定訓(xùn)練數(shù)據(jù)集所在位置,val測(cè)試數(shù)據(jù)集所在位置,nc類別數(shù),names類別的名稱(注意順序,我們txt文件中索引0代表未戴口罩,1代表戴口罩,所以這里順序是‘no_mask’,‘mask’)

train: /home/cmy/newdataset/mask/train/ #注意修改為自己的數(shù)據(jù)集所在位置
val: /home/cmy/newdataset/mask/val/
nc: 2
names: ['no_mask','mask']

從零開始使用YOLOv5+PyQt5+OpenCV+爬蟲實(shí)現(xiàn)是否佩戴口罩檢測(cè)

2.2.5 開始訓(xùn)練
python3 train.py --img 640 --batch 8 --epochs 50 --data mask.yaml --cfg yolov5s_mask.yaml --weights "yolov5s.pt"

從零開始使用YOLOv5+PyQt5+OpenCV+爬蟲實(shí)現(xiàn)是否佩戴口罩檢測(cè)

從零開始使用YOLOv5+PyQt5+OpenCV+爬蟲實(shí)現(xiàn)是否佩戴口罩檢測(cè)
如果出現(xiàn)顯卡空間不足的情況可以改小–bath參數(shù)
從零開始使用YOLOv5+PyQt5+OpenCV+爬蟲實(shí)現(xiàn)是否佩戴口罩檢測(cè)

會(huì)在/runs/train/exp/weights/best.pt下生成最終的權(quán)重文件。
從零開始使用YOLOv5+PyQt5+OpenCV+爬蟲實(shí)現(xiàn)是否佩戴口罩檢測(cè)
將此文件復(fù)制到y(tǒng)olov5目錄下后續(xù)使用
從零開始使用YOLOv5+PyQt5+OpenCV+爬蟲實(shí)現(xiàn)是否佩戴口罩檢測(cè)

2.2.5 編寫detection方法用于后續(xù)檢測(cè)的調(diào)用

后續(xù)進(jìn)行圖片或者視頻檢測(cè)時(shí),只需要傳入YOLOv5模型和圖片,便會(huì)返回檢測(cè)后圖片

import os
import sys
from pathlib import Path

import numpy as np
import torch


FILE = Path(__file__).resolve()
ROOT = FILE.parents[0]  # YOLOv5 root directory
if str(ROOT) not in sys.path:
    sys.path.append(str(ROOT))  # add ROOT to PATH
ROOT = Path(os.path.relpath(ROOT, Path.cwd()))  # relative

from models.experimental import attempt_load
from utils.general import apply_classifier, check_img_size, check_imshow, check_requirements, check_suffix, colorstr, \
    increment_path, non_max_suppression, print_args, save_one_box, scale_coords, strip_optimizer, xyxy2xywh, LOGGER
from utils.plots import Annotator, colors
from utils.torch_utils import load_classifier, select_device, time_sync
from utils.augmentations import Albumentations, augment_hsv, copy_paste, letterbox, mixup, random_perspective

@torch.no_grad()
def detection(model,input_img):
    imgsz = 640  # inference size (pixels)
    conf_thres = 0.25   # confidence threshold
    iou_thres = 0.45   # NMS IOU threshold
    max_det = 1000  # maximum detections per image
    device = '0'  # cuda device, i.e. 0 or 0,1,2,3 or cpu
    view_img = False   # show results
    save_txt = False  # save results to *.txt
    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
    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
    # Directories
    # Initialize
    device = select_device(device)
    weights = 'best.pt'
    # # Load model
    w = str(weights[0] if isinstance(weights, list) else weights)
    classify, suffix, suffixes = False, Path(w).suffix.lower(), ['.pt', '.onnx', '.tflite', '.pb', '']
    check_suffix(w, suffixes)  # check weights have acceptable suffix
    pt, onnx, tflite, pb, saved_model = (suffix == x for x in suffixes)  # backend booleans
    stride = int(model.stride.max())
    names = model.module.names if hasattr(model, 'module') else model.names  # get class names
    imgsz = check_img_size(imgsz, s=stride)  # check image size
    img0 = input_img  # BGR
    im0s=img0
    # Padded resize
    img = letterbox(img0, imgsz, stride=32, auto=pt)[0]

    # Convert
    img = img.transpose((2, 0, 1))[::-1]  # HWC to CHW, BGR to RGB
    img = np.ascontiguousarray(img)
    bs = 1  # batch_size

    dt, seen = [0.0, 0.0, 0.0], 0
    t1 = time_sync()
    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 len(img.shape) == 3:
        img = img[None]  # expand for batch dim
    t2 = time_sync()
    dt[0] += t2 - t1
    # Inference
    if pt:
        pred = model(img, augment=augment)[0]
    t3 = time_sync()
    dt[1] += t3 - t2

    # NMS
    pred = non_max_suppression(pred, conf_thres, iou_thres, classes, agnostic_nms, max_det=max_det)
    dt[2] += time_sync() - t3
    # Process predictions
    for i, det in enumerate(pred):  # per image
        seen += 1
        im0=im0s.copy()
        annotator = Annotator(im0, line_width=line_thickness, example=str(names))
        if len(det):
            # Rescale boxes from img_size to im0 size
            det[:, :4] = scale_coords(img.shape[2:], det[:, :4], im0.shape).round()
            # Write results
            for *xyxy, conf, cls in reversed(det):
                  # Add bbox to image
                c = int(cls)  # integer class
                label = None if hide_labels else (names[c] if hide_conf else f'{names[c]} {conf:.2f}')
                annotator.box_label(xyxy, label, color=colors(c, True))
        # Stream results
        im0 = annotator.result()
        return im0

3. Pyqt5

我們通過pyqt來制作展示的界面

3.1介紹

PyQt5 是 Digia的一套 Qt5 應(yīng)用框架與 python 的結(jié)合,同時(shí)支持 python2.x和 python3.x。

這里使用的是Python 3.x。Qt庫由 Riverbank Computing開發(fā),是最強(qiáng)大的GUI庫之一 。

PyQt5 是由一系列 Python 模塊組成。超過 620 個(gè)類,6000 函數(shù)和方法。能在諸如 Unix、Windows 和Mac OS 等主流操作系統(tǒng)上運(yùn)行。PyQt5 有兩種證書,GPL和 商業(yè)證書。

3.2 window平臺(tái)安裝

PyQt5 有兩種安裝方式,一種是從官網(wǎng)下載源碼安裝,另外一種是使用 pip 安裝。

這里我推薦大家使用pip 安裝。因?yàn)樗鼤?huì)自動(dòng)根據(jù)你的Python 版本來選擇合適的 PyQt5 版本,如果是手動(dòng)下載源碼安裝,難免會(huì)選擇出錯(cuò)。建議使用比較穩(wěn)妥的安裝方式。

pip3 install PyQt5 

另外,如果你的網(wǎng)絡(luò)訪問外網(wǎng)不是很好的話建議使用豆瓣的鏡像下載,不然會(huì)很很慢或者直接安裝失敗。

pip install PyQt5 -i https://pypi.douban.com/simple

執(zhí)行以下代碼:

import sys
from PyQt5.QtWidgets import QWidget, QApplication

app = QApplication(sys.argv)
widget = QWidget()
widget.resize(640, 480)
widget.setWindowTitle("Hello, PyQt5!")
widget.show()
sys.exit(app.exec())

如果沒有報(bào)錯(cuò),彈出了一個(gè)標(biāo)題為"Hello, PyQt5!"的窗口,則說明安裝成功。
從零開始使用YOLOv5+PyQt5+OpenCV+爬蟲實(shí)現(xiàn)是否佩戴口罩檢測(cè)
若pip安裝pyqt5報(bào)錯(cuò) error: Microsoft Visual C++ 14.0 or greater is required. Get it with “Microsoft C++ Build Tools”: https://visualstudio.microsoft.com/visual-cpp-build-tools/

error: Microsoft Visual C++ 14.0 or greater is required. Get it with "Microsoft C++ Build Tools": https://visualstudio.microsoft.com/visual-cpp-build-tools/

可參考我另外一篇文章 已解決(pip安裝pyqt5報(bào)錯(cuò)) error: Microsoft Visual C++ 14.0 or greater is required. Get it with “Microsoft
對(duì)于運(yùn)行項(xiàng)目做到此即可,若對(duì)pyqt感興趣如圖形界面開發(fā)工具Qt Designer等可以參考文章https://zhuanlan.zhihu.com/p/162866700

4. OpenCV

OpenCV(開源的計(jì)算機(jī)視覺庫)是基于BSD協(xié)議,因此它可免費(fèi)用于學(xué)術(shù)和商業(yè)用途。其提供C++,C,Python和Java接口,支持Windows,Linux,Mac OS,iOS和Android。

我們使用OpenCV來處理圖片和視頻,以便于將圖片轉(zhuǎn)為Yolov5模型需要的輸入。

安裝

首先我們得先安裝另一個(gè)第三方庫numpy,這是opencv的依賴庫,沒有它無法進(jìn)行python-opencv開發(fā)。
安裝numpy:pip install numpy
安裝opencv-python: pip install opencv-python

5. 圖片檢測(cè)

5.1界面布局

首先使用pyqt設(shè)計(jì)我們界面的布局,主要為一個(gè)上傳圖片的按鈕和兩個(gè)展示板,一個(gè)展示原始圖片,一個(gè)展示我們模型進(jìn)行檢測(cè)后的圖片。這里主要使用的是網(wǎng)格布局QGridLayout()

class Qdetection1(QWidget):
    def __init__(self,model):
        super(Qdetection1, self).__init__()
        self.initUI()
        self.model=model
    def initUI(self):
        self.main_layout = QGridLayout()  # 創(chuàng)建主部件的網(wǎng)格布局
        self.setLayout(self.main_layout)  # 設(shè)置窗口主部件布局為網(wǎng)格布局
        self.button1 = QPushButton('上傳圖片')
        self.button1.clicked.connect(self.loadImage)
        self.main_layout.addWidget(self.button1)
        self.imageLabel1 = QLabel()
        self.main_layout.addWidget(self.imageLabel1)
        self.imageLabel2 = QLabel()
        self.main_layout.addWidget(self.imageLabel2)
        self.main_layout.addWidget(self.button1, 0, 0, 1, 2)
        self.main_layout.addWidget(self.imageLabel1, 2, 0, 1, 1)
        self.main_layout.addWidget(self.imageLabel2, 2, 1, 1, 1)

因?yàn)楹罄m(xù)有視頻檢測(cè)和攝像頭實(shí)時(shí)檢測(cè),為了將其集成在同一個(gè)界面里,可以使用QTabWidget()

    my_tabwidget=QTabWidget()
    tab1_widget=Qdetection1(model)
    tab2_widget = Qdetection2(model)
    tab3_widget = Qdetection3(model)
    my_tabwidget.setWindowTitle('目標(biāo)檢測(cè)演示 ')
    my_tabwidget.addTab(tab1_widget, '圖片檢測(cè)')
    my_tabwidget.addTab(tab2_widget, '視頻檢測(cè)')
    my_tabwidget.addTab(tab3_widget, '攝像頭實(shí)時(shí)檢測(cè)')
    my_tabwidget.show()

pyqt原始提供的組件并不美觀,為了美化組件可以使用qt_material。其安裝和使用都比較簡單。
安裝

pip install qt_material

使用

import sys
from PyQt5 import QtWidgets
from qt_material import apply_stylesheet

# create the application and the main window
app = QtWidgets.QApplication(sys.argv)
window = QtWidgets.QMainWindow()

# setup stylesheet
apply_stylesheet(app, theme='dark_teal.xml')

# run
window.show()
app.exec_()

對(duì)比效果
從零開始使用YOLOv5+PyQt5+OpenCV+爬蟲實(shí)現(xiàn)是否佩戴口罩檢測(cè)

從零開始使用YOLOv5+PyQt5+OpenCV+爬蟲實(shí)現(xiàn)是否佩戴口罩檢測(cè)

5.2 模型加載

我們需要將訓(xùn)練好的模型讀取加載從而使用。為了提交響應(yīng)速度和防止每個(gè)功能都重復(fù)加載,這里采用了在啟動(dòng)窗口的時(shí)候就進(jìn)行加載。

if __name__ == '__main__':
    device = select_device('0')
    # Load model
    weights = 'best.pt'
    w = str(weights[0] if isinstance(weights, list) else weights)
    classify, suffix, suffixes = False, Path(w).suffix.lower(), ['.pt', '.onnx', '.tflite', '.pb', '']
    check_suffix(w, suffixes)  # check weights have acceptable suffix
    pt, onnx, tflite, pb, saved_model = (suffix == x for x in suffixes)  # backend booleans
    stride, names = 64, [f'class{i}' for i in range(1000)]  # assign defaults
    if pt:
        model = torch.jit.load(w) if 'torchscript' in w else attempt_load(weights, map_location=device)
        stride = int(model.stride.max())  # model stride
        names = model.module.names if hasattr(model, 'module') else model.names  # get class names

5.3點(diǎn)擊上傳按鈕事件和檢測(cè)展示綁定

當(dāng)我們點(diǎn)擊上傳按鈕后通過cv2讀取文件,通過detection方法檢測(cè)圖片。然后將結(jié)果暫時(shí)到對(duì)應(yīng)的展示板上。

    def loadImage(self):
        fname, _ = QFileDialog.getOpenFileName(self, '打開文件', '.', '圖像文件(*.jpg *.png)')
        if fname is None or fname=="":
            print("未選擇圖片")
        else:
            img = cv2.imread(fname)
            np_img=detection(self.model,img)
            np_img = cv2.cvtColor(np_img, cv2.COLOR_BGR2RGB)
            img=cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
            self.imageLabel1.setPixmap(QPixmap(QImage(img.data, img.shape[1], img.shape[0], img.shape[1]*3, QImage.Format_RGB888)))
            self.imageLabel2.setPixmap(QPixmap(QImage(np_img.data, np_img.shape[1], np_img.shape[0], np_img.shape[1]*3, QImage.Format_RGB888)))

5.4完整代碼

import torch
from utils.general import  check_suffix
from utils.torch_utils import select_device
from pathlib import Path
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import time
import cv2
from mydetection import detection
from yolov5.models.experimental import attempt_load
class Qdetection1(QWidget):
    def __init__(self,model):
        super(Qdetection1, self).__init__()
        self.initUI()
        self.model=model
    def initUI(self):
        self.main_layout = QGridLayout()  # 創(chuàng)建主部件的網(wǎng)格布局
        self.setLayout(self.main_layout)  # 設(shè)置窗口主部件布局為網(wǎng)格布局
        self.button1 = QPushButton('上傳圖片')
        self.button1.clicked.connect(self.loadImage)
        self.main_layout.addWidget(self.button1)
        self.imageLabel1 = QLabel()
        self.main_layout.addWidget(self.imageLabel1)
        self.imageLabel2 = QLabel()
        self.main_layout.addWidget(self.imageLabel2)
        self.main_layout.addWidget(self.button1, 0, 0, 1, 2)
        self.main_layout.addWidget(self.imageLabel1, 2, 0, 1, 1)
        self.main_layout.addWidget(self.imageLabel2, 2, 1, 1, 1)
    def loadImage(self):
        fname, _ = QFileDialog.getOpenFileName(self, '打開文件', '.', '圖像文件(*.jpg *.png)')
        if fname is None or fname=="":
            print("未選擇圖片")
        else:
            img = cv2.imread(fname)
            np_img=detection(self.model,img)
            np_img = cv2.cvtColor(np_img, cv2.COLOR_BGR2RGB)
            img=cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
            self.imageLabel1.setPixmap(QPixmap(QImage(img.data, img.shape[1], img.shape[0], img.shape[1]*3, QImage.Format_RGB888)))
            self.imageLabel2.setPixmap(QPixmap(QImage(np_img.data, np_img.shape[1], np_img.shape[0], np_img.shape[1]*3, QImage.Format_RGB888)))
if __name__ == '__main__':
    app = QApplication(sys.argv)
    device = select_device('0')
    # Load model
    weights = 'best.pt'
    w = str(weights[0] if isinstance(weights, list) else weights)
    classify, suffix, suffixes = False, Path(w).suffix.lower(), ['.pt', '.onnx', '.tflite', '.pb', '']
    check_suffix(w, suffixes)  # check weights have acceptable suffix
    pt, onnx, tflite, pb, saved_model = (suffix == x for x in suffixes)  # backend booleans
    stride, names = 64, [f'class{i}' for i in range(1000)]  # assign defaults
    if pt:
        model = torch.jit.load(w) if 'torchscript' in w else attempt_load(weights, map_location=device)
        stride = int(model.stride.max())  # model stride
        names = model.module.names if hasattr(model, 'module') else model.names  # get class names
    my_tabwidget=QTabWidget()
    tab1_widget=Qdetection1(model)
    my_tabwidget.setWindowTitle('目標(biāo)檢測(cè)演示 ')
    my_tabwidget.addTab(tab1_widget, '圖片檢測(cè)')
    my_tabwidget.show()
    apply_stylesheet(app, theme='light_blue.xml')
    sys.exit(app.exec_())

6. 視頻檢測(cè)

視頻檢測(cè)的布局模型加載等都有圖片檢測(cè)相同。主要是綁定事件函數(shù)的處理。
我們self.cap.isOpened()方法來判斷是否到文件結(jié)尾,從而循環(huán)的讀取視頻的每一幀即每一張圖片,將這一幀的圖像使用detection方法進(jìn)行檢測(cè)。為了使其能以視頻的方式展示,每一幀圖像和下一幀圖像之間需要借助cv2.waitKey()方法進(jìn)行暫停。對(duì)于普通的視頻其暫停時(shí)間可以通過計(jì)算視頻播放幀率frameRate=self.cap.get(cv2.CAP_PROP_FPS)
wait_time=int(1000 / frameRate)獲得wait_time。

這里我考量了模型檢測(cè)的耗費(fèi)時(shí)間time_cost,對(duì)其暫停時(shí)間進(jìn)行了一個(gè)動(dòng)態(tài)的處理,模型耗費(fèi)時(shí)間小于wait_time的進(jìn)行暫停補(bǔ)時(shí),否則不暫停。

class Qdetection2(QMainWindow):
    def __init__(self,model):
        super(Qdetection2, self).__init__()
        self.initUI()
        self.model=model
    def initUI(self):
        # self.setFixedSize(960, 700)
        self.main_widget =QWidget()  # 創(chuàng)建窗口主部件
        self.main_layout = QGridLayout()  # 創(chuàng)建主部件的網(wǎng)格布局
        self.main_widget.setLayout(self.main_layout)  # 設(shè)置窗口主部件布局為網(wǎng)格布局
        self.setCentralWidget(self.main_widget)  # 設(shè)置窗口主部件
        # layout = QVBoxLayout()
        self.button1 = QPushButton('上傳視頻')
        self.button1.clicked.connect(self.loadVideo)
        self.main_layout.addWidget(self.button1)

        self.imageLabel1 = QLabel()
        self.main_layout.addWidget(self.imageLabel1)
        self.imageLabel2 = QLabel()
        self.main_layout.addWidget(self.imageLabel2)
        # self.main_layout.addWidget(self.button2)
        self.main_layout.addWidget(self.button1, 0, 0, 1, 2)
        # self.main_layout.addWidget(self.button2, 1, 0, 1, 2)
        self.main_layout.addWidget(self.imageLabel1, 2, 0, 1, 1)
        self.main_layout.addWidget(self.imageLabel2, 2, 1, 1, 1)
    def loadVideo(self):
        fname, _ = QFileDialog.getOpenFileName(self, '打開文件')
        if fname is None or fname=="":
            print("未選擇視頻")
        else:
            self.cap = cv2.VideoCapture(fname)
            frameRate=self.cap.get(cv2.CAP_PROP_FPS)
            wait_time=int(1000 / frameRate)
            while self.cap.isOpened():
                success, frame = self.cap.read()
                # RGB轉(zhuǎn)BGR
                if not success:
                    break
                # print(success)
                time_begin=time.time()
                np_img = detection(self.model, frame)
                np_img = cv2.cvtColor(np_img, cv2.COLOR_BGR2RGB)
                frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
                img = QImage(frame.data, frame.shape[1], frame.shape[0], QImage.Format_RGB888)
                self.imageLabel1.setPixmap(QPixmap.fromImage(img))
                self.imageLabel2.setPixmap(QPixmap(
                    QImage(np_img.data, np_img.shape[1], np_img.shape[0], np_img.shape[1] * 3, QImage.Format_RGB888)))
                time_cost=time.time()-time_begin
                time_cost=time_cost*1000
                print(time_cost)
                if(time_cost<wait_time):
                    cv2.waitKey(int(wait_time-time_cost))
                else:
                    cv2.waitKey(0)

7. 攝像頭實(shí)時(shí)檢測(cè)

博主終于買了一個(gè)攝像頭??梢蚤_始實(shí)現(xiàn)這個(gè)功能了。

攝像頭實(shí)時(shí)檢測(cè)的布局模型加載等都與視頻檢測(cè)相同。主要是修改視頻的來源改為從攝像頭獲取。

self.cap = cv2.VideoCapture(0,cv2.CAP_DSHOW)

這個(gè)模塊的代碼如下

class Qdetection3(QMainWindow):
    def __init__(self,model):
        super(Qdetection3, self).__init__()
        self.initUI()
        self.model=model
    def initUI(self):
        # self.setFixedSize(960, 700)
        self.main_widget =QWidget()  # 創(chuàng)建窗口主部件
        self.main_layout = QGridLayout()  # 創(chuàng)建主部件的網(wǎng)格布局
        self.main_widget.setLayout(self.main_layout)  # 設(shè)置窗口主部件布局為網(wǎng)格布局
        self.setCentralWidget(self.main_widget)  # 設(shè)置窗口主部件
        # layout = QVBoxLayout()
        self.button1 = QPushButton('開始檢測(cè)')
        self.button1.clicked.connect(self.loadVideo)
        self.main_layout.addWidget(self.button1)

        self.imageLabel1 = QLabel()
        self.main_layout.addWidget(self.imageLabel1)
        self.imageLabel2 = QLabel()
        self.main_layout.addWidget(self.imageLabel2)
        # self.main_layout.addWidget(self.button2)
        self.main_layout.addWidget(self.button1, 0, 0, 1, 2)
        # self.main_layout.addWidget(self.button2, 1, 0, 1, 2)
        self.main_layout.addWidget(self.imageLabel1, 2, 0, 1, 1)
        self.main_layout.addWidget(self.imageLabel2, 2, 1, 1, 1)
    def loadVideo(self):
        self.cap = cv2.VideoCapture(0,cv2.CAP_DSHOW)
        while self.cap.isOpened():
            success, frame = self.cap.read()
            # RGB轉(zhuǎn)BGR
            if not success:
                break
            # print(success)
            time_begin=time.time()
            np_img = detection(self.model, frame)
            np_img = cv2.cvtColor(np_img, cv2.COLOR_BGR2RGB)
            frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
            img = QImage(frame.data, frame.shape[1], frame.shape[0], QImage.Format_RGB888)
            self.imageLabel1.setPixmap(QPixmap.fromImage(img))
            self.imageLabel2.setPixmap(QPixmap(
                QImage(np_img.data, np_img.shape[1], np_img.shape[0], np_img.shape[1] * 3, QImage.Format_RGB888)))
            time_cost=time.time()-time_begin
            time_cost=time_cost*1000
            print(time_cost)
            cv2.waitKey(1)

8. 圖片、視頻、攝像頭三個(gè)模塊整合完整代碼

注意這個(gè)代碼要放在yolov5項(xiàng)目代碼中以及自己編寫的mydetection.py工具一起使用。yolov5代碼的獲取和配置在第2節(jié)YOLOV5有描述。單獨(dú)運(yùn)行這個(gè)是不行的。

import torch
from utils.general import  check_suffix
from utils.torch_utils import select_device
from pathlib import Path
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import time
import cv2
from mydetection import detection
from yolov5.models.experimental import attempt_load


class Qdetection1(QWidget):
    def __init__(self,model):
        super(Qdetection1, self).__init__()
        self.initUI()
        self.model=model
    def initUI(self):
        # self.setFixedSize(960, 700)
        self.main_layout = QGridLayout()  # 創(chuàng)建主部件的網(wǎng)格布局
        self.setLayout(self.main_layout)  # 設(shè)置窗口主部件布局為網(wǎng)格布局
        # layout = QVBoxLayout()
        self.button1 = QPushButton('上傳圖片')
        self.button1.clicked.connect(self.loadImage)
        self.main_layout.addWidget(self.button1)

        self.imageLabel1 = QLabel()
        self.main_layout.addWidget(self.imageLabel1)
        self.imageLabel2 = QLabel()
        self.main_layout.addWidget(self.imageLabel2)
        self.main_layout.addWidget(self.button1, 0, 0, 1, 2)
        # self.main_layout.addWidget(self.button2, 1, 0, 1, 2)
        self.main_layout.addWidget(self.imageLabel1, 2, 0, 1, 1)
        self.main_layout.addWidget(self.imageLabel2, 2, 1, 1, 1)
        self.setWindowTitle('目標(biāo)檢測(cè)演示 ')
    def loadImage(self):
        fname, _ = QFileDialog.getOpenFileName(self, '打開文件', '.', '圖像文件(*.jpg *.png)')
        if fname is None or fname=="":
            print("未選擇圖片")
        else:
            img = cv2.imread(fname)
            np_img=detection(self.model,img)
            np_img = cv2.cvtColor(np_img, cv2.COLOR_BGR2RGB)
            img=cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
            # cv.imshow('img', img)
            # cv.waitKey()  # 解決圖片閃退問題
            self.imageLabel1.setPixmap(QPixmap(QImage(img.data, img.shape[1], img.shape[0], img.shape[1]*3, QImage.Format_RGB888)))
            self.imageLabel2.setPixmap(QPixmap(QImage(np_img.data, np_img.shape[1], np_img.shape[0], np_img.shape[1]*3, QImage.Format_RGB888)))

    def loadText(self):
        dialog = QFileDialog()
        dialog.setFileMode(QFileDialog.AnyFile)
        dialog.setFilter(QDir.Files)

        if dialog.exec():
            filenames = dialog.selectedFiles()
            f = open(filenames[0], encoding='utf-8', mode='r')
            with f:
                data = f.read()
                self.contents.setText(data)

class Qdetection2(QMainWindow):
    def __init__(self,model):
        super(Qdetection2, self).__init__()
        self.initUI()
        self.model=model
    def initUI(self):
        # self.setFixedSize(960, 700)
        self.main_widget =QWidget()  # 創(chuàng)建窗口主部件
        self.main_layout = QGridLayout()  # 創(chuàng)建主部件的網(wǎng)格布局
        self.main_widget.setLayout(self.main_layout)  # 設(shè)置窗口主部件布局為網(wǎng)格布局
        self.setCentralWidget(self.main_widget)  # 設(shè)置窗口主部件
        # layout = QVBoxLayout()
        self.button1 = QPushButton('上傳視頻')
        self.button1.clicked.connect(self.loadVideo)
        self.main_layout.addWidget(self.button1)

        self.imageLabel1 = QLabel()
        self.main_layout.addWidget(self.imageLabel1)
        self.imageLabel2 = QLabel()
        self.main_layout.addWidget(self.imageLabel2)
        # self.main_layout.addWidget(self.button2)
        self.main_layout.addWidget(self.button1, 0, 0, 1, 2)
        # self.main_layout.addWidget(self.button2, 1, 0, 1, 2)
        self.main_layout.addWidget(self.imageLabel1, 2, 0, 1, 1)
        self.main_layout.addWidget(self.imageLabel2, 2, 1, 1, 1)
    def loadVideo(self):
        fname, _ = QFileDialog.getOpenFileName(self, '打開文件')
        if fname is None or fname=="":
            print("未選擇視頻")
        else:
            self.cap = cv2.VideoCapture(fname)
            frameRate=self.cap.get(cv2.CAP_PROP_FPS)
            wait_time=int(1000 / frameRate)
            while self.cap.isOpened():
                success, frame = self.cap.read()
                # RGB轉(zhuǎn)BGR
                if not success:
                    break
                # print(success)
                time_begin=time.time()
                np_img = detection(self.model, frame)
                np_img = cv2.cvtColor(np_img, cv2.COLOR_BGR2RGB)
                frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
                img = QImage(frame.data, frame.shape[1], frame.shape[0], QImage.Format_RGB888)
                self.imageLabel1.setPixmap(QPixmap.fromImage(img))
                self.imageLabel2.setPixmap(QPixmap(
                    QImage(np_img.data, np_img.shape[1], np_img.shape[0], np_img.shape[1] * 3, QImage.Format_RGB888)))
                time_cost=time.time()-time_begin
                time_cost=time_cost*1000
                print(time_cost)
                if(time_cost<wait_time):
                    cv2.waitKey(int(wait_time-time_cost))
                else:
                    cv2.waitKey(0)
class Qdetection3(QMainWindow):
    def __init__(self,model):
        super(Qdetection3, self).__init__()
        self.initUI()
        self.model=model
    def initUI(self):
        # self.setFixedSize(960, 700)
        self.main_widget =QWidget()  # 創(chuàng)建窗口主部件
        self.main_layout = QGridLayout()  # 創(chuàng)建主部件的網(wǎng)格布局
        self.main_widget.setLayout(self.main_layout)  # 設(shè)置窗口主部件布局為網(wǎng)格布局
        self.setCentralWidget(self.main_widget)  # 設(shè)置窗口主部件
        # layout = QVBoxLayout()
        self.button1 = QPushButton('開始檢測(cè)')
        self.button1.clicked.connect(self.loadVideo)
        self.main_layout.addWidget(self.button1)

        self.imageLabel1 = QLabel()
        self.main_layout.addWidget(self.imageLabel1)
        self.imageLabel2 = QLabel()
        self.main_layout.addWidget(self.imageLabel2)
        # self.main_layout.addWidget(self.button2)
        self.main_layout.addWidget(self.button1, 0, 0, 1, 2)
        # self.main_layout.addWidget(self.button2, 1, 0, 1, 2)
        self.main_layout.addWidget(self.imageLabel1, 2, 0, 1, 1)
        self.main_layout.addWidget(self.imageLabel2, 2, 1, 1, 1)
    def loadVideo(self):
        self.cap = cv2.VideoCapture(0,cv2.CAP_DSHOW)
        while self.cap.isOpened():
            success, frame = self.cap.read()
            # RGB轉(zhuǎn)BGR
            if not success:
                break
            # print(success)
            time_begin=time.time()
            np_img = detection(self.model, frame)
            np_img = cv2.cvtColor(np_img, cv2.COLOR_BGR2RGB)
            frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
            img = QImage(frame.data, frame.shape[1], frame.shape[0], QImage.Format_RGB888)
            self.imageLabel1.setPixmap(QPixmap.fromImage(img))
            self.imageLabel2.setPixmap(QPixmap(
                QImage(np_img.data, np_img.shape[1], np_img.shape[0], np_img.shape[1] * 3, QImage.Format_RGB888)))
            time_cost=time.time()-time_begin
            time_cost=time_cost*1000
            print(time_cost)
            cv2.waitKey(1)

from qt_material import apply_stylesheet
# import qdarkstyle
if __name__ == '__main__':
    app = QApplication(sys.argv)
    device = select_device('0')
    # Load model
    weights = 'best.pt'
    w = str(weights[0] if isinstance(weights, list) else weights)
    classify, suffix, suffixes = False, Path(w).suffix.lower(), ['.pt', '.onnx', '.tflite', '.pb', '']
    check_suffix(w, suffixes)  # check weights have acceptable suffix
    pt, onnx, tflite, pb, saved_model = (suffix == x for x in suffixes)  # backend booleans
    stride, names = 64, [f'class{i}' for i in range(1000)]  # assign defaults
    if pt:
        model = torch.jit.load(w) if 'torchscript' in w else attempt_load(weights, map_location=device)
        stride = int(model.stride.max())  # model stride
        names = model.module.names if hasattr(model, 'module') else model.names  # get class names
    my_tabwidget=QTabWidget()
    tab1_widget=Qdetection1(model)
    tab2_widget = Qdetection2(model)
    tab3_widget = Qdetection3(model)
    # my_tabwidget.setFixedSize(960, 700)
    # my_tabwidget.setFixedSize(1080, 960)
    my_tabwidget.setWindowTitle('目標(biāo)檢測(cè)演示 ')
    my_tabwidget.addTab(tab1_widget, '圖片檢測(cè)')
    my_tabwidget.addTab(tab2_widget, '視頻檢測(cè)')
    my_tabwidget.addTab(tab3_widget, '攝像頭實(shí)時(shí)檢測(cè)')
    my_tabwidget.show()
    apply_stylesheet(app, theme='light_blue.xml')
    sys.exit(app.exec_())

考慮在上文查找也麻煩。這里將mydetection.py ,以及yolov5代碼獲取鏈接yolo 再重復(fù)一遍。

import os
import sys
from pathlib import Path

import numpy as np
import torch


FILE = Path(__file__).resolve()
ROOT = FILE.parents[0]  # YOLOv5 root directory
if str(ROOT) not in sys.path:
    sys.path.append(str(ROOT))  # add ROOT to PATH
ROOT = Path(os.path.relpath(ROOT, Path.cwd()))  # relative

from utils.general import apply_classifier, check_img_size, check_imshow, check_requirements, check_suffix, colorstr, \
    increment_path, non_max_suppression, print_args, save_one_box, scale_coords, strip_optimizer, xyxy2xywh, LOGGER
from utils.plots import Annotator, colors
from utils.torch_utils import load_classifier, select_device, time_sync
from utils.augmentations import Albumentations, augment_hsv, copy_paste, letterbox, mixup, random_perspective

@torch.no_grad()
def detection(model,input_img):
       # model.pt path(s)
    imgsz = 640  # inference size (pixels)
    conf_thres = 0.25   # confidence threshold
    iou_thres = 0.45   # NMS IOU threshold
    max_det = 1000  # maximum detections per image
    device = '0'  # cuda device, i.e. 0 or 0,1,2,3 or cpu
    view_img = False   # show results
    save_txt = False  # save results to *.txt
    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
    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
    # Directories

    # Initialize
    device = select_device(device)
    weights = 'best.pt'
    # # Load model
    w = str(weights[0] if isinstance(weights, list) else weights)
    classify, suffix, suffixes = False, Path(w).suffix.lower(), ['.pt', '.onnx', '.tflite', '.pb', '']
    check_suffix(w, suffixes)  # check weights have acceptable suffix
    pt, onnx, tflite, pb, saved_model = (suffix == x for x in suffixes)  # backend booleans
    # stride, names = 64, [f'class{i}' for i in range(1000)]  # assign defaults
    # if pt:
    #     model = torch.jit.load(w) if 'torchscript' in w else attempt_load(weights, map_location=device)
    #     stride = int(model.stride.max())  # model stride
    #     names = model.module.names if hasattr(model, 'module') else model.names  # get class names
    stride = int(model.stride.max())
    names = model.module.names if hasattr(model, 'module') else model.names  # get class names
    imgsz = check_img_size(imgsz, s=stride)  # check image size
    img0 = input_img  # BGR
    im0s=img0
    # Padded resize
    img = letterbox(img0, imgsz, stride=32, auto=pt)[0]

    # Convert
    img = img.transpose((2, 0, 1))[::-1]  # HWC to CHW, BGR to RGB
    img = np.ascontiguousarray(img)
    bs = 1  # batch_size

    dt, seen = [0.0, 0.0, 0.0], 0
    t1 = time_sync()
    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 len(img.shape) == 3:
        img = img[None]  # expand for batch dim
    t2 = time_sync()
    dt[0] += t2 - t1

    # Inference
    if pt:
        # visualize = increment_path(save_dir / Path(path).stem, mkdir=True) if visualize else False
        # pred = model(img, augment=augment, visualize=visualize)[0]
        pred = model(img, augment=augment)[0]
    t3 = time_sync()
    dt[1] += t3 - t2

    # NMS
    pred = non_max_suppression(pred, conf_thres, iou_thres, classes, agnostic_nms, max_det=max_det)
    dt[2] += time_sync() - t3

    # Process predictions
    for i, det in enumerate(pred):  # per image
        seen += 1
        im0=im0s.copy()
        annotator = Annotator(im0, line_width=line_thickness, example=str(names))
        if len(det):
            # Rescale boxes from img_size to im0 size
            det[:, :4] = scale_coords(img.shape[2:], det[:, :4], im0.shape).round()
            # Write results
            for *xyxy, conf, cls in reversed(det):
                  # Add bbox to image
                c = int(cls)  # integer class
                label = None if hide_labels else (names[c] if hide_conf else f'{names[c]} {conf:.2f}')
                annotator.box_label(xyxy, label, color=colors(c, True))
        # Stream results
        im0 = annotator.result()
        return im0

歡迎看看我的新文章

歡迎看看我的新文章佩戴口罩檢測(cè)從零開始使用YOLOv5+PyQt5+OpenCV+爬蟲實(shí)現(xiàn)(支持圖片、視頻、攝像頭實(shí)時(shí)檢測(cè),UI美化升級(jí)),UI和功能都有改動(dòng)升級(jí),新改動(dòng)效果如下。從零開始使用YOLOv5+PyQt5+OpenCV+爬蟲實(shí)現(xiàn)是否佩戴口罩檢測(cè)文章來源地址http://www.zghlxwxcb.cn/news/detail-448433.html

到了這里,關(guān)于從零開始使用YOLOv5+PyQt5+OpenCV+爬蟲實(shí)現(xiàn)是否佩戴口罩檢測(cè)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 智能零售柜商品識(shí)別從零開始使用YOLOv5+PyQt5+OpenCV實(shí)現(xiàn)(支持圖片、視頻、攝像頭實(shí)時(shí)檢測(cè))

    智能零售柜商品識(shí)別從零開始使用YOLOv5+PyQt5+OpenCV實(shí)現(xiàn)(支持圖片、視頻、攝像頭實(shí)時(shí)檢測(cè))

    全流程 教程,從數(shù)據(jù)采集到模型使用到最終展示。若有任何疑問和建議歡迎評(píng)論區(qū)討論。 先放上最終實(shí)現(xiàn)效果 檢測(cè)效果 智能零售柜商品識(shí)別,當(dāng)顧客將自己選購的商品放置在制定區(qū)域的時(shí)候,能精準(zhǔn)地識(shí)別每一個(gè)商品,從而能夠返回完整地購物清單及計(jì)算顧客應(yīng)付的實(shí)際商

    2024年02月08日
    瀏覽(22)
  • YOLOv5入門實(shí)踐(5)——從零開始,手把手教你訓(xùn)練自己的目標(biāo)檢測(cè)模型(包含pyqt5界面)

    YOLOv5入門實(shí)踐(5)——從零開始,手把手教你訓(xùn)練自己的目標(biāo)檢測(cè)模型(包含pyqt5界面)

    ? 通過前幾篇文章,相信大家已經(jīng)學(xué)會(huì)訓(xùn)練自己的數(shù)據(jù)集了。本篇是YOLOv5入門實(shí)踐系列的最后一篇,也是一篇總結(jié),我們?cè)賮硪黄鸢粗?配置環(huán)境--標(biāo)注數(shù)據(jù)集--劃分?jǐn)?shù)據(jù)集--訓(xùn)練模型--測(cè)試模型--推理模型 的步驟,從零開始,一起實(shí)現(xiàn)自己的目標(biāo)檢測(cè)模型吧! 前期回顧: YOLO

    2023年04月26日
    瀏覽(32)
  • python中的yolov5結(jié)合PyQt5,使用QT designer設(shè)計(jì)界面沒正確啟動(dòng)的解決方法

    python中的yolov5結(jié)合PyQt5,使用QT designer設(shè)計(jì)界面沒正確啟動(dòng)的解決方法

    一、窗體設(shè)計(jì)test: 默認(rèn)你已經(jīng)設(shè)計(jì)好了窗體后: 這時(shí)你需要的是保存生成的untitle.ui到某個(gè)文件夾下,然后在命令行中獎(jiǎng).ui轉(zhuǎn)換為.py(,通過??pyqt5???提供的轉(zhuǎn)換工具,將??ui???文件轉(zhuǎn)換成??python??的代碼) 或者使用在PyCharm中安裝的工具: 然后你會(huì)看到mai

    2024年02月07日
    瀏覽(32)
  • YOLOV5 + PYQT5單目測(cè)距(四)

    YOLOV5 + PYQT5單目測(cè)距(四)

    系統(tǒng):win 10 YOLO版本:yolov5 5.0 拍攝視頻設(shè)備:安卓手機(jī) 電腦顯卡:NVIDIA 2080Ti(CPU也可以跑,GPU只是起到加速推理效果) 詳見文章 YOLOV5 + 單目測(cè)距(python) 首先安裝一下pyqt5 接著再pycharm設(shè)置里配置一下 添加下面兩個(gè)工具: 工具1:Qt Designer 工具2:PyUIC 實(shí)驗(yàn)采用的是一個(gè)博主

    2024年02月08日
    瀏覽(24)
  • PyQt5 | 手把手教你YOLOv5添加PyQt頁面

    PyQt5 | 手把手教你YOLOv5添加PyQt頁面

    演示視頻:YOLOv5/v7添加 PyQT5 頁面 我的畢業(yè)有救了 !嗶哩嗶哩

    2024年02月01日
    瀏覽(21)
  • Yolov5(v5.0) + pyqt5界面設(shè)計(jì)

    Yolov5(v5.0) + pyqt5界面設(shè)計(jì)

    ?2.1 添加QtDesigner ?Qt Designer 是通過拖拽的方式放置控件,并實(shí)時(shí)查看控件效果進(jìn)行快速UI設(shè)計(jì) 位置 內(nèi)容 name 可以隨便命名,只要便于記憶就可以,本次采取通用命名:Qt Designer Program designer.exe路徑,一般在python中.Librarybindesigner.exe Arguments 固定格式,直接復(fù)制也可: $FileDir

    2024年04月15日
    瀏覽(23)
  • 基于yolov5的pyqt5目標(biāo)檢測(cè)圖形上位機(jī)工具【附工程代碼】

    基于yolov5的pyqt5目標(biāo)檢測(cè)圖形上位機(jī)工具【附工程代碼】

    【后附工程代碼】這是一個(gè)集成yolov5算法的目標(biāo)檢測(cè)的上位機(jī)軟件,主要涉及的界面: B站視頻演示 1. 用戶登入 2.用戶注冊(cè) 3. 忘記密碼(暫未開發(fā)) 特別說明:這里的用戶登入有倆種方式,主要是使用mysql數(shù)據(jù)庫。 若需要使用自己的數(shù)據(jù)庫,記得將以下的信息改未自己的對(duì)

    2024年02月03日
    瀏覽(25)
  • 基于yolov5-master和pyqt5的森林火災(zāi)監(jiān)測(cè)軟件

    基于yolov5-master和pyqt5的森林火災(zāi)監(jiān)測(cè)軟件

    火災(zāi)作為威脅人類生命生產(chǎn)安全的隱患之一,一直是人們關(guān)注的重點(diǎn)。傳統(tǒng)的火災(zāi)監(jiān)測(cè)裝置根據(jù)溫度來檢測(cè)火災(zāi),不僅靈敏度差,而且反饋時(shí)間長,常常會(huì)出現(xiàn)消防員收到警報(bào)消息時(shí),火室已經(jīng)無法控制。 森林火災(zāi)監(jiān)測(cè)系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)是一項(xiàng)基于深度學(xué)習(xí)技術(shù)的創(chuàng)新性研究

    2024年01月22日
    瀏覽(21)
  • YOLOv5目標(biāo)檢測(cè):ubuntu1804從零開始使用YOLOv5訓(xùn)練自己的數(shù)據(jù)集(親測(cè)有效,一步一步來一定行)

    YOLOv5目標(biāo)檢測(cè):ubuntu1804從零開始使用YOLOv5訓(xùn)練自己的數(shù)據(jù)集(親測(cè)有效,一步一步來一定行)

    (1)首先需要安裝Anaconda,這個(gè)網(wǎng)上教程太多了,下載最新版本就行,在這里就不在贅述了。 (2)安裝Pytorch 1. 首先創(chuàng)建python3.6以上版本的conda環(huán)境,在這里我用的是python3.8,環(huán)境名稱為mypytorch 2. 激活創(chuàng)建好的conda環(huán)境 3.在PyTorch官網(wǎng)上選擇指定版本安裝Pytorch Install PyTorch: h

    2024年02月19日
    瀏覽(93)
  • 【YOLOV5 入門】——Pyside6/PyQt5可視化UI界面&后端邏輯

    【YOLOV5 入門】——Pyside6/PyQt5可視化UI界面&后端邏輯

    聲明:筆記是做項(xiàng)目時(shí)根據(jù)B站博主視頻學(xué)習(xí)時(shí)自己編寫,請(qǐng)勿隨意轉(zhuǎn)載! VScode/Pycharm 終端進(jìn)入虛擬環(huán)境后,輸入下面代碼安裝 pyside6 ,若用的 Pycharm 作為集成開發(fā)環(huán)境,也下載個(gè) pyqt5 : 安裝完 pyside6 時(shí)其實(shí)一并安裝了 qtdesigner ,這個(gè)工具可讓我們以拖拽的方式設(shè)計(jì)界面,按

    2024年04月16日
    瀏覽(173)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包