赞
踩
python+OpenCV+yolov3训练库,代码如下:
- #!/usr/bin/env python3
- # -*- coding: utf-8 -*-
- import cv2
- import numpy as np
- import os
-
- imgFiles=["pic03.jpg", "pic04.jpg"]
-
- net=None
- classes=None
- colors=None
-
- def recog_person(imgFile, ratio):
- print(imgFile)
- global net, classes, colors
- if(net==None):
- # 加载模型配置和权重
- net = cv2.dnn.readNet("../common/yolov3.weights", "../common/yolov3.cfg")
-
- # 加载对象类别
- classes = []
- with open("coco.names", "r") as f:
- classes = [line.strip() for line in f.readlines()]
-
- # 随机颜色
- colors = np.random.uniform(0, 255, size=(len(classes), 3))
-
- # 加载图像
- image = cv2.imread(imgFile)
-
- # 获取图像尺寸
- height, width, _ = image.shape
-
- new_height = 416
- new_width = int(width * (new_height / height))
-
- resized_image = cv2.resize(image, (new_width, new_height))
-
- # 构建输入blob
- blob = cv2.dnn.blobFromImage(image, 1/255.0, (416, 416), swapRB=True, crop=False)
-
- # 设置输入blob作为网络的输入
- net.setInput(blob)
-
- # 前向传递,获取输出层
- layer_names = net.getLayerNames()
- print("layer names counts=%d" %(len(layer_names)))
- print(net.getUnconnectedOutLayers())
-
- #print(length(layer_names))
- #output_layers = [layer_names[i[0] - 1] for i in net.getUnconnectedOutLayers()]
- output_layers = [layer_names[i - 1] for i in net.getUnconnectedOutLayers()]
- outs = net.forward(output_layers)
-
- # 初始化边界框、置信度和类别列表
- boxes = []
- confidences = []
- class_ids = []
-
- # 对每个输出层进行处理
- for out in outs:
- for detection in out:
- # 获取类别置信度
- scores = detection[5:]
- class_id = np.argmax(scores)
- confidence = scores[class_id]
-
- # 过滤掉低置信度的预测
- if confidence > ratio:
- # 获取边界框坐标
- center_x = int(detection[0] * width)
- center_y = int(detection[1] * height)
- w = int(detection[2] * width)
- h = int(detection[3] * height)
-
- # 边界框的左上角坐标
- x = int(center_x - w / 2)
- y = int(center_y - h / 2)
-
- # 更新边界框、置信度和类别列表
- boxes.append([x, y, w, h])
- confidences.append(float(confidence))
- class_ids.append(class_id)
-
- # 非最大值抑制
- indices = cv2.dnn.NMSBoxes(boxes, confidences, 0.5, 0.4)
- print("indices", len(indices), indices)
- print("-------------------------------")
- print("class_ids", len(class_ids), class_ids)
- print("classes", len(classes));
- print("colors", len(colors));
- print("boxes counts=", len(boxes), len(indices));
-
- # 绘制边界框和类别标签
- font = cv2.FONT_HERSHEY_SIMPLEX
- for i in range(len(boxes)):
- if i in indices:
- x, y, w, h = boxes[i]
- #label = classes[class_ids[i]]
- #color = colors[class_ids[i]]
- color = (128,0,128)
- cv2.rectangle(image, (x, y), (x+w, y+h), color, 2)
- #cv2.putText(image, label, (x, y-10), font, 0.5, color, 2)
-
- # 显示结果图像
- name, extension = os.path.splitext(imgFile)
- output_filename = name + ".ai.jpg";
- cv2.imwrite(output_filename, image)
-
- for file in imgFiles:
- recog_person(file,0.5)

3.1 yoloV3的训练库使用的分辨率是一个正方形的分辨率,416*416或者压缩,或者是扫描。
3.2上面筛选目标对象的代码没有代入,所以误识别到了一些其他物体。
3.3 yoloV3的训练库名称是:yolov3.weight yolov3.cfg
3.4 置信概率50%。
图像识别中运算量最大的部分是矩阵运算。它的原理是这样的:你看,刚刚的yoloV3的训练库,针对的是固定分辨率416*416的图片。它的训练库最终输出的总规模是200M字节。假定我们有一个非常简单的训练库,能够识别三角形。那这个东西,在最终进行图像识别时,是怎么运作的呢?我们知道图像在被拍摄为图片后,会有平移,缩放,投影,这三种运算。这些运算对应的都是一些矩阵运算。假定最终,我们经过某些变换后,能够让我们的识别库中的这组三角形顶点集合,与最终识别到的点阵中的某组点阵之间能够形成(ArrayOfModel) = K*(ArrayOfPt),也就是说,这个时候,它们只是大小的差异,那么我们就认为捕获到了一组三角形。
捕获的原则,肯定是先捕获更大的点阵组,然后逐渐尝试捕获更小的点阵组,类似这样。这个点阵的匹配过程是可以并行执行的。所以,显卡那种结构会更适合进行点阵运算。支持多路同时计算的量子计算也肯定更适合这种模式。
模式库的分离,可能是最有效的提高效率的途径。如果你已经确定了要进行模式匹配的对象的几乎,匹配算法就不会在尝试在一个明显更大的模式库里去进行复杂匹配计算。
基本的步骤:
机器学习很像在进行某些变量的函数关系的推导过程中,使用逐点样条差值。你不再尝试推导出明确的点阵特征值。而是一切交给机器,喂入大量的图片,由它自己建立关联关系。
通过检查附录A,附录B,你会发现,工程实现时的关键在于代码优化。算法基本是明的。但是,在工程应用时必须考虑成本。此时,必须进行计算优化。针对学习阶段可以用堆CPU,堆显卡的方式实现。但是一但开始部署,必须要在一个性价比较高的嵌入式平台,能在所需的有限时间内跑通算法。
建议搜索是否有针对特定的识别算法经过预先优化的arm平台。我觉得这比自己做始终要更快——当然,局限是,它可能已经限制死了训练集的图片幅面和具体的识别算法。但是即使这样,它仍然是更好的途径。
在优化瓶颈无法克服时,降低像素是可以尝试的途径。
你可以使用一个预先训练好的训练集先对你自己拍摄的图片进行识别,然后删减识别到的物体,或者追加。这样更快,不必徒手标注每一张图片。
观察附录B,你会发现ARM平台在不降低其他参数的情况下,几乎无法使用。但是事实上并非如此。推荐一篇帖子:
YOLOv8 与 RKNN 的碰撞:全新 SOTA 视觉模型如何在边端大放异彩 - 知乎 (zhihu.com)
RKNN是一种基于既有训练结果的一种识别优化:
利用这种计算技术,在 RK3399平台下的实际运算结果:
YOLOv5s部署在瑞芯微电子RK3399Pro中使用NPU进行加速推理 - 知乎
NPU 的算力相当于1~8TPOS,这个算力已经和附录A,未使用任何加速技术在I5-9400 2.9GHz下的运算结果相当。而事实上的识别能力,训练集的图片尺寸不变,实际的识别速度可以达到100ms以内。在工业场景,已经是一个可以接受的识别方案。此时看这个测试人员的截屏:
它跑的是80个物体的完整训练集,对于有针对性的特定物体的识别,速度还可以进一步加快。
这个平台的开发板淘宝价在800+Yuan 这个级别。
全志V853 在 NPU 转换 YOLO V3 模型_全志npu适配-CSDN博客
注意yolov3的部分啊。320,应该指320*320, 416是416*416,对应的是待识别物体的幅面,tiny,spp似乎是为了适应嵌入式环境的一些简化版本,不仅仅缩减了幅面,而且对运算过程本身也做了裁剪。
出处:深度学习模型Intel与ARM部署性能分析,Intel和ARM CPU上CNN计算速度差距分析。
CPU 型号 | 支持加速指令 | 1 core 测试时间 | 2 core测试时间 | 4核测试时间 | 8核心测试时间 |
---|---|---|---|---|---|
i5-10400 CPU @2.90GHz 12核 睿频4.3GHz Ubuntu 18.04, x86-64,Linux 5.4.0,本地 mkl-threads 6 | OpenMP+MKL-DNN | 27.63s | 17.63s | 9.64s | 8.0s |
与上同3080ti服务器 | OpenMP 4.5, 没有MKL-DNN | 36.44s | 24.10s | 16.00s | 13.25s |
i7-9700k CPU @3.60Hz 8核 睿频4.9GHz torch 1.5 linux 5.4 x86-64, | OpenMP+MKL-DNN | 28.46s | 15.40s | 11.1s, | 6.75s |
Intel Xeon CPU E5-2680 v4 @2.40GHz 2 CPU 56核 睿频3.3 GHz centos linux 7,linux 3.10.0 | OpenMP+MKL-DNN | 32.23s | 18.20s | 10.72s | 6.94s |
Intel Xeon CPU E5-2690 v4@2.6GHz,32核,centos linux 7,linux3.10.0 mkl-max-threads=16 | OpenMP+MKL-DNN | 36.72s | 20.44s | 12.31s | 7.34s |
飞腾FT-2000+/64 CPU,64核,2.3GHz, 架构ARM 64 操作系统kylin 4.0,内核 linux 4.4 | OpenMP 4.5,无MKL-DNN | 501.35s 100%CPU | 303.8s 170%cpu | 210.7s 250%CPU | 112.0s 510% |
MacBook ARM CPU m1 3.2GHz, aarch64架构,ARMv8-A指令集架构,8核,mkl-max-threads=1 | 没有OpenMP,有MKL-DNN | 57.10s | 52.94s | 49.6s | 48.62s |
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。