Object Detection 手把手教你使用LabVIEW OpenCV dnn实现物体识别含源码

前言今天和大家一起分享如何使用LabVIEW调用pb模型实现物体识别,本博客中使用的智能工具包可到主页置顶博客LabVIEW AI视觉工具包(非NI Vision)下载与安装教程中下载
一、物体识别算法原理概述1、物体识别的概念物体识别也称目标检测,目标检测所要解决的问题是目标在哪里以及其状态的问题 。但是,这个问题并不是很容易解决 。形态不合理,对象出现的区域不确定,更不用说对象也可以是多个类别 。

Object Detection 手把手教你使用LabVIEW OpenCV dnn实现物体识别含源码

文章插图
目标检测用的比较多的主要是RCNN,spp- net,fast- rcnn,faster- rcnn;YOLO系列,如YOLOV3和YOLOV4;除此之外还有SSD,ResNet等 。
2、Yolo算法原理概述Yolo的识别原理简单清晰 。对于输入的图片,将整张图片分为7×7(7为参数,可调)个方格 。当某个物体的中心点落在了某个方格中,该方格则负责预测该物体 。每个方格会为被预测物体产生2(参数,可调)个候选框并生成每个框的置信度 。最后选取置信度较高的方框作为预测结果 。
Object Detection 手把手教你使用LabVIEW OpenCV dnn实现物体识别含源码

文章插图
二、opencv调用darknet物体识别模型(yolov3/yolov4)相关源码及模型在darknt文件夹下
Object Detection 手把手教你使用LabVIEW OpenCV dnn实现物体识别含源码

文章插图
使用darknet训练yolo的模型,生成weights文件 。使用opencv调用生成的模型
1、darknet模型的获取文件含义:
  • cfg文件:模型描述文件
  • weights文件:模型权重文件
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调用darknet模型实现物体识别(1)dnn模块调用darknet模型
net = cv2.dnn.readNetFromDarknet("yolov3/yolov3.cfg", "yolov3/yolov3.weights")(2)获取三个输出端的LayerName
使用getUnconnectedOutLayer获取三个只有输入,没有输出的层的名字,Yolov3的三个输出端层名为:['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)图像预处理
使用blobFromImage将图像转为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)获取多个层的结果,其中getOutputsNames(net)=['yolo_82', 'yolo_94', 'yolo_106']
net.setInput(blob)outs = net.forward(getOutputsNames(net))(5)后处理(postrocess)
获取的结果(outs)里面有三个矩阵(out),每个矩阵的大小为85*n,n表示检测到了n个物体,85的排列顺序是这样的:
  • 第0列代表物体中心x在图中的位置(0~1)
  • 第1列表示物体中心y在图中的位置(0~1)
  • 第2列表示物体的宽度
  • 第3列表示物体的高度
  • 第4列是置信概率,值域为[0-1],用来与阈值作比较决定是否标记目标
  • 第5~84列为基于COCO数据集的80分类的标记权重,最大的为输出分类 。使用这些参数保留置信度高的识别结果(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)

经验总结扩展阅读