rdk x5 tuning求助

您好!针对您关于 RDK X5 MJPEG 硬件解码格式YOLO 主流输入格式 的问题,结合社区实战案例(参考 Topic 29100),解答如下:


:one: RDK X5 MJPEG 硬件解码输出格式

RDK X5 的硬件解码器(libsrcampy 或底层 hbm 接口)在解码 MJPEG 流时,默认输出为 NV12 格式

  • NV12 是一种 YUV 4:2:0 的存储格式:
    • Y 分量(亮度):全分辨率
    • UV 分量(色度):水平和垂直方向都减半,交错存储
  • 内存布局Y 平面 + UV 交错平面,总大小为 width × height × 1.5 字节。

:white_check_mark: 硬件解码示例(Python):

from hobot_vio import libsrcampy
import cv2
import numpy as np

# 初始化解码器 (3 代表 MJPEG)
dec = libsrcampy.Decoder()
ret = dec.decode("", 0, 3, imgw, imgh)

# 传入 MJPEG 数据
dec.set_img(mjpg_byte_data)

# 获取解码后的 NV12 数据
nv12_data = dec.get_img()  # 返回 bytes

# 转换为 BGR 图像(用于显示或推理)
nv12_array = np.frombuffer(nv12_data, dtype=np.uint8).reshape(imgh * 3 // 2, imgw)
bgr_img = cv2.cvtColor(nv12_array, cv2.COLOR_YUV2BGR_NV12)

:warning: 注意:硬件解码器不支持直接输出 BGR/RGB,必须先解为 NV12,再用 OpenCV 或 BPU 预处理模块转为 BGR。


:two: YOLO 主流输入格式

在 RDK X5 上部署 YOLO 系列模型(v5/v8/v10/v11),主流输入格式为 BGR,且通常要求:

项目 要求
颜色空间 BGR(OpenCV 默认)
数据布局 NHWC(Batch, Height, Width, Channel)
像素范围 0-255(uint8)或 0.0-1.0(float32,需归一化)
输入尺寸 常见为 640×640,也支持 320×3201280×1280 等(取决于模型训练配置)
预处理方式 Resize + Letterbox(保持宽高比,填充灰边)或 Stretch Resize(直接拉伸)

:white_check_mark: YOLO 推理前预处理示例:

import cv2
import numpy as np

def preprocess_yolo(img, input_size=(640, 640)):
    # img 是 BGR 格式
    h, w = img.shape[:2]
    new_h, new_w = input_size
    
    # 方式一:Letterbox(推荐,保持比例)
    scale = min(new_w / w, new_h / h)
    new_w, new_h = int(w * scale), int(h * scale)
    resized = cv2.resize(img, (new_w, new_h), interpolation=cv2.INTER_LINEAR)
    
    # 填充灰边
    pad_w = (new_w - new_w) // 2
    pad_h = (new_h - new_h) // 2
    padded = np.full((new_h, new_w, 3), 114, dtype=np.uint8)
    padded[pad_h:pad_h+new_h, pad_w:pad_w+new_w] = resized
    
    # 归一化到 0-1 (如模型需要)
    # padded = padded.astype(np.float32) / 255.0
    
    return padded

:link: 完整流程:MJPEG 摄像头 → YOLO 推理

# 1. 采集 MJPEG(设置 V4L2 + MJPG 模式)
cap = cv2.VideoCapture(0, cv2.CAP_V4L2)
cap.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc('M', 'J', 'P', 'G'))
cap.set(cv2.CAP_PROP_CONVERT_RGB, 0)  # 不转 RGB,取原始 MJPG

# 2. 硬件解码为 NV12
ret, mjpg_frame = cap.read()
nv12_data = decoder.decode(mjpg_frame.tobytes())

# 3. NV12 → BGR
bgr_img = cv2.cvtColor(nv12_array, cv2.COLOR_YUV2BGR_NV12)

# 4. YOLO 预处理(Resize + Letterbox)
input_tensor = preprocess_yolo(bgr_img, input_size=(640, 640))

# 5. BPU 推理
# ... (使用 hb_mapper 转换后的 bin 模型)

:pushpin: 关键总结

问题 答案
MJPEG 硬解码输出 NV12(YUV 4:2:0)
YOLO 输入格式 BGRNHWC640×640(常见)
颜色转换 NV12 → BGRcv2.COLOR_YUV2BGR_NV12
性能优化 使用硬解码 + BPU 预处理,避免 CPU 瓶颈

:books: 参考资源

如需具体代码模板或模型转换参数配置,可继续提问!:rocket: