最近一直研究YOLOV3,原因是边缘计算的话才是将来嵌入式开发的前途。看了美国的遥感预测图,可以区分到飞机型号,确实NB,就自己也想写一个关于YOLOV3的来,顺便新手也是掌握一下整个流程。整个过程:三个部分。第一个部分是使用OPENCV3.4 测试预测的框架,第二部分是LINUX下 数据集处理,主要是采用了NWPU 10的数据集 。第三部分,由于我只有一台电脑WINDOWS, 测试开发都是在VMWARE14,训练的话 虚拟机不行 还的GPU训练 就需要回到WINDOWS框架下,搞了一周记录一下。

1.硬件配置:

cpu: i5+3.2G(4核) ,内存16G,固态硬盘

GPU:GTX1060 6G

2 .系统配置

物理:windows7 x64 16g 2块固态硬盘 (操,为了搞这个,重装了系统一次)

2.软件配置

   1.虚拟机: vmware14+ubuntu16.04 + pycharm2019 主要是采用python避免了很多数据类型的转换(以前是传统搞嵌入式的,刚开始学python) 

   2. windows7: vs2015 ultreditev24 (训练数据集) cuda10 cudnn 7.6 最新版显卡驱动( 经验告诉我这一定要下载最新版的,因为平时会更新显卡驱动,用了CUDA9发现 训练中出现 参数错误)

   2.YOLOV3:

         (1) 测试OPENCVDNN框架的学习yolov3预测:

                  (1)yolov3.weigth(权重文件),github下载

                 (2)yolov3.cfg 配置文件,github下载

                 (3)coco.names (voc数据集) 下载DARKNET源码 里面已经有了(原版和AB版都有)

                 (4)opencv-python3.4.7.28(pycharm 下载) (修改

opencv如何调用yolov5模型 opencv yolov3_yolov3

   https://pypi.tuna.tsinghua.edu.cn/simple/)                

         (2) 数据集制作:

                   (1) 下载DARKNET源码(原版):darknet-master:

                   (2) 下载NWPU 10遥感数据集:http://jiong.tea.ac.cn/people/JunweiHan/NWPUVHR10dataset.html

          (3) 数据集训练:

                 (1) vs2015 社区版: 注册后免费可以用,偶尔注册的时候很慢,网速问题

                 (2) 下载darknet-master(windows版):这个有两种方式,一种是源代码用cgwin编译, 第二种采用alexeyAB做好的VS版,前提条件是2015以下版本,其他的据说不行,没试验过,我只是需要权重文件,暂不研究很深,先走流程 下载地址:                 (https://github.com/AlexeyAB/darknet/)

第一部分开发:

            环境:.vmware14环境+ubuntu16.04+pycharm2019.2( 我是付费版,怕第二天起来看不到工程了)

           pycahrm:需要主要的库是【opencv3.4.7.28】 ,【numpy】 python数据结构核心           

import cv2 as cv
import  numpy as np
from  skimage import  exposure
import sys
import os



conftherd = 0.1
# 置信度
nmstherd = 0.1
#最大非抑制

ImgWeigth =416
ImgHeigth =416
#输入图片的 w h ,这个要和CFG保持一致

classesFile = "nwpu.names"


def getOutputsNames(net):
    # Get the names of all the layers in the network
    layersNames = net.getLayerNames()
    outputlayer = net.getUnconnectedOutLayers()

    # # Get the names of the output layers, i.e. the layers with unconnected outputs
    # for x in net.getUnconnectedOutLayers():
    return [layersNames[i[0] - 1] for i in net.getUnconnectedOutLayers()]

def drawPred(classId, conf, left, top, right, bottom,frame):
    # Draw a bounding box.
    cv.rectangle(frame, (left, top), (right, bottom), (255, 178, 50), 3)

    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.rectangle(frame, (left, top - round(1.5*labelSize[1])), (left + round(1.5*labelSize[0]), top + baseLine), (255, 255, 255), cv.FILLED)
    cv.putText(frame, label, (left, top), cv.FONT_HERSHEY_SIMPLEX, 0.5, (0,0,0), 1)


def Detectprocess(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 > conftherd:
                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.
    indices = cv.dnn.NMSBoxes(boxes,confidences, conftherd, nmstherd)

    for i in indices:
        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,frame)


if __name__ == '__main__':
    classes = None
    with open(classesFile,'rt') as f:
        classes = f.read().rstrip('\n').split('\n')

# Mode file : weigth and cfg
    modecfg = "yolov3-NWPU.cfg"      
    modeweigth = "yolov3-NWPU_2000.weights"
    # 加载权重和配置文件
    net = cv.dnn.readNetFromDarknet(modecfg,modeweigth)
    #设置处理引擎是基于opencv,默认是inter
    net.setPreferableBackend(cv.dnn.DNN_BACKEND_OPENCV)
    #设置计算是cpu,主要我是虚拟机没有GPU
    net.setPreferableTarget(cv.dnn.DNN_TARGET_CPU)

    img = cv.imread('013.jpg')
    # imgs = exposure.adjust_gamma(img, 2)
    # 发现耨一些图片背景很差,通过GAMMA调整饱和度,提高预测率
    # imgs = cv.bilateralFilter(imgs,9,70,70)


    # cv.imshow('img',imgs)
    # cv.dnn.blobFromImage(image[, scalefactor[, size[, mean[, swapRB[, crop[, ddepth]]]]]]    )
    blob= cv.dnn.blobFromImage(img,1.0/255.0,(ImgHeigth,ImgWeigth),[0,0,0], 1, crop=False)
    #输入图像预处理,通道,尺寸等是否进行裁剪
    net.setInput(blob)
    #前向预测 
    outs = net.forward(getOutputsNames(net)) 
    Detectprocess(img,outs)
    cv.imshow("select",img)
    if cv.waitKey(0) == ord("q"):
        cv.destroyAllWindows()
    # cap = cv.VideoCapture(0)
    # viodeHeigth =int( cap.get(cv.CAP_PROP_FRAME_HEIGHT))
    # viodeWeigth = int(cap.get(cv.CAP_PROP_FRAME_WIDTH))
    # print(viodeWeigth,viodeHeigth)
    # while True:
    #     ret , frame = cap.read()
    #     blob= cv.dnn.blobFromImage(frame,1.0/255.0,(viodeWeigth,viodeHeigth),[0,0,0],swapRB=True, crop=False)
    #     net.setInput(blob)
    #
    #     outs = net.forward(getOutputsNames(net))
    #     postprocess(frame,outs)
    #
    #     cv.imshow("select",frame)
    #     if cv.waitKey(1) == ord("q"):
    #         break
    # cv.destroyAllWindows()
    # cap.release()

     第一步:配置网络,因为是虚拟机只能采用CPU的方式

    第二步:开始预测,前向预测的网络,得到最后的输出层名称,[layersNames[i[0] - 1] for i in net.getUnconnectedOutLayers()] (实战理解了 python 中比较高级的 链式推导 研究了半天 )

    第三步:预测处理 Detectprocess(),这部分预测得到预测的所有结果,前4个元素代表center_x,center_y,width和height。第五个元素表示边界框包围对象的置信度,【indices = cv.dnn.NMSBoxes(boxes,confidences, conftherd, nmstherd)】非极大抑制处理,主要就是剔除重复的,置信度低的BOX,选择满足参数的框。 

    总结,opencv最有可能成为边缘计算未来大量的应用,遇到的最大坑就是,视频监测的时候,虚拟机真心跑不动,v4l2框架还有问题,会超时,难为vmware了


opencv如何调用yolov5模型 opencv yolov3_ide_02

遥感数据预测