赞
踩
print("总平均帧率\t", frames / (time.time() - initTime))
# 释放cap和rknn线程池
cap.release()
cv2.destroyAllWindows()
pool.release()
这是在不同线程数下视频推理的帧率:
测试模型来源 yolov5s,激活函数为silu(非relu优化版本)
resnet18_for_rk3588, resnet26, resnet50
测试视频为 新宝岛
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
yolov5s | 13.4159 | 26.0832 | 35.8814 | 38.1729 | 43.2117 | 45.5549 | 45.2401 | 45.5819 | 46.4229 |
resnet18 | 288.91 | 483.83 | 577.60 | ||||||
resnet26 | 233.16 | 394.83 | 420.10 | ||||||
resnet50 | 186.17 | 259.88 | 284.49 |
resnet50在9线程下的NPU占用率:
可以看到此时NPU的性能发挥到近乎极致,其推理性能约为280帧
可移步rknn多线程获取yolov5s, resnet26, resnet50的rknn模型、完整代码和演示视频
import cv2 import time from rknnpool import rknnPoolExecutor # 图像处理函数,实际应用过程中需要自行修改 from func import myFunc cap = cv2.VideoCapture('./video/islandBenchmark.mp4') # cap = cv2.VideoCapture(0) modelPath = "./rknnModel/yolov5s.rknn" # 线程数 TPEs = 6 # 初始化rknn池 pool = rknnPoolExecutor( rknnModel=modelPath, TPEs=TPEs, func=myFunc) # 初始化异步所需要的帧 if (cap.isOpened()): for i in range(TPEs + 1): ret, frame = cap.read() if not ret: cap.release() del pool exit(-1) pool.put(frame) frames, loopTime, initTime = 0, time.time(), time.time() while (cap.isOpened()): frames += 1 ret, frame = cap.read() if not ret: break pool.put(frame) frame, flag = pool.get() if flag == False: break cv2.imshow('test', frame) if cv2.waitKey(1) & 0xFF == ord('q'): break if frames % 30 == 0: print("30帧平均帧率:\t", 30 / (time.time() - loopTime), "帧") loopTime = time.time() print("总平均帧率\t", frames / (time.time() - initTime)) # 释放cap和rknn线程池 cap.release() cv2.destroyAllWindows() pool.release()
from queue import Queue from rknnlite.api import RKNNLite from concurrent.futures import ThreadPoolExecutor, as_completed def initRKNN(rknnModel="./rknnModel/yolov5s.rknn", id=0): rknn_lite = RKNNLite() ret = rknn_lite.load_rknn(rknnModel) if ret != 0: print("Load RKNN rknnModel failed") exit(ret) if id == 0: ret = rknn_lite.init_runtime(core_mask=RKNNLite.NPU_CORE_0) elif id == 1: ret = rknn_lite.init_runtime(core_mask=RKNNLite.NPU_CORE_1) elif id == 2: ret = rknn_lite.init_runtime(core_mask=RKNNLite.NPU_CORE_2) elif id == -1: ret = rknn_lite.init_runtime(core_mask=RKNNLite.NPU_CORE_0_1_2) else: ret = rknn_lite.init_runtime() if ret != 0: print("Init runtime environment failed") exit(ret) print(rknnModel, "\t\tdone") return rknn_lite def initRKNNs(rknnModel="./rknnModel/yolov5s.rknn", TPEs=1): rknn_list = [] for i in range(TPEs): rknn_list.append(initRKNN(rknnModel, i % 3)) return rknn_list class rknnPoolExecutor(): def __init__(self, rknnModel, TPEs, func): self.TPEs = TPEs self.queue = Queue() self.rknnPool = initRKNNs(rknnModel, TPEs) self.pool = ThreadPoolExecutor(max_workers=TPEs) self.func = func self.num = 0 def put(self, frame): self.queue.put(self.pool.submit( self.func, self.rknnPool[self.num % self.TPEs], frame)) self.num += 1 def get(self): if self.queue.empty(): return None, False temp = [] temp.append(self.queue.get()) for frame in as_completed(temp): return frame.result(), True def release(self): self.pool.shutdown() for rknn_lite in self.rknnPool: rknn_lite.release()
#以下代码改自https://github.com/rockchip-linux/rknn-toolkit2/tree/master/examples/onnx/yolov5 import cv2 import numpy as np from rknnlite.api import RKNNLite QUANTIZE_ON = True OBJ_THRESH, NMS_THRESH, IMG_SIZE = 0.25, 0.45, 640 CLASSES = ("person", "bicycle", "car", "motorbike ", "aeroplane ", "bus ", "train", "truck ", "boat", "traffic light", "fire hydrant", "stop sign ", "parking meter", "bench", "bird", "cat", "dog ", "horse ", "sheep", "cow", "elephant", "bear", "zebra ", "giraffe", "backpack", "umbrella", "handbag", "tie", "suitcase", "frisbee", "skis", "snowboard", "sports ball", "kite", "baseball bat", "baseball glove", "skateboard", "surfboard", "tennis racket", "bottle", "wine glass", "cup", "fork", "knife ", "spoon", "bowl", "banana", "apple", "sandwich", "orange", "broccoli", "carrot", "hot dog", "pizza ", "donut", "cake", "chair", "sofa", "pottedplant", "bed", "diningtable", "toilet ", "tvmonitor", "laptop ", "mouse ", "remote ", "keyboard ", "cell phone", "microwave ", "oven ", "toaster", "sink", "refrigerator ", "book", "clock", "vase", "scissors ", "teddy bear ", "hair drier", "toothbrush ") def sigmoid(x): return 1 / (1 + np.exp(-x)) def xywh2xyxy(x): # Convert [x, y, w, h] to [x1, y1, x2, y2] y = np.copy(x) y[:, 0] = x[:, 0] - x[:, 2] / 2 # top left x y[:, 1] = x[:, 1] - x[:, 3] / 2 # top left y y[:, 2] = x[:, 0] + x[:, 2] / 2 # bottom right x y[:, 3] = x[:, 1] + x[:, 3] / 2 # bottom right y return y def process(input, mask, anchors): anchors = [anchors[i] for i in mask] grid_h, grid_w = map(int, input.shape[0:2]) box_confidence = sigmoid(input[..., 4]) box_confidence = np.expand_dims(box_confidence, axis=-1) box_class_probs = sigmoid(input[..., 5:]) box_xy = sigmoid(input[..., :2])*2 - 0.5 col = np.tile(np.arange(0, grid_w), grid_w).reshape(-1, grid_w) row = np.tile(np.arange(0, grid_h).reshape(-1, 1), grid_h) col = col.reshape(grid_h, grid_w, 1, 1).repeat(3, axis=-2) row = row.reshape(grid_h, grid_w, 1, 1).repeat(3, axis=-2) grid = np.concatenate((col, row), axis=-1) box_xy += grid box_xy *= int(IMG_SIZE/grid_h) box_wh = pow(sigmoid(input[..., 2:4])*2, 2) box_wh = box_wh * anchors box = np.concatenate((box_xy, box_wh), axis=-1) return box, box_confidence, box_class_probs def filter_boxes(boxes, box_confidences, box_class_probs): """Filter boxes with box threshold. It's a bit different with origin yolov5 post process! # Arguments boxes: ndarray, boxes of objects. box_confidences: ndarray, confidences of objects. box_class_probs: ndarray, class_probs of objects. # Returns boxes: ndarray, filtered boxes. classes: ndarray, classes for boxes. scores: ndarray, scores for boxes. """ boxes = boxes.reshape(-1, 4) box_confidences = box_confidences.reshape(-1) box_class_probs = box_class_probs.reshape(-1, box_class_probs.shape[-1]) _box_pos = np.where(box_confidences >= OBJ_THRESH) boxes = boxes[_box_pos] box_confidences = box_confidences[_box_pos] box_class_probs = box_class_probs[_box_pos] class_max_score = np.max(box_class_probs, axis=-1) classes = np.argmax(box_class_probs, axis=-1) _class_pos = np.where(class_max_score >= OBJ_THRESH) boxes = boxes[_class_pos] classes = classes[_class_pos] scores = (class_max_score * box_confidences)[_class_pos] return boxes, classes, scores def nms_boxes(boxes, scores): """Suppress non-maximal boxes. # Arguments boxes: ndarray, boxes of objects. scores: ndarray, scores of objects. # Returns keep: ndarray, index of effective boxes. """ x = boxes[:, 0] y = boxes[:, 1] w = boxes[:, 2] - boxes[:, 0] h = boxes[:, 3] - boxes[:, 1] areas = w * h order = scores.argsort()[::-1] keep = [] while order.size > 0: i = order[0] keep.append(i) xx1 = np.maximum(x[i], x[order[1:]]) yy1 = np.maximum(y[i], y[order[1:]]) xx2 = np.minimum(x[i] + w[i], x[order[1:]] + w[order[1:]]) yy2 = np.minimum(y[i] + h[i], y[order[1:]] + h[order[1:]]) w1 = np.maximum(0.0, xx2 - xx1 + 0.00001) h1 = np.maximum(0.0, yy2 - yy1 + 0.00001) inter = w1 * h1 ovr = inter / (areas[i] + areas[order[1:]] - inter) inds = np.where(ovr <= NMS_THRESH)[0] order = order[inds + 1] keep = np.array(keep) return keep def yolov5_post_process(input_data): masks = [[0, 1, 2], [3, 4, 5], [6, 7, 8]] anchors = [[10, 13], [16, 30], [33, 23], [30, 61], [62, 45], [59, 119], [116, 90], [156, 198], [373, 326]] boxes, classes, scores = [], [], [] for input, mask in zip(input_data, masks): b, c, s = process(input, mask, anchors) b, c, s = filter_boxes(b, c, s) boxes.append(b) classes.append(c) scores.append(s) boxes = np.concatenate(boxes) boxes = xywh2xyxy(boxes) classes = np.concatenate(classes) scores = np.concatenate(scores) nboxes, nclasses, nscores = [], [], [] for c in set(classes): inds = np.where(classes == c) b = boxes[inds] c = classes[inds] s = scores[inds] keep = nms_boxes(b, s) nboxes.append(b[keep]) nclasses.append(c[keep]) nscores.append(s[keep]) if not nclasses and not nscores: return None, None, None boxes = np.concatenate(nboxes) classes = np.concatenate(nclasses) scores = np.concatenate(nscores) return boxes, classes, scores def draw(image, boxes, scores, classes): for box, score, cl in zip(boxes, scores, classes): top, left, right, bottom = box # print('class: {}, score: {}'.format(CLASSES[cl], score)) # print('box coordinate left,top,right,down: [{}, {}, {}, {}]'.format(top, left, right, bottom)) top = int(top) left = int(left) right = int(right) bottom = int(bottom) cv2.rectangle(image, (top, left), (right, bottom), (255, 0, 0), 2) cv2.putText(image, '{0} {1:.2f}'.format(CLASSES[cl], score), (top, left - 6), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 255), 2) def letterbox(im, new_shape=(640, 640), color=(0, 0, 0)): shape = im.shape[:2] # current shape [height, width] if isinstance(new_shape, int): new_shape = (new_shape, new_shape) r = min(new_shape[0] / shape[0], new_shape[1] / shape[1]) ratio = r, r # width, height ratios new_unpad = int(round(shape[1] * r)), int(round(shape[0] * r)) dw, dh = new_shape[1] - new_unpad[0], new_shape[0] - \ new_unpad[1] # wh padding dw /= 2 # divide padding into 2 sides dh /= 2 **自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。** **深知大多数Python工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!** **因此收集整理了一份《2024年Python开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。** ![img](https://img-blog.csdnimg.cn/img_convert/2c9592ecf9dee95097c0187861c256f9.png) ![img](https://img-blog.csdnimg.cn/img_convert/d927814b2dc0a2ffe09d6451dba8f3ec.png) ![img](https://img-blog.csdnimg.cn/img_convert/6f52fc3dab855a639a2c8e96eeb9158c.png) ![img](https://img-blog.csdnimg.cn/img_convert/82373c89c328391ed48a76254162cfb7.png) ![img](https://img-blog.csdnimg.cn/img_convert/6c361282296f86381401c05e862fe4e9.png) ![img](https://img-blog.csdnimg.cn/img_convert/9f49b566129f47b8a67243c1008edf79.png) **既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!** **由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新** **如果你觉得这些内容对你有帮助,可以扫码获取!!!(备注Python)** [外链图片转存中...(img-TOQUxa54-1713209744916)] ![img](https://img-blog.csdnimg.cn/img_convert/6c361282296f86381401c05e862fe4e9.png) ![img](https://img-blog.csdnimg.cn/img_convert/9f49b566129f47b8a67243c1008edf79.png) **既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!** **由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新** **如果你觉得这些内容对你有帮助,可以扫码获取!!!(备注Python)** <img src="https://img-community.csdnimg.cn/images/fd6ebf0d450a4dbea7428752dc7ffd34.jpg" alt="img" style="zoom:50%;" />
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。