无垠的广袤 · 1 天前 · 上海

【“星睿O6”AI PC开发套件评测】物体识别

【“星睿O6”AI PC开发套件评测】物体识别

本文介绍了瑞莎星睿 O6 (Radxa Orion O6) 开发板结合 YOLO 模型实现物体识别的项目设计,包括通过 CPU 和 NPU 实现板端推理的相关流程。

项目介绍

  • 准备工作:包括所需 Python 环境以及软件包的安装部署等;
  • CPU 推理:使用 YOLOv5n 等轻量化 ONNX 模型实现物体识别的板端推理;
  • NPU 推理:结合官方 NPU SDK 实现预训练模型导出、实现板端 NPU 对目标图片的物体识别。

ONNX

Open Neural Network Exchange (ONNX) 是一个开放的生态系统,为 AI 开发人员提供支持 随着项目的发展选择正确的工具。

ONNX 为 AI 模型(包括深度学习和传统 ML)提供开源格式。它定义了一个可扩展的计算图模型,以及内置运算符和标准的定义 数据类型。

详见:onnx/onnx: Open standard for machine learning interoperability .

YOLO

YOLO(You Only Look Once)是一种流行的目标检测算法,它以其快速和准确性而闻名。YOLO算法的核心思想是将目标检测问题转化为一个回归问题,通过一个单一的卷积神经网络(CNN)直接从输入图像预测边界框和类别概率。

YOLO 的主要优点是速度快,能够实时处理视频流。它还具有较强的通用性,能够迁移到新的领域。

YOLOv5n 代表了目标检测方法的进步,源于 Ultralytics 开发的 YOLOv5 模型的基础架构,调整优化了模型架构,从而在目标检测任务中实现了更高的精度-速度权衡。YOLOv5 为那些在研究和实际应用中寻求稳健解决方案的人们提供了高效的解决方案。

详见:主页 - Ultralytics YOLO 文档 .

准备工作

主要包括硬件连接、系统安装、环境部署、模型下载等。

硬件连接

库安装

  • 执行指令 sudo apt install python3-opencv 安装 OpenCV
  • 安装解析 ONNX 模型所需的 onnxruntime 库,终端执行
sudo apt install python3-pip
sudo pip3 install onnxruntime --break-system-packages

模型下载

  • 下载 CPU 推理所需的 ONNX 模型文件
wget https://github.com/ultralytics/yolov5/releases/download/v7.0/yolov5n.onnx
  • 下载 radxa 预编译完成的 yolov8_l.cix 模型文件
wget https://modelscope.cn/models/cix/ai_model_hub_24_Q4/resolve/master/models/ComputeVision/Object_Detection/onnx_yolov8_l/yolov8_l.cix

体积约 40MB

CPU 推理

包括流程图、关键代码、效果演示等。

流程图

flowchart_or_cpu.png

代码

终端执行 touch or_cpu.py 指令新建文件,并使用 nano 文本编辑器添加如下代码

#!/usr/bin/env python3
import cv2, numpy as np, onnxruntime as ort
from pathlib import Path

COCO_NAMES = ["person","bicycle","car","motorcycle","airplane","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","couch",
              "potted plant","bed","dining table","toilet","tv","laptop","mouse","remote","keyboard","cell phone",
              "microwave","oven","toaster","sink","refrigerator","book","clock","vase","scissors","teddy bear",
              "hair drier","toothbrush"]

MODEL_PATH = "models/yolov5n.onnx"
IMG_PATH   = "img/desktop.jpg"

# ---------- 1. 加载 FP16 模型 ----------
sess = ort.InferenceSession(MODEL_PATH, providers=['CPUExecutionProvider'])
in_name  = sess.get_inputs()[0].name   # 期望 tensor(float16)
out_name = sess.get_outputs()[0].name

# ---------- 2. 读图 ----------
img0 = cv2.imread(IMG_PATH)
if img0 is None: raise FileNotFoundError(IMG_PATH)

# ---------- 3. 预处理(FP16 + 640×640) ----------
blob = cv2.resize(img0, (640, 640))
blob = (blob.astype(np.float16) / 255.0).transpose(2, 0, 1)[None]  # <- 关键:float16

# ---------- 4. 推理 ----------
outputs = sess.run([out_name], {in_name: blob})[0]
outputs = np.squeeze(outputs)                                       # [25200,85]

# ---------- 5. 后处理 + 画框 ----------
boxes, scores, class_ids = [], [], []
for pred in outputs:
    x, y, w, h, conf = pred[:5]
    if conf < 0.25: continue
    cls = int(np.argmax(pred[5:]))
    scores.append(float(conf))
    class_ids.append(cls)
    # 映射回原图
    x1 = int((x - w / 2) * img0.shape[1] / 640)
    y1 = int((y - h / 2) * img0.shape[0] / 640)
    x2 = int((x + w / 2) * img0.shape[1] / 640)
    y2 = int((y + h / 2) * img0.shape[0] / 640)
    boxes.append([x1, y1, x2 - x1, y2 - y1])

indices = cv2.dnn.NMSBoxes(boxes, scores, score_threshold=0.25, nms_threshold=0.45)
if indices is not None:
    for i in indices.flatten():
        x, y, w, h = boxes[i]
        label = f"{COCO_NAMES[class_ids[i]]} {scores[i]:.2f}"
        cv2.rectangle(img0, (x, y), (x + w, y + h), (0, 255, 0), 2)
        cv2.putText(img0, label, (x, y - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2)

# ---------- 6. 弹窗 ----------
cv2.imshow("YOLOv5n-FP16-ORT", img0)
cv2.waitKey(0)
cv2.destroyAllWindows()

保存代码。

效果

终端执行 python or_cpu.py ,弹窗显示推理后的图片

desktop.jpg

NPU 推理

包括流程图、关键代码、效果演示等。

加载预编译的 *.cix 格式模型文件;

python3 inference_npu.py --image_path ./test_data/ --model_path ./yolov8_l.cix

流程图

flowchart_or_npu.png

代码

打开 inference_npu.py 文件,代码如下

import cv2
import numpy as np
import argparse
import os
import sys
from tqdm import tqdm

_abs_path = os.path.join(os.path.dirname(__file__), "../../../../")
sys.path.append(_abs_path)
from utils.tools import get_file_list
from utils.image_process import preprocess_object_detect_method1
from utils.object_detect_postprocess import postprocess_yolo, xywh2xyxy
from utils.draw import draw_coco as draw
from utils.NOE_Engine import EngineInfer


def get_args():
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "--image_path",
        default="test_data",
        help="path to the image file",
    )
    parser.add_argument(
        "--model_path",
        default="yolov12_n.cix",
        help="path to the quant model file",
    )
    parser.add_argument(
        "--output_dir", default="./output", help="path to the result output"
    )
    parser.add_argument(
        "--conf_thr",
        type=float,
        default=0.3,
        help="Score threshould to filter the result.",
    )
    parser.add_argument(
        "--nms_thr", type=float, default=0.45, help="NMS threshould to the object."
    )
    args = parser.parse_args()
    return args


if __name__ == "__main__":
    args = get_args()
    os.makedirs(args.output_dir, exist_ok=True)
    # Get list of images from the specified path
    image_list = get_file_list(args.image_path)
    model = EngineInfer(args.model_path)
    image_list = get_file_list(args.image_path)

    for img_name in tqdm(image_list):
        # Preprocess the image for inference
        src_shape, new_shape, show_image, data = preprocess_object_detect_method1(
            img_name, target_size=(640, 640), mode="BGR"
        )

        # Run inference and get predictions
        pred = model.forward(data.astype(np.float32))[0]
        pred = np.reshape(pred, (84, 8400))
        pred = np.transpose(pred, (1, 0))

        # bboxes, conf, class_id
        results = postprocess_yolo(pred, args.conf_thr, args.nms_thr)
        if len(results) == 0:
            output_path = os.path.join(args.output_dir,"npu_" + os.path.basename(img_name))
            # Save the resulting image to the output directory
            cv2.imwrite(output_path, show_image)
            continue
        bbox_xywh = results[:, :4]
        bbox_xyxy = xywh2xyxy(bbox_xywh)
        x_scale = src_shape[1] / new_shape[1]
        y_scale = src_shape[0] / new_shape[0]
        bbox_xyxy *= (x_scale, y_scale, x_scale, y_scale)

        ret_img = draw(show_image, bbox_xyxy, results[:, 5], results[:, 4])
        output_path = os.path.join(args.output_dir, "npu_" + os.path.basename(img_name))
        # Save the resulting image to the output directory
        cv2.imwrite(output_path, ret_img)
    model.clean()

终端执行 NPU 推理程序 python3 inference_npu.py ,输出推理结果

v) radxa@orion-o6:~/NOE/ai_model_hub/models/ComputeVision/Object_Detection/onnx_yolov8_l$ time python3 inference_npu.py --image_path ./test_data/ --model_path ./yolov8_l.cix
npu: noe_init_context success
npu: noe_load_graph success
Input tensor count is 1.
Output tensor count is 1.
npu: noe_create_job success
100%|█████████████████████████████████████████████████████████████████████████████████████████████████████| 2/2 [00:00<00:00,  8.08it/s]
npu: noe_clean_job success
npu: noe_unload_graph success
npu: noe_deinit_context success

real    0m3.884s
user    0m3.391s
sys    0m0.400s

结果保存在 output_npu 文件夹。

效果

  • 将目标图片放置于 test_data 文件夹,执行 python3 inference_npu.py 指令;
  • 打开 output_npu 文件夹中输出的图片,识别结果被精准地框选出来;

onnx_000000007977.jpg

onnx_1.jpeg

  • 更多场景应用举例

运动

onnx_sport.jpg

骑行

onnx_horse.jpg

小路

onnx_dog.jpg

户外

onnx_bicycle.jpg

路口

onnx_road.jpg

家居

onnx_room.jpg

总结

本文介绍了瑞莎星睿 O6 (Radxa Orion O6) 开发板结合 YOLO 模型实现物体识别的项目设计,包括通过 CPU 和 NPU 实现板端推理的相关流程,为相关产品在 AI 视觉领域的开发设计和快速应用提供了参考。

推荐阅读
关注数
2
文章数
14
MCU 开发者和爱好者
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息