python通過(guò)yolo算法識(shí)別圖片中的對(duì)象

1 場(chǎng)景

YOLO全稱You Only Look Once,YOLO實(shí)現(xiàn)了自動(dòng)駕駛汽車等前沿技術(shù)中使用的實(shí)時(shí)對(duì)象檢測(cè)

可以實(shí)現(xiàn)對(duì)圖像中的對(duì)象進(jìn)行識(shí)別和定位,如下效果:

1.png

這里不研究算法,只研究,在python環(huán)境下,如何使用yolo進(jìn)行圖像中物體的識(shí)別定位

2 官網(wǎng)

2.1 官方地址

YOLO使用相關(guān)網(wǎng)站如下:

http://pjreddie.com/yolo/

github地址:

https://github.com/pjreddie/darknet

2.2 百度網(wǎng)盤(pán)

如下為作者在百度網(wǎng)盤(pán)中備份的相關(guān)文件(配置文件+演示文件):

鏈接:https://pan.baidu.com/s/1dsXTUB_MHAeEnPDeJBNvHg
提取碼:i8pm

3 版本

python:3.6.3

4 依賴

(1)安裝cv2依賴

pip install opencv-python

(2)安裝numpy依賴

pip install numpy

4 代碼

4.1 準(zhǔn)備

(1)創(chuàng)建yolo配置文件

創(chuàng)建配置文件夾:cfg

將配置文件下載后,拷貝到cfg配置文件中:

鏈接:https://pan.baidu.com/s/1x_xIPC19lQ8sAljXtZqWWg
提取碼:6w0x

(2)創(chuàng)建測(cè)試文件夾

測(cè)試文件夾:yoloSrc

輸出文件夾:yoloRes

4.2 引入依賴

import cv2
import numpy as np
import os
import time

4.3 定義函數(shù)

def yolo_detect(pathIn='',
                pathOut=None,
                label_path='cfg/coco.names',
                config_path='cfg/yolov3.cfg',
                weights_path='cfg/yolov3.weights',
                confidence_thre=0.5,
                nms_thre=0.3,
                jpg_quality=80):
    '''
    pathIn:原始圖片的路徑
    pathOut:結(jié)果圖片的路徑
    label_path:類別標(biāo)簽文件的路徑
    config_path:模型配置文件的路徑
    weights_path:模型權(quán)重文件的路徑
    confidence_thre:0-1,置信度(概率/打分)閾值,即保留概率大于這個(gè)值的邊界框,默認(rèn)為0.5
    nms_thre:非極大值抑制的閾值,默認(rèn)為0.3
    jpg_quality:設(shè)定輸出圖片的質(zhì)量,范圍為0到100,默認(rèn)為80,越大質(zhì)量越好
    '''

    # 加載類別標(biāo)簽文件
    LABELS = open(label_path).read().strip().split("\n")
    nclass = len(LABELS)

    # 為每個(gè)類別的邊界框隨機(jī)匹配相應(yīng)顏色
    np.random.seed(42)
    COLORS = np.random.randint(0, 255, size=(nclass, 3), dtype='uint8')

    # 載入圖片并獲取其維度
    base_path = os.path.basename(pathIn)
    img = cv2.imread(pathIn)
    (H, W) = img.shape[:2]

    # 加載模型配置和權(quán)重文件
    print('從硬盤(pán)加載YOLO......')
    net = cv2.dnn.readNetFromDarknet(config_path, weights_path)

    # 獲取YOLO輸出層的名字
    ln = net.getLayerNames()
    ln = [ln[i[0] - 1] for i in net.getUnconnectedOutLayers()]

    # 將圖片構(gòu)建成一個(gè)blob,設(shè)置圖片尺寸,然后執(zhí)行一次
    # YOLO前饋網(wǎng)絡(luò)計(jì)算,最終獲取邊界框和相應(yīng)概率
    blob = cv2.dnn.blobFromImage(img, 1 / 255.0, (416, 416), swapRB=True, crop=False)
    net.setInput(blob)
    start = time.time()
    layerOutputs = net.forward(ln)
    end = time.time()

    # 顯示預(yù)測(cè)所花費(fèi)時(shí)間
    print('YOLO模型花費(fèi) {:.2f} 秒來(lái)預(yù)測(cè)一張圖片'.format(end - start))

    # 初始化邊界框,置信度(概率)以及類別
    boxes = []
    confidences = []
    classIDs = []

    # 迭代每個(gè)輸出層,總共三個(gè)
    for output in layerOutputs:
        # 迭代每個(gè)檢測(cè)
        for detection in output:
            # 提取類別ID和置信度
            scores = detection[5:]
            classID = np.argmax(scores)
            confidence = scores[classID]

            # 只保留置信度大于某值的邊界框
            if confidence > confidence_thre:
                # 將邊界框的坐標(biāo)還原至與原圖片相匹配,記住YOLO返回的是
                # 邊界框的中心坐標(biāo)以及邊界框的寬度和高度
                box = detection[0:4] * np.array([W, H, W, H])
                (centerX, centerY, width, height) = box.astype("int")

                # 計(jì)算邊界框的左上角位置
                x = int(centerX - (width / 2))
                y = int(centerY - (height / 2))

                # 更新邊界框,置信度(概率)以及類別
                boxes.append([x, y, int(width), int(height)])
                confidences.append(float(confidence))
                classIDs.append(classID)

    # 使用非極大值抑制方法抑制弱、重疊邊界框
    idxs = cv2.dnn.NMSBoxes(boxes, confidences, confidence_thre, nms_thre)

    # 確保至少一個(gè)邊界框
    if len(idxs) > 0:
        # 迭代每個(gè)邊界框
        for i in idxs.flatten():
            # 提取邊界框的坐標(biāo)
            (x, y) = (boxes[i][0], boxes[i][1])
            (w, h) = (boxes[i][2], boxes[i][3])

            # 繪制邊界框以及在左上角添加類別標(biāo)簽和置信度
            color = [int(c) for c in COLORS[classIDs[i]]]
            cv2.rectangle(img, (x, y), (x + w, y + h), color, 2)
            text = '{}: {:.3f}'.format(LABELS[classIDs[i]], confidences[i])
            (text_w, text_h), baseline = cv2.getTextSize(text, cv2.FONT_HERSHEY_SIMPLEX, 0.5, 2)
            cv2.rectangle(img, (x, y - text_h - baseline), (x + text_w, y), color, -1)
            cv2.putText(img, text, (x, y - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0), 2)

    # 輸出結(jié)果圖片
    if pathOut is None:
        cv2.imwrite('with_box_' + base_path, img, [int(cv2.IMWRITE_JPEG_QUALITY), jpg_quality])
    else:
        cv2.imwrite(pathOut, img, [int(cv2.IMWRITE_JPEG_QUALITY), jpg_quality])

4.4 使用

if __name__ == '__main__':
   yolo_detect('yoloSrc/trunk.jpg', 'yoloRes/trunk.jpg')

4.5 結(jié)果

輸出日志:

從硬盤(pán)加載YOLO......
YOLO模型花費(fèi) 1.75 秒來(lái)預(yù)測(cè)一張圖片

(1)原文件

trunk.jpg

(2)輸出結(jié)果

監(jiān)測(cè)結(jié)果為truck,后面的0.999為對(duì)象匹配度

trunk-2.jpg
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容