最近一直研究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 下载) (修改
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了
遥感数据预测