1.添加使用yolov8_rknn模型脚本\n2.添加paddleocr_onnx转rknn脚本
This commit is contained in:
parent
dd548e8915
commit
b3a781dbcf
@ -16,7 +16,7 @@ rknn.config(
|
||||
)
|
||||
|
||||
# 加载 ONNX
|
||||
ret = rknn.load_onnx(model="/home/admin-root/haotian/rk3588/pytorch模型转rknn/models/yolov8m.onnx")
|
||||
ret = rknn.load_onnx(model="/home/admin-root/haotian/康达瑞贝斯机器狗/yolov8_20250820.onnx")
|
||||
assert ret == 0, "加载 ONNX 失败!"
|
||||
|
||||
# 转换模型
|
||||
@ -27,12 +27,12 @@ ret = rknn.build(
|
||||
assert ret == 0, "转换 RKNN 失败!"
|
||||
|
||||
# 导出 RKNN
|
||||
ret = rknn.export_rknn("/home/admin-root/haotian/rk3588/pytorch模型转rknn/models/yolov8m.rknn")
|
||||
ret = rknn.export_rknn("/home/admin-root/haotian/康达瑞贝斯机器狗/yolov8_20250820.rknn")
|
||||
assert ret == 0, "导出 RKNN 失败!"
|
||||
|
||||
|
||||
# Set inputs
|
||||
img = cv2.imread('/home/admin-root/haotian/rk3588/pytorch模型转rknn/images/bus.jpg')
|
||||
img = cv2.imread('/home/admin-root/haotian/康达瑞贝斯机器狗/YoloV8Obj/dataset_20250819/train/images/1e4c75b76e531606e2adc491a8f09ae8_frame_000000.jpg')
|
||||
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
|
||||
img.resize((3, 640, 640))
|
||||
img = np.expand_dims(img, 0)
|
||||
|
||||
@ -9,16 +9,16 @@ rknn = RKNN()
|
||||
# 配置参数(关键!)
|
||||
rknn.config(
|
||||
target_platform="rk3588", # 根据实际芯片型号修改
|
||||
# mean_values=[[123.675, 116.28, 103.53]], # 默认输入是255, 使用这些值归一化到0-1
|
||||
# std_values=[[58.395, 57.12, 57.375]],
|
||||
mean_values=[[0, 0, 0]], # 默认输入是255, 使用这些值归一化到0-1
|
||||
std_values=[[255, 255, 255]],
|
||||
mean_values=[[123.675, 116.28, 103.53]], # 文本检测模型, 默认输入是255, 使用这些值归一化到0-1
|
||||
std_values=[[58.395, 57.12, 57.375]],
|
||||
# mean_values=[[127.5, 127.5, 127.5]], # 文本识别模型
|
||||
# std_values=[[127.5, 127.5, 127.5]],
|
||||
quant_img_RGB2BGR=True,
|
||||
optimization_level=3, # 最高优化级别
|
||||
# optimization_level=3, # 最高优化级别
|
||||
)
|
||||
|
||||
# 加载 ONNX, 只支持固定输入的onnx模型
|
||||
ret = rknn.load_onnx(model="/home/admin-root/haotian/康达瑞贝斯机器狗/rec_shape_20250815.onnx")
|
||||
ret = rknn.load_onnx(model="/home/admin-root/haotian/康达瑞贝斯机器狗/det_shape_20250814.onnx")
|
||||
assert ret == 0, "加载 ONNX 失败!"
|
||||
|
||||
# 转换模型
|
||||
@ -29,31 +29,31 @@ ret = rknn.build(
|
||||
assert ret == 0, "转换 RKNN 失败!"
|
||||
|
||||
# 导出 RKNN
|
||||
ret = rknn.export_rknn("/home/admin-root/haotian/康达瑞贝斯机器狗/rec_shape_20250815_0m.rknn")
|
||||
ret = rknn.export_rknn("/home/admin-root/haotian/康达瑞贝斯机器狗/det_shape_20250814_0.rknn")
|
||||
assert ret == 0, "导出 RKNN 失败!"
|
||||
|
||||
|
||||
# Set inputs
|
||||
img = cv2.imread('/home/admin-root/haotian/rk3588/pytorch模型转rknn/images/bus.jpg')
|
||||
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
|
||||
# img.resize((3, 640, 640))
|
||||
img.resize((3, 48, 320))
|
||||
img = np.expand_dims(img, 0)
|
||||
# # Set inputs
|
||||
# img = cv2.imread('/home/admin-root/haotian/rk3588/pytorch模型转rknn/images/bus.jpg')
|
||||
# img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
|
||||
# # img.resize((3, 640, 640))
|
||||
# img.resize((3, 48, 320))
|
||||
# img = np.expand_dims(img, 0)
|
||||
|
||||
# Init runtime environment
|
||||
print('--> Init runtime environment')
|
||||
ret = rknn.init_runtime()
|
||||
if ret != 0:
|
||||
print('Init runtime environment failed!')
|
||||
exit(ret)
|
||||
print('done')
|
||||
# # Init runtime environment
|
||||
# print('--> Init runtime environment')
|
||||
# ret = rknn.init_runtime()
|
||||
# if ret != 0:
|
||||
# print('Init runtime environment failed!')
|
||||
# exit(ret)
|
||||
# print('done')
|
||||
|
||||
# Inference
|
||||
print('--> Running model')
|
||||
outputs = rknn.inference(inputs=[img], data_format=['nchw'])
|
||||
np.save('./tflite_mobilenet_v1_0.npy', outputs[0])
|
||||
print(len(outputs))
|
||||
print('done')
|
||||
# # Inference
|
||||
# print('--> Running model')
|
||||
# outputs = rknn.inference(inputs=[img], data_format=['nchw'])
|
||||
# np.save('./tflite_mobilenet_v1_0.npy', outputs[0])
|
||||
# print(len(outputs))
|
||||
# print('done')
|
||||
|
||||
rknn.release()
|
||||
|
||||
|
||||
38
013PaddleOCR_ONNX文本检测模型转rknn.py
Normal file
38
013PaddleOCR_ONNX文本检测模型转rknn.py
Normal file
@ -0,0 +1,38 @@
|
||||
from rknn.api import RKNN
|
||||
|
||||
def convert_det_model():
|
||||
# 创建RKNN对象
|
||||
rknn = RKNN(verbose=True)
|
||||
|
||||
# 配置模型
|
||||
print('--> Config model')
|
||||
rknn.config(mean_values=[[123.675, 116.28, 103.53]],
|
||||
std_values=[[58.395, 57.12, 57.375]],
|
||||
quant_img_RGB2BGR=True,
|
||||
target_platform='rk3588') # 根据您的芯片型号调整
|
||||
|
||||
# 加载ONNX模型
|
||||
print('--> Loading model')
|
||||
ret = rknn.load_onnx(model='/home/admin-root/haotian/康达瑞贝斯机器狗/det_shape_20250814.onnx')
|
||||
if ret != 0:
|
||||
print('Load model failed!')
|
||||
exit(ret)
|
||||
|
||||
# 构建模型
|
||||
print('--> Building model')
|
||||
ret = rknn.build(do_quantization=False
|
||||
# , dataset='./det_dataset.txt'
|
||||
)
|
||||
if ret != 0:
|
||||
print('Build model failed!')
|
||||
exit(ret)
|
||||
|
||||
# 导出RKNN模型
|
||||
ret = rknn.export_rknn('./det_shape_bgr.rknn')
|
||||
if ret != 0:
|
||||
print('Export model failed!')
|
||||
exit(ret)
|
||||
|
||||
rknn.release()
|
||||
|
||||
convert_det_model()
|
||||
34
014PaddleOCR_ONNX文本识别模型转rknn.py
Normal file
34
014PaddleOCR_ONNX文本识别模型转rknn.py
Normal file
@ -0,0 +1,34 @@
|
||||
from rknn.api import RKNN
|
||||
|
||||
|
||||
def convert_rec_model():
|
||||
rknn = RKNN(verbose=True)
|
||||
|
||||
print('--> Config model')
|
||||
rknn.config(mean_values=[[127.5, 127.5, 127.5]],
|
||||
std_values=[[127.5, 127.5, 127.5]],
|
||||
quant_img_RGB2BGR=True,
|
||||
target_platform='rk3588')
|
||||
|
||||
print('--> Loading model')
|
||||
ret = rknn.load_onnx(model='/home/admin-root/haotian/康达瑞贝斯机器狗/rec_shape_20250815.onnx')
|
||||
if ret != 0:
|
||||
print('Load model failed!')
|
||||
exit(ret)
|
||||
|
||||
print('--> Building model')
|
||||
ret = rknn.build(do_quantization=False
|
||||
# , dataset='./rec_dataset.txt'
|
||||
)
|
||||
if ret != 0:
|
||||
print('Build model failed!')
|
||||
exit(ret)
|
||||
|
||||
ret = rknn.export_rknn('./rec_model_bgr.rknn')
|
||||
if ret != 0:
|
||||
print('Export model failed!')
|
||||
exit(ret)
|
||||
|
||||
rknn.release()
|
||||
|
||||
convert_rec_model()
|
||||
240
015测试Yolov8_rknn.py
Normal file
240
015测试Yolov8_rknn.py
Normal file
@ -0,0 +1,240 @@
|
||||
import cv2
|
||||
import numpy as np
|
||||
from rknn.api import RKNN
|
||||
import time
|
||||
|
||||
class YOLOv8RKNN:
|
||||
def __init__(self, model_path, input_size=(640, 640)):
|
||||
self.model_path = model_path
|
||||
self.input_size = input_size
|
||||
self.rknn = RKNN()
|
||||
|
||||
# 类别名称,根据你的2个类别修改
|
||||
self.class_names = ['class1', 'class2'] # 请替换为你实际的类别名称
|
||||
|
||||
# 初始化模型
|
||||
self.load_model()
|
||||
|
||||
def load_model(self):
|
||||
"""加载RKNN模型"""
|
||||
print("Loading RKNN model...")
|
||||
ret = self.rknn.load_rknn(self.model_path)
|
||||
if ret != 0:
|
||||
print("Load RKNN model failed!")
|
||||
return False
|
||||
|
||||
# 初始化运行时环境(在RK3588设备上运行)
|
||||
print("Init RKNN runtime...")
|
||||
ret = self.rknn.init_runtime(target='rk3588', device_id=None, perf_debug=False, eval_mem=False)
|
||||
if ret != 0:
|
||||
print("Init RKNN runtime failed!")
|
||||
return False
|
||||
|
||||
print("RKNN model loaded successfully!")
|
||||
return True
|
||||
|
||||
def preprocess(self, image):
|
||||
"""图像预处理"""
|
||||
# 获取原始图像尺寸
|
||||
self.orig_height, self.orig_width = image.shape[:2]
|
||||
|
||||
# Resize到模型输入尺寸,保持宽高比
|
||||
scale = min(self.input_size[0]/self.orig_width, self.input_size[1]/self.orig_height)
|
||||
new_width = int(self.orig_width * scale)
|
||||
new_height = int(self.orig_height * scale)
|
||||
|
||||
# 缩放图像
|
||||
resized = cv2.resize(image, (new_width, new_height))
|
||||
|
||||
# 创建输入图像(填充到目标尺寸)
|
||||
input_image = np.full((self.input_size[1], self.input_size[0], 3), 114, dtype=np.uint8)
|
||||
|
||||
# 计算填充位置(居中)
|
||||
y_offset = (self.input_size[1] - new_height) // 2
|
||||
x_offset = (self.input_size[0] - new_width) // 2
|
||||
|
||||
# 将缩放后的图像放到中心位置
|
||||
input_image[y_offset:y_offset+new_height, x_offset:x_offset+new_width] = resized
|
||||
|
||||
# 保存缩放参数用于后处理
|
||||
self.scale = scale
|
||||
self.x_offset = x_offset
|
||||
self.y_offset = y_offset
|
||||
|
||||
return input_image
|
||||
|
||||
def postprocess(self, outputs, conf_threshold=0.5, nms_threshold=0.4):
|
||||
"""后处理:解析YOLO输出并进行NMS"""
|
||||
# YOLOv8输出格式: [batch, 84, 8400] (2个类别: 4+2+80=84,但实际只有6维)
|
||||
# 对于2类别: [x, y, w, h, conf_class1, conf_class2]
|
||||
predictions = outputs[0][0] # 移除batch维度
|
||||
|
||||
# 转置为 [8400, 6] 格式
|
||||
predictions = predictions.transpose()
|
||||
|
||||
boxes = []
|
||||
scores = []
|
||||
class_ids = []
|
||||
|
||||
for detection in predictions:
|
||||
# 提取坐标和类别置信度
|
||||
x, y, w, h = detection[:4]
|
||||
class_confs = detection[4:6] # 2个类别的置信度
|
||||
|
||||
# 找到最大置信度的类别
|
||||
class_id = np.argmax(class_confs)
|
||||
max_conf = class_confs[class_id]
|
||||
|
||||
if max_conf >= conf_threshold:
|
||||
# 转换坐标格式 (中心点 -> 左上角)
|
||||
x1 = x - w/2
|
||||
y1 = y - h/2
|
||||
x2 = x + w/2
|
||||
y2 = y + h/2
|
||||
|
||||
# 将坐标映射回原图尺寸
|
||||
x1 = (x1 - self.x_offset) / self.scale
|
||||
y1 = (y1 - self.y_offset) / self.scale
|
||||
x2 = (x2 - self.x_offset) / self.scale
|
||||
y2 = (y2 - self.y_offset) / self.scale
|
||||
|
||||
# 限制在图像边界内
|
||||
x1 = max(0, min(x1, self.orig_width))
|
||||
y1 = max(0, min(y1, self.orig_height))
|
||||
x2 = max(0, min(x2, self.orig_width))
|
||||
y2 = max(0, min(y2, self.orig_height))
|
||||
|
||||
boxes.append([x1, y1, x2, y2])
|
||||
scores.append(max_conf)
|
||||
class_ids.append(class_id)
|
||||
|
||||
# 执行NMS
|
||||
if len(boxes) > 0:
|
||||
boxes = np.array(boxes)
|
||||
scores = np.array(scores)
|
||||
class_ids = np.array(class_ids)
|
||||
|
||||
# OpenCV NMS
|
||||
indices = cv2.dnn.NMSBoxes(boxes, scores, conf_threshold, nms_threshold)
|
||||
|
||||
if len(indices) > 0:
|
||||
indices = indices.flatten()
|
||||
return boxes[indices], scores[indices], class_ids[indices]
|
||||
|
||||
return np.array([]), np.array([]), np.array([])
|
||||
|
||||
def detect(self, image, conf_threshold=0.5, nms_threshold=0.4):
|
||||
"""执行检测"""
|
||||
# 预处理
|
||||
input_image = self.preprocess(image)
|
||||
|
||||
# 推理
|
||||
start_time = time.time()
|
||||
outputs = self.rknn.inference(inputs=[input_image])
|
||||
inference_time = time.time() - start_time
|
||||
|
||||
# 后处理
|
||||
boxes, scores, class_ids = self.postprocess(outputs, conf_threshold, nms_threshold)
|
||||
|
||||
return boxes, scores, class_ids, inference_time
|
||||
|
||||
def draw_detections(self, image, boxes, scores, class_ids):
|
||||
"""在图像上绘制检测结果"""
|
||||
for i in range(len(boxes)):
|
||||
x1, y1, x2, y2 = boxes[i].astype(int)
|
||||
score = scores[i]
|
||||
class_id = int(class_ids[i])
|
||||
|
||||
# 绘制边界框
|
||||
cv2.rectangle(image, (x1, y1), (x2, y2), (0, 255, 0), 2)
|
||||
|
||||
# 绘制标签
|
||||
label = f"{self.class_names[class_id]}: {score:.2f}"
|
||||
label_size = cv2.getTextSize(label, cv2.FONT_HERSHEY_SIMPLEX, 0.5, 2)[0]
|
||||
cv2.rectangle(image, (x1, y1-label_size[1]-10),
|
||||
(x1+label_size[0], y1), (0, 255, 0), -1)
|
||||
cv2.putText(image, label, (x1, y1-5),
|
||||
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0), 2)
|
||||
|
||||
return image
|
||||
|
||||
def release(self):
|
||||
"""释放资源"""
|
||||
if self.rknn:
|
||||
self.rknn.release()
|
||||
|
||||
def main():
|
||||
# 初始化检测器
|
||||
model_path = "/home/orangepi/Desktop/康达机器狗/model_rknn/yolov8_20250820.rknn"
|
||||
detector = YOLOv8RKNN(model_path)
|
||||
|
||||
# 测试单张图片
|
||||
def test_image(image_path):
|
||||
image = cv2.imread(image_path)
|
||||
if image is None:
|
||||
print(f"Cannot load image: {image_path}")
|
||||
return
|
||||
|
||||
# 执行检测
|
||||
boxes, scores, class_ids, inference_time = detector.detect(image)
|
||||
|
||||
print(f"Inference time: {inference_time*1000:.2f}ms")
|
||||
print(f"Detected {len(boxes)} objects")
|
||||
|
||||
# 绘制结果
|
||||
result_image = detector.draw_detections(image, boxes, scores, class_ids)
|
||||
|
||||
# 显示结果
|
||||
# cv2.imshow("Detection Result", result_image)
|
||||
# cv2.waitKey(0)
|
||||
# cv2.destroyAllWindows()
|
||||
|
||||
cv2.imwrite("xxxxxxx.jpg", result_image)
|
||||
|
||||
# 测试摄像头实时检测
|
||||
def test_camera():
|
||||
cap = cv2.VideoCapture(0) # 使用默认摄像头
|
||||
if not cap.isOpened():
|
||||
print("Cannot open camera")
|
||||
return
|
||||
|
||||
while True:
|
||||
ret, frame = cap.read()
|
||||
if not ret:
|
||||
break
|
||||
|
||||
# 执行检测
|
||||
boxes, scores, class_ids, inference_time = detector.detect(frame)
|
||||
|
||||
# 绘制结果
|
||||
result_frame = detector.draw_detections(frame, boxes, scores, class_ids)
|
||||
|
||||
# 显示FPS
|
||||
fps = 1.0 / inference_time if inference_time > 0 else 0
|
||||
cv2.putText(result_frame, f"FPS: {fps:.1f}", (10, 30),
|
||||
cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
|
||||
|
||||
cv2.imshow("Real-time Detection", result_frame)
|
||||
|
||||
if cv2.waitKey(1) & 0xFF == ord('q'):
|
||||
break
|
||||
|
||||
cap.release()
|
||||
cv2.destroyAllWindows()
|
||||
|
||||
# 选择测试模式
|
||||
mode = input("选择模式 (1: 图片检测, 2: 摄像头实时检测): ")
|
||||
|
||||
if mode == "1":
|
||||
image_path = input("输入图片路径: ")
|
||||
test_image(image_path)
|
||||
elif mode == "2":
|
||||
test_camera()
|
||||
else:
|
||||
print("无效选择")
|
||||
|
||||
# 释放资源
|
||||
detector.release()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Binary file not shown.
Loading…
Reference in New Issue
Block a user