0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

手把手教你使用LabVIEW OpenCV dnn實(shí)現(xiàn)物體識(shí)別(Object Detection)含源碼

LabVIEW深度學(xué)習(xí)實(shí)戰(zhàn) ? 來(lái)源:wangstoudamire ? 作者:wangstoudamire ? 2023-03-10 15:58 ? 次閱讀

前言

今天和大家一起分享如何使用LabVIEW調(diào)用pb模型實(shí)現(xiàn)物體識(shí)別,本博客中使用的智能工具包可到主頁(yè)置頂博客LabVIEW AI視覺(jué)工具包(非NI Vision)下載與安裝教程中下載

一、物體識(shí)別算法原理概述

1、物體識(shí)別的概念

物體識(shí)別也稱 目標(biāo)檢測(cè) ,目標(biāo)檢測(cè)所要解決的問(wèn)題是目標(biāo)在哪里以及其狀態(tài)的問(wèn)題。但是,這個(gè)問(wèn)題并不是很容易解決。形態(tài)不合理,對(duì)象出現(xiàn)的區(qū)域不確定,更不用說(shuō)對(duì)象也可以是多個(gè)類別。**

**在這里插入圖片描述

目標(biāo)檢測(cè)用的比較多的主要是RCNN,spp- net,fast- rcnn,faster- rcnn;YOLO系列,如YOLOV3和YOLOV4;除此之外還有SSD,ResNet等。

2、Yolo算法原理概述

Yolo的識(shí)別原理簡(jiǎn)單清晰。對(duì)于輸入的圖片,將整張圖片分為7×7(7為參數(shù),可調(diào))個(gè)方格。當(dāng)某個(gè)物體的中心點(diǎn)落在了某個(gè)方格中,該方格則負(fù)責(zé)預(yù)測(cè)該物體。每個(gè)方格會(huì)為被預(yù)測(cè)物體產(chǎn)生2(參數(shù),可調(diào))個(gè)候選框并生成每個(gè)框的置信度。最后選取置信度較高的方框作為預(yù)測(cè)結(jié)果。

在這里插入圖片描述

二、opencv調(diào)用darknet物體識(shí)別模型(yolov3/yolov4)

相關(guān)源碼及模型在darknt文件夾下

在這里插入圖片描述

使用darknet訓(xùn)練yolo的模型,生成weights文件。使用opencv調(diào)用生成的模型

1、darknet模型的獲取

文件含義:

  • **cfg文件:模型描述文件 **
  • weights文件:模型權(quán)重文件

Yolov3獲取鏈接:

https://github.com/pjreddie/darknet/blob/master/cfg/yolov3.cfg

https://pjreddie.com/media/files/yolov3.weights

Yolov4獲取鏈接:

https://github.com/AlexeyAB/darknet/releases/download/darknet_yolo_v3_optimal/yolov4.cfg

https://github.com/AlexeyAB/darknet/releases/download/darknet_yolo_v3_optimal/yolov4.weights

2、python調(diào)用darknet模型實(shí)現(xiàn)物體識(shí)別

(1)dnn模塊調(diào)用darknet模型

net = cv2.dnn.readNetFromDarknet("yolov3/yolov3.cfg", "yolov3/yolov3.weights")

(2)獲取三個(gè)輸出端的LayerName

使用getUnconnectedOutLayer獲取三個(gè)只有輸入,沒(méi)有輸出的層的名字,Yolov3的三個(gè)輸出端層名為:['yolo_82', 'yolo_94', 'yolo_106']

def getOutputsNames(net):
    # Get the names of all the layers in the network
    layersNames = net.getLayerNames()
    # Get the names of the output layers, i.e. the layers with unconnected outputs
    return [layersNames[i - 1] for i in net.getUnconnectedOutLayers()]

**(3)圖像預(yù)處理 **

使用blobFromImage將圖像轉(zhuǎn)為image

Size=(416,416)或(608,608)

Scale=1/255

Means=[0,0,0]

blob = cv2.dnn.blobFromImage(frame, 1/255, (416, 416), [0,0,0], 1, crop=False)

(4)推理

使用net.forward(multiNames)獲取多個(gè)層的結(jié)果,其中g(shù)etOutputsNames(net)=['yolo_82', 'yolo_94', 'yolo_106']

net.setInput(blob)
outs = net.forward(getOutputsNames(net))

**(5)后處理(postrocess) **

獲取的結(jié)果(outs)里面有三個(gè)矩陣(out),每個(gè)矩陣的大小為85*n,n表示檢測(cè)到了n個(gè)物體,85的排列順序是這樣的:

  • 第0列代表物體中心x在圖中的位置(0~1)
  • 第1列表示物體中心y在圖中的位置(0~1)
  • 第2列表示物體的寬度
  • 第3列表示物體的高度
  • 第4列是置信概率,值域?yàn)閇0-1],用來(lái)與閾值作比較決定是否標(biāo)記目標(biāo)
  • 第5~84列為基于COCO數(shù)據(jù)集的80分類的標(biāo)記權(quán)重,最大的為輸出分類。使用這些參數(shù)保留置信度高的識(shí)別結(jié)果(confidence>confThreshold)
def postprocess(frame, outs):
    frameHeight = frame.shape[0]
    frameWidth = frame.shape[1]
    classIds = []
    confidences = []
    boxes = []
    classIds = []
    confidences = []
    boxes = []
    for out in outs:
        for detection in out:
            scores = detection[5:]
            classId = np.argmax(scores)
            confidence = scores[classId]
            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])
    print(boxes)
    print(confidences)

**(6)后處理(postrocess) **

使用NMSBoxes函數(shù)過(guò)濾掉重復(fù)識(shí)別的區(qū)域。

indices = cv.dnn.NMSBoxes(boxes, confidences, confThreshold, nmsThreshold)  
    for i in indices:
        box = boxes[i]
        left = box[0]
        top = box[1]
        width = box[2]
        height = box[3]
        drawPred(classIds[i], confidences[i], left, top, left + width, top + height)

(7)畫出檢測(cè)到的對(duì)象

def drawPred(classId, conf, left, top, right, bottom):
    # Draw a bounding box.
    cv.rectangle(frame, (left, top), (right, bottom), (0, 0, 255))
     
    label = '%.2f' % conf
         
    # Get the label for the class name and its confidence
    if classes:
        assert(classId < len(classes))
        label = '%s:%s' % (classes[classId], label)

    #Display the label at the top of the bounding box
    labelSize, baseLine = cv.getTextSize(label, cv.FONT_HERSHEY_SIMPLEX, 0.5, 1)
    top = max(top, labelSize[1])
    cv.putText(frame, label, (left, top), cv.FONT_HERSHEY_SIMPLEX, 0.5, (255,255,255))

(8)完整源碼及檢測(cè)結(jié)果(cv_call_yolo.py)

import cv2
cv=cv2
import numpy as np
import time
net = cv2.dnn.readNetFromDarknet("yolov3/yolov3.cfg", "yolov3/yolov3.weights")
net.setPreferableBackend(cv2.dnn.DNN_BACKEND_CUDA)
net.setPreferableTarget(cv2.dnn.DNN_TARGET_CUDA)
?
confThreshold = 0.5  #Confidence threshold
nmsThreshold = 0.4   #Non-maximum suppression threshold
frame=cv2.imread("dog.jpg")
classesFile = "coco.names";
classes = None
with open(classesFile, 'rt') as f:
    classes = f.read().rstrip('\\\\\\\\\\\\\\\\n').split('\\\\\\\\\\\\\\\\n')
?
def getOutputsNames(net):
    # Get the names of all the layers in the network
    layersNames = net.getLayerNames()
    # Get the names of the output layers, i.e. the layers with unconnected outputs
    return [layersNames[i - 1] for i in net.getUnconnectedOutLayers()]
print(getOutputsNames(net))
# Remove the bounding boxes with low confidence using non-maxima suppression
?
def postprocess(frame, outs):
    frameHeight = frame.shape[0]
    frameWidth = frame.shape[1]
    classIds = []
    confidences = []
    boxes = []
    # Scan through all the bounding boxes output from the network and keep only the
    # ones with high confidence scores. Assign the box's class label as the class with the highest score.
    classIds = []
    confidences = []
    boxes = []
    for out in outs:
        for detection in out:
            scores = detection[5:]
            classId = np.argmax(scores)
            confidence = scores[classId]
            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])

    # Perform non maximum suppression to eliminate redundant overlapping boxes with
    # lower confidences.
    print(boxes)
    print(confidences)  
    indices = cv.dnn.NMSBoxes(boxes, confidences, confThreshold, nmsThreshold) 
    for i in indices:
        #print(i)
        #i = i[0]
        box = boxes[i]
        left = box[0]
        top = box[1]
        width = box[2]
        height = box[3]
        drawPred(classIds[i], confidences[i], left, top, left + width, top + height)
?
    # Draw the predicted bounding box
def drawPred(classId, conf, left, top, right, bottom):
    # Draw a bounding box.
    cv.rectangle(frame, (left, top), (right, bottom), (0, 0, 255))
    label = '%.2f' % conf    
    # Get the label for the class name and its confidence
    if classes:
        assert(classId < len(classes))
        label = '%s:%s' % (classes[classId], label)
    #Display the label at the top of the bounding box
    labelSize, baseLine = cv.getTextSize(label, cv.FONT_HERSHEY_SIMPLEX, 0.5, 1)
    top = max(top, labelSize[1])
    cv.putText(frame, label, (left, top), cv.FONT_HERSHEY_SIMPLEX, 0.5, (255,255,255))
blob = cv2.dnn.blobFromImage(frame, 1/255, (416, 416), [0,0,0], 1, crop=False)
t1=time.time()
net.setInput(blob)
outs = net.forward(getOutputsNames(net))
print(time.time()-t1)
postprocess(frame, outs)
t, _ = net.getPerfProfile()
label = 'Inference time: %.2f ms' % (t * 1000.0 / cv.getTickFrequency())
cv.putText(frame, label, (0, 15), cv.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255))
cv2.imshow("result",frame)
?

在這里插入圖片描述

3、LabVIEW調(diào)用darknet模型實(shí)現(xiàn)物體識(shí)別yolo_example.vi

(1)LabVIEW調(diào)用yolov3的方式及步驟和python類似,源碼如下所示:

在這里插入圖片描述

將待識(shí)別圖片與yolo_example.vi置于同一路徑下,即可進(jìn)行物體識(shí)別

(2)識(shí)別結(jié)果如下:

在這里插入圖片描述

4、LabVIEW實(shí)現(xiàn)實(shí)時(shí)攝像頭物體識(shí)別(yolo_example_camera.vi)

(1)使用GPU加速

使用順序結(jié)構(gòu)檢測(cè)神經(jīng)網(wǎng)絡(luò)推理的時(shí)間

在這里插入圖片描述

比較使用GPU和不使用GPU兩種情況下的推理速度

普通模式 :net.serPerferenceBackend(0),net.serPerferenceTarget(0)**

** Nvidia GPU模式 :net.serPreferenceBackend(5), net.serPerferenceTarget(6)**

**在這里插入圖片描述

**注:普通的c++、python、LabVIEW版本的opencv,即便選了GPU模式也沒(méi)用,程序仍然運(yùn)行在CPU上,需要安裝CUDA和CUDNN后重新從源碼編譯opencv **

(2)程序源碼如下:

在這里插入圖片描述

(3)物體識(shí)別結(jié)果如下:

在這里插入圖片描述

注意,使用如上程序,可以點(diǎn)擊STOP按鈕,停止本次物體識(shí)別,也可勾選使用GPU進(jìn)行加速

(4)使用GPU加速結(jié)果:

在這里插入圖片描述

三、tensorflow的物體識(shí)別模型調(diào)用

相關(guān)源碼及模型在tf1文件夾下

在這里插入圖片描述

1、下載預(yù)訓(xùn)練模型并生成pbtxt文件

(1)下載ssd_mobilenet_v2_coco,下載地址如下:

http://download.tensorflow.org/models/object_detection/ssd_mobilenet_v2_coco_2018_03_29.tar.gz

(2)解壓后的文件內(nèi)容

在這里插入圖片描述

(3)根據(jù)pb模型生成pbtxt文件

運(yùn)行 tf_text_graph_ssd.py以生成pptxt文件

在cmd中運(yùn)行:

**python tf_text_graph_ssd.py --input ssd_mobilenet_v1_coco_2017_11_17/frozen_inference_graph.pb --config ssd_mobilenet_v1_coco_2017_11_17/ssd_mobilenet_v1_coco.config --output ssd_mobilenet_v1_coco_2017_11_17.pbtxt **

2、LabVIEW調(diào)用tensorflow模型推理并實(shí)現(xiàn)物體識(shí)別(callpb.vi)

(1)程序源碼如下:

在這里插入圖片描述

(2)運(yùn)行結(jié)果如下:

在這里插入圖片描述

四、項(xiàng)目源碼及模型下載

鏈接: https://pan.baidu.com/s/1zwbLQe0VehGhsqNIHyaFRw?pwd=8888

**提取碼:8888 **

總結(jié)拓展

**可以使用Yolov3訓(xùn)練自己的數(shù)據(jù)集,具體訓(xùn)練方法可參考博客

可實(shí)現(xiàn)案例:口罩佩戴識(shí)別、肺炎分類、CT等,如口罩佩戴檢測(cè)

在這里插入圖片描述

審核編輯 黃宇

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • LabVIEW
    +關(guān)注

    關(guān)注

    1995

    文章

    3670

    瀏覽量

    333938
  • 目標(biāo)檢測(cè)
    +關(guān)注

    關(guān)注

    0

    文章

    223

    瀏覽量

    15939
  • OpenCV
    +關(guān)注

    關(guān)注

    32

    文章

    642

    瀏覽量

    42551
  • 物體識(shí)別
    +關(guān)注

    關(guān)注

    0

    文章

    16

    瀏覽量

    7580
  • dnn
    dnn
    +關(guān)注

    關(guān)注

    0

    文章

    61

    瀏覽量

    9239
收藏 人收藏

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    【匯總篇】小草手把手教你 LabVIEW 串口儀器控制

    `課程推薦>>《每天1小時(shí),龍哥手把手教您LabVIEW視覺(jué)設(shè)計(jì)》[hide]小草手把手教你 LabVIEW 串口儀器控制—生成
    發(fā)表于 02-04 10:45

    【視頻匯總】小草大神手把手教你Labview技巧及源代碼分享

    點(diǎn)擊學(xué)習(xí)>>《龍哥手把手教你學(xué)LabVIEW視覺(jué)設(shè)計(jì)》視頻教程原創(chuàng)視頻教程小草手把手教你LabVIEW
    發(fā)表于 05-26 13:48

    手把手教你LabVIEW儀器控制

    手把手教你LabVIEW儀器控制,串口學(xué)習(xí)
    發(fā)表于 12-11 12:00

    labview測(cè)試tensorflow深度學(xué)習(xí)SSD模型識(shí)別物體

    文件調(diào)用labview深度學(xué)習(xí)推理函數(shù)完成識(shí)別以上是識(shí)別動(dòng)物和人等物體labview識(shí)別效果。
    發(fā)表于 08-16 17:21

    手把手教你如何一步一步實(shí)現(xiàn)人臉識(shí)別的門禁系統(tǒng)

    是一個(gè)人臉識(shí)別的門禁系統(tǒng)開源源碼及論文,基本功能實(shí)現(xiàn),但其教程較簡(jiǎn)略且有欠缺。本教程將從零開始,手把手教你如何一步一步
    發(fā)表于 12-14 06:44

    手把手教你寫批處理-批處理的介紹

    手把手教你寫批處理-批處理的介紹
    發(fā)表于 10-25 15:02 ?69次下載

    美女手把手教你如何裝機(jī)(中)

    美女手把手教你如何裝機(jī)(中) 再來(lái)是硬碟的部份,這款機(jī)殼還不錯(cuò),可以旋轉(zhuǎn)支架~
    發(fā)表于 01-27 11:14 ?1515次閱讀

    美女手把手教你如何裝機(jī)(下)

    美女手把手教你如何裝機(jī)(下) 接著下來(lái)就是今天的重頭戲,開核蘿!~
    發(fā)表于 01-27 11:16 ?3011次閱讀

    小草手把手教你LabVIEW儀器控制V1.0

    小草手把手教你LabVIEW儀器控制V1.0 ,感興趣的小伙伴們可以看看。
    發(fā)表于 08-03 17:55 ?95次下載

    手把手教你安裝Quartus II

    本章手把手把教你如何安裝 Quartus II 軟件 ,并將它激活 。此外 還有USB -Blaster下載器的驅(qū)動(dòng)安裝步驟 。
    發(fā)表于 09-18 14:55 ?9次下載

    手把手教你如何開始DSP編程

    手把手教你如何開始DSP編程。
    發(fā)表于 04-09 11:54 ?13次下載
    <b class='flag-5'>手把手</b><b class='flag-5'>教你</b>如何開始DSP編程

    手把手教你學(xué)LabVIEW視覺(jué)設(shè)計(jì)

    手把手教你學(xué)LabVIEW視覺(jué)設(shè)計(jì)手把手教你學(xué)LabVIEW視覺(jué)設(shè)計(jì)
    發(fā)表于 03-06 01:41 ?3315次閱讀

    手把手教你使用LabVIEW OpenCV DNN實(shí)現(xiàn)手寫數(shù)字識(shí)別源碼

    LabVIEW中如何使用OpenCV DNN模塊實(shí)現(xiàn)手寫數(shù)字識(shí)別
    的頭像 發(fā)表于 03-08 16:10 ?2194次閱讀

    手把手教你使用LabVIEW OpenCV dnn實(shí)現(xiàn)圖像分類(源碼

    使用LabVIEW OpenCV dnn實(shí)現(xiàn)圖像分類
    的頭像 發(fā)表于 03-09 13:37 ?1768次閱讀

    手把手教你學(xué)FPGA仿真

    電子發(fā)燒友網(wǎng)站提供《手把手教你學(xué)FPGA仿真.pdf》資料免費(fèi)下載
    發(fā)表于 10-19 09:17 ?2次下載
    <b class='flag-5'>手把手</b><b class='flag-5'>教你</b>學(xué)FPGA仿真

    電子發(fā)燒友

    中國(guó)電子工程師最喜歡的網(wǎng)站

    • 2931785位工程師會(huì)員交流學(xué)習(xí)
    • 獲取您個(gè)性化的科技前沿技術(shù)信息
    • 參加活動(dòng)獲取豐厚的禮品