opencv調用yolo3


# coding:utf-8

import cv2
import argparseimport numpy as np

parser = argparse.ArgumentParser(description='manual to this script')
parser.add_argument("--videoOrImage", default=0)
args = parser.parse_args()

'''初始化參數'''
confThreshold = 0.25  # 置信度,忽略掉低於置信度閾值參數的所有框
nmsThreshold = 0.4  # 非極大抑制參數,對其余框執行非極大值抑制,這會消除多余的重疊邊界框
inpWidth = 416
inpHeight = 416

modelConfiguration = r"C:\Users\Administrator\Desktop\darknet\cfg\yolov3.cfg";
modelWeights = r'C:\Users\Administrator\Desktop\darknet_weights\yolov3.weights';
classesFile = r"C:\Users\Administrator\Desktop\darknet\data\coco.names";
classes = None
'''
t是windows平台特有的所謂text mode(文本模式),區別在於會自動識別windows平台的換行符。類Unix平台的換行符是\n,
而windows平台用的是\r\n兩個ASCII字符來表示換行,python內部采用的是\n來表示換行符。rt模式下,python在讀取文本時會自動把\r\n轉換成\n.
'''
with open(classesFile, 'rt') as f:
    classes = f.read().rstrip('\n').split('\n')

COLORS = np.random.randint(0, 255, size=(len(classes), 3), dtype='uint8')  # 顏色

#加載 網絡配置與訓練的權重文件 構建網絡
net = cv2.dnn.readNetFromDarknet(modelConfiguration, modelWeights)
cap = cv2.VideoCapture(args.videoOrImage)
cv2.namedWindow("win", cv2.WINDOW_NORMAL)
while cv2.waitKey(1) < 0:
    res, frame = cap.read()
    if not res:
        break

    '''
    從輸入圖像或視頻流中讀取幀后,將通過 blobFromImage 函數將其轉換為神經網絡的輸入blob。在此過程中,
    它使用比例因子1/255 將圖像像素值縮放到0到1的目標范圍。它還將圖像的大小縮放為給定的大小(416,416)而不進行裁剪。
    請注意,我們不在此處執行任何均值減法,因此將[0,0,0]傳遞給函數的mean參數,並將swapRB參數保持為其默認值1。
    '''
    blob = cv2.dnn.blobFromImage(frame, 1/255.0, (inpWidth, inpHeight), [0, 0, 0], swapRB=1, crop=False)

    '''
    然后輸出blob作為輸入傳遞到網絡,並運行前向傳遞以獲得預測邊界框列表作為網絡的輸出。這些框經過后處理步驟,以濾除具有低置信度分數的那些框。
    '''
    net.setInput(blob)
    '''
    OpenCV 的 Net 類中的 forward 函數需要知道它的結束層。 想要遍歷整個網絡就需要識別網絡的最后一層。 
    我們通過使用函數getUnconnectedOutLayers()來實現,該函數給出了未連接的輸出層名稱,這些輸出層基本上是網絡的最后一層。 
    然后我們運行網絡的前向傳遞以從輸出層獲得輸出
    '''
    layersNames = net.getLayerNames()  # ['conv_0', 'bn_0', 'relu_0', 'conv_1', 'bn_1', .......]
    '''
    net.getUnconnectedOutLayers():得到未連接層得序號 例如:[[200], [227]]
    i[0]-1  取out中的數字  [200][0]=200  layersNames(199)= 'yolo_82'
    '''
    outs = net.forward([layersNames[i[0] - 1] for i in net.getUnconnectedOutLayers()])  # net.forward(['conv_0', 'bn_0'])得到了所有輸出結果的輸出

    '''
    網絡 outs 每個輸出都由一組 類數目+5 個元素的向量表示。前4個元素代表center_x,center_y,width和height。 
    第五個元素表示邊界框包圍對象的置信度。其余元素是與每個類相關的置信度(即對象類型)。 該框被分配到與該框的最高分相對應的那一類。
    '''
    frameHeight = frame.shape[0]
    frameWidth = frame.shape[1]

    classIds = []
    confidences = []
    boxes = []

    for out in outs:
        for detection in out:  # detection的前五元素(中心坐標點以及長寬)[center_x,center_y,width,height,邊界框包圍對象的置信度,。。。。。。]
            scores = detection[5:]  # 所有元素的置信度
            classId = np.argmax(scores, axis=0)  # 取出最大置信度所對應的索引
            confidence = scores[classId]  # g根據索引取出最大的置信度
            if confidence > confThreshold:  # 判斷當前的置信度是否大於設定的閾值
                center_x = int(detection[0] * frameWidth)
                center_y = int(detection[1] * frameHeight)
                width = int(detection[2] * frameWidth)
                height = int(detection[3] * frameHeight)
                left = int(center_x - width / 2)
                top = int(center_y - height / 2)
                classIds.append(classId)  # 將最大置信度的索引也就是類別的索引加入集合
                confidences.append(float(confidence))  # 將置信度加入集合
                boxes.append([left, top, width, height])  # 將坐標左上和長寬加入box

    '''
    對其置信度等於或大於閾值的框進行非極大值抑制。 這將會減少重疊框的數量。
    '''
    indices = cv2.dnn.NMSBoxes(boxes, confidences, confThreshold, nmsThreshold)

    for i in indices:
        i = i[0]
        box = boxes[i]
        left = box[0]
        top = box[1]
        width = box[2]
        height = box[3]
        color = [int(c) for c in COLORS[classIds[i]]]
        cv2.rectangle(frame, (left, top), (left + width, top + height), color, 2)
        text = "{}".format(classes[classIds[i]])
        cv2.putText(frame, text, (left, top - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 2)
    cv2.imshow("win", frame)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM