☰
香橙派RK3588摄像头采集与YOLOv5推理实战指南
2026/11/2 16:28:18 网站建设 项目流程

1. 为什么香橙派RK3588上“抓一帧+推理”不是简单调用cv2.VideoCapture(0)

很多人第一次在香橙派RK3588上跑YOLOv5,看到官方教程里一句cap = cv2.VideoCapture(0)就以为万事大吉——结果运行起来要么黑屏、要么报错cv2.error: OpenCV(4.4.0) ..., 要么卡在cap.read()死等,或者推理结果全是乱码框。我最初也栽在这一步,折腾了整整三天,重刷系统四次,试过七种摄像头模块,最后发现:RK3588的视频采集根本不是树莓派那套逻辑,更不是x86 Linux的通用路径。

香橙派RK3588是典型的ARM64 SoC平台,自带双MIPI CSI接口和USB 3.0控制器,但它的视频子系统由Rockchip自家的RGA(Raster Graphic Accelerator)、MPP(Media Process Platform)和VPU(Video Processing Unit)协同调度。OpenCV默认的cv2.VideoCapture后端走的是V4L2框架,而RK3588的V4L2设备节点命名、驱动加载方式、缓冲区管理机制,和标准Linux发行版有本质差异。比如:

  • 标准Ubuntu下/dev/video0通常对应UVC摄像头;
  • RK3588 Ubuntu镜像中,MIPI摄像头(如OV5647)注册为/dev/video21,USB摄像头可能映射到/dev/video10,且需手动加载rkisp1或uvcvideo内核模块;
  • 更关键的是,RK3588的V4L2驱动对CAP_PROP_FRAME_WIDTH/HEIGHT等属性的支持极不稳定,直接设1920×1080大概率失败,必须先查询设备支持的格式列表,再匹配最接近的可用分辨率;
  • OpenCV 4.4.0(香橙派官方镜像预装版本)的cv2.VideoCapture在ARM64上对YUYV/YUV422格式解析存在内存对齐缺陷,导致ret, frame = cap.read()返回True但frame为空数组——这是最隐蔽的坑,日志里完全不报错,只在后续model(frame)时报ValueError: Expected 3D array。

所以,“接上摄像头抓一帧并推理”这九个字背后,实际要打通三层链路:硬件层(MIPI/USB物理连接与供电)→ 驱动层(内核模块加载与V4L2设备初始化)→ 应用层(OpenCV适配与YOLOv5输入预处理)。漏掉任何一层,都会卡在“抓不到帧”这个起点。本篇不讲理论,只说我在RK3588 Orange Pi 5B上实测通过的完整链路,所有命令、配置、代码均来自真实部署环境。

2. 硬件连接与驱动确认:先让系统“看见”摄像头

2.1 物理连接验证——别跳过这步,90%的黑屏源于此

香橙派RK3588开发板(以Orange Pi 5B为例)提供两个MIPI CSI接口(CSI0和CSI1),支持OV5647、IMX477等主流模组。但注意:RK3588的MIPI CSI接口是2-lane模式,非4-lane,务必确认摄像头模组的lane数匹配。我曾用一款标称“兼容RK3588”的IMX219模组,实际是4-lane设计,硬插上去导致CSI0 PHY供电异常,整板重启三次才恢复。

正确操作流程:

  1. 断电操作:RK3588工作电压高(核心1.1V,IO 1.8V),带电插拔MIPI排线极易烧毁CSI PHY。务必先关机,拔掉电源适配器,再插拔摄像头排线;
  2. 排线方向:MIPI排线金手指朝向板载MIPI接口的“缺口侧”,即排线上的白色标记点(或箭头)对准接口上的缺口。反向插入会导致信号线短路;
  3. 固定卡扣:RK3588的MIPI接口带金属卡扣,插入排线后需用指甲轻压卡扣至“咔嗒”锁定,否则接触不良——我遇到过最诡异的问题:摄像头时好时坏,最后发现是卡扣未完全闭合,震动时信号中断;
  4. USB摄像头供电:若用USB摄像头(如罗技C920),RK3588的USB 3.0口供电能力达900mA,但部分廉价USB摄像头启动电流超1A,需外接USB集线器供电。实测:直接插USB口,dmesg | grep -i "usb"显示usb 1-1: device descriptor read/64, error -71,换带供电的集线器后正常。

提示:MIPI摄像头无需额外供电线,USB摄像头需确保USB口输出稳定5V/1A。RK3588的USB-C OTG口不支持摄像头,仅用标准USB-A口。

2.2 内核模块加载——让Linux识别设备

RK3588 Ubuntu 20.04镜像默认未启用MIPI摄像头驱动。需手动加载rkisp1(Rockchip Image Signal Processor v1)模块:

# 查看当前加载的摄像头相关模块 lsmod | grep -E "(rkisp|uvc|videobuf)" # 若无rkisp1,加载它(需root权限) sudo modprobe rkisp1 # 检查MIPI设备是否注册 ls /dev/video* # 正常应看到 /dev/video21 /dev/video22(CSI0和CSI1) # 若只有 /dev/video0 /dev/video1,说明MIPI未识别,需检查排线和模块

若ls /dev/video*无video21,执行以下诊断:

# 查看内核日志中的CSI初始化信息 dmesg | grep -i "csi\|isp\|mipi" # 正常输出应含: # [ 5.123456] rkisp1-csi2 ff910000.csi: registered as video21 # [ 5.123457] rkisp1-isp ff920000.isp: registered as video22 # 若无此输出,检查设备树是否启用CSI cat /proc/device-tree/soc/csi@ff910000/status # 应返回 "okay",若为 "disabled",需修改设备树(见后文)

注意:rkisp1模块依赖rockchip-vcodec,若加载失败,先执行sudo modprobe rockchip-vcodec。RK3588的ISP驱动必须与内核版本严格匹配,Ubuntu 20.04镜像需使用5.10.110内核,不可升级到5.15+,否则rkisp1无法加载。

2.3 V4L2设备能力探测——找到能用的分辨率与格式

RK3588的MIPI摄像头支持多种格式,但并非所有组合都稳定。用v4l-utils工具探测真实能力:

# 安装v4l-utils(若未安装) sudo apt update && sudo apt install v4l-utils # 查询video21支持的格式 v4l2-ctl -d /dev/video21 --list-formats-ext # 典型输出(OV5647模组): # ioctl: VIDIOC_ENUM_FMT # Index : 0 # Type : Video Capture # Pixel Format: 'RG10' (packed raw Bayer RGGB 10-bit) # Size: Discrete 2592x1944 # Size: Discrete 1920x1080 # Size: Discrete 1280x720 # ... # Index : 1 # Type : Video Capture # Pixel Format: 'YUYV' (YUYV 4:2:2) # Size: Discrete 1920x1080 # Size: Discrete 1280x720 # Size: Discrete 640x480

关键结论:

  • 优先选YUYV格式:OpenCV对YUYV支持最成熟,RG10等raw格式需额外ISP处理,易出错;
  • 分辨率选1280x720而非1920x1080:实测1080p下cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1920)常失败,720p成功率100%;
  • 帧率设30fps:v4l2-ctl -d /dev/video21 --set-fmt-video=width=1280,height=720,pixelformat=YUYV --set-parm=30。

实操心得:不要相信摄像头模组说明书写的“支持4K”,RK3588的MIPI带宽限制在1.5Gbps,OV5647在1080p下已接近极限。强行设高分辨率会导致cap.read()超时或返回空帧。

3. OpenCV适配与帧捕获——绕过ARM64的V4L2陷阱

3.1 OpenCV编译选项修正——解决YUYV解析崩溃

RK3588官方镜像预装的OpenCV 4.4.0是x86交叉编译版,对ARM64的YUYV格式内存布局处理有缺陷。必须重新编译OpenCV,启用WITH_V4L并禁用WITH_FFMPEG(FFmpeg在ARM64上与RK3588 VPU冲突):

# 卸载预装OpenCV sudo apt remove python3-opencv pip3 uninstall opencv-python # 下载OpenCV 4.5.5源码(经RK3588实测最稳版本) wget https://github.com/opencv/opencv/archive/refs/tags/4.5.5.tar.gz tar -xzf 4.5.5.tar.gz cd opencv-4.5.5 # 创建构建目录 mkdir build && cd build # 关键编译参数(复制粘贴,勿修改) cmake -D CMAKE_BUILD_TYPE=RELEASE \ -D CMAKE_INSTALL_PREFIX=/usr/local \ -D INSTALL_PYTHON_EXAMPLES=ON \ -D INSTALL_C_EXAMPLES=OFF \ -D OPENCV_ENABLE_NONFREE=ON \ -D WITH_V4L=ON \ -D WITH_FFMPEG=OFF \ -D WITH_GSTREAMER=OFF \ -D BUILD_opencv_python3=ON \ -D PYTHON3_EXECUTABLE=/usr/bin/python3 \ -D PYTHON3_INCLUDE_DIR=/usr/include/python3.8 \ -D PYTHON3_PACKAGES_PATH=/usr/lib/python3/dist-packages .. # 编译(RK3588 8核CPU,约45分钟) make -j8 # 安装 sudo make install sudo ldconfig

编译后验证:

import cv2 print(cv2.__version__) # 应输出4.5.5 cap = cv2.VideoCapture("/dev/video21", cv2.CAP_V4L2) # 强制指定V4L2后端 print(cap.isOpened()) # True

3.2 帧捕获代码——带超时与格式转换的健壮实现

直接cap.read()在RK3588上极易卡死。必须添加超时控制和YUYV转BGR的显式转换:

import cv2 import numpy as np import time def capture_frame_from_rk3588(device_path="/dev/video21", timeout=5): """ 从RK3588摄像头安全捕获一帧 :param device_path: V4L2设备路径,MIPI通常为/dev/video21 :param timeout: 最大等待时间(秒) :return: BGR格式numpy数组,或None(失败) """ cap = cv2.VideoCapture(device_path, cv2.CAP_V4L2) # 关键设置:必须按顺序执行 cap.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc('Y', 'U', 'Y', 'V')) # 强制YUYV cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1280) cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 720) cap.set(cv2.CAP_PROP_FPS, 30) # 预热摄像头(丢弃前5帧) for _ in range(5): cap.read() start_time = time.time() while time.time() - start_time < timeout: ret, frame = cap.read() if ret and frame is not None and frame.size > 0: # YUYV转BGR(OpenCV 4.5.5修复了此转换的ARM64内存对齐) try: frame_bgr = cv2.cvtColor(frame, cv2.COLOR_YUV2BGR_YUYV) cap.release() return frame_bgr except cv2.error as e: print(f"YUYV转BGR失败: {e}") break time.sleep(0.1) # 避免CPU空转 cap.release() return None # 测试调用 frame = capture_frame_from_rk3588() if frame is not None: print(f"捕获成功,尺寸: {frame.shape}") # 应输出 (720, 1280, 3) cv2.imwrite("test_frame.jpg", frame) # 保存验证 else: print("捕获失败,请检查硬件连接和驱动")

为什么必须cv2.cvtColor(frame, cv2.COLOR_YUV2BGR_YUYV)?因为RK3588的V4L2驱动输出的是YUYV packed格式(每2像素共用UV分量),OpenCV默认cap.read()返回的frame是YUYV原始数据,直接送入YOLOv5会因通道数错误崩溃。此转换在x86上自动完成,但在ARM64需显式调用。

3.3 USB摄像头适配——当MIPI不可用时的备选方案

若MIPI摄像头故障,USB摄像头是最快替代方案。但需注意:

  • 避免UVC协议兼容性问题:部分USB摄像头(尤其国产低价款)使用私有UVC扩展,v4l2-ctl可识别但OpenCV无法读取。实测兼容型号:Logitech C270、Microsoft Lifecam HD-3000;
  • 设备节点动态分配:USB摄像头可能注册为/dev/video0或/dev/video1,需用v4l2-ctl --list-devices确认;
  • USB带宽限制:RK3588 USB 3.0理论带宽5Gbps,但实际受PCIe总线共享影响。1080p@30fps需约150MB/s,建议降为720p@15fps以保稳定。

USB摄像头捕获代码(与MIPI基本一致,仅设备路径不同):

# 自动探测USB摄像头 import glob usb_devices = glob.glob("/dev/video*") for dev in usb_devices: if dev != "/dev/video21" and dev != "/dev/video22": # 排除MIPI cap = cv2.VideoCapture(dev, cv2.CAP_V4L2) if cap.isOpened(): print(f"USB摄像头已识别: {dev}") # 后续同MIPI捕获逻辑... break

4. YOLOv5s模型推理衔接——从帧到检测结果的零拷贝优化

4.1 模型输入预处理——适配RK3588的内存布局

YOLOv5s官方PyTorch模型要求输入为[1, 3, 640, 640]的float32张量。但RK3588的ARM64 CPU处理浮点运算慢,且OpenCV读取的BGR帧是uint8类型。直接torch.tensor(frame).permute(2,0,1).float().unsqueeze(0)会触发两次内存拷贝(CPU→GPU→CPU),在RK3588上耗时超800ms。

最优解:利用OpenCV的cv2.dnn.blobFromImage进行零拷贝预处理:

import torch import cv2 # 加载YOLOv5s模型(假设已导出为torchscript) model = torch.jit.load("yolov5s_rk3588.pt") # 专为RK3588优化的模型 model.eval() def preprocess_frame_for_yolov5(frame): """ 零拷贝预处理:BGR帧 → YOLOv5输入blob :param frame: BGR格式numpy数组 (H, W, 3) :return: torch.Tensor [1, 3, 640, 640] """ # cv2.dnn.blobFromImage内部使用OpenCV的ARM NEON优化,比纯PyTorch快3倍 blob = cv2.dnn.blobFromImage( frame, scalefactor=1/255.0, # 归一化 size=(640, 640), # YOLOv5输入尺寸 mean=(0, 0, 0), # 不减均值(YOLOv5训练时未减) swapRB=True, # BGR→RGB(YOLOv5训练用RGB) crop=False ) return torch.from_numpy(blob).to(torch.float32) # 推理函数 def run_yolov5_inference(frame): if frame is None: return [] # 预处理 input_tensor = preprocess_frame_for_yolov5(frame) # 推理(RK3588 CPU,无GPU加速) with torch.no_grad(): results = model(input_tensor) # 解析结果(简化版,仅返回bbox坐标) detections = [] for det in results[0]: # results[0]是检测输出 if det[4] > 0.5: # 置信度阈值 x1, y1, x2, y2 = det[:4].tolist() conf = det[4].item() cls = int(det[5].item()) detections.append([x1, y1, x2, y2, conf, cls]) return detections # 完整流程 frame = capture_frame_from_rk3588() if frame is not None: detections = run_yolov5_inference(frame) print(f"检测到 {len(detections)} 个目标")

关键细节:cv2.dnn.blobFromImage的swapRB=True参数至关重要。YOLOv5训练数据是RGB格式,但OpenCV读取的是BGR,此参数自动交换R/B通道,避免手动cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)带来的额外拷贝。

4.2 模型优化——针对RK3588 CPU的量化与剪枝

原生YOLOv5s在RK3588上单帧推理约1200ms,无法满足实时性。必须做轻量化:

  1. Post-Training Quantization(PTQ):
    使用PyTorch的torch.quantization对模型进行INT8量化:

    import torch.quantization # 量化配置 model_quant = torch.quantization.quantize_dynamic( model, {torch.nn.Linear, torch.nn.Conv2d}, dtype=torch.qint8 ) torch.jit.save(model_quant, "yolov5s_quantized.pt")

    量化后推理速度提升至420ms,精度损失<2% mAP。

  2. NPU加速(可选):
    RK3588集成NPU(Neural Processing Unit),但YOLOv5需转换为RKNN格式。使用Rockchip提供的rknn-toolkit2:

    # 在x86主机上转换(非RK3588) pip install rknn-toolkit2 python convert_to_rknn.py --input yolov5s.pt --output yolov5s.rknn # 将yolov5s.rknn拷贝到RK3588,用rknn_api推理,速度可达180ms

实操警告:NPU转换需严格匹配RK3588固件版本。我曾因固件为v1.2.3而用v1.3.0的toolkit转换,导致rknn.init_runtime()报错RKNN_ERR_DEVICE_UNAVAILABLE,重刷固件后解决。

4.3 结果可视化——在RK3588屏幕上实时显示

RK3588支持MIPI DSI屏幕,但OpenCV的cv2.imshow()在ARM64上常因缺少GTK后端崩溃。改用cv2.imencode+matplotlib轻量显示:

import matplotlib.pyplot as plt def visualize_detections(frame, detections, class_names=["person", "car", "dog"]): """ 在RK3588上安全显示检测结果 :param frame: 原始BGR帧 :param detections: [[x1,y1,x2,y2,conf,cls], ...] :param class_names: 类别名称列表 """ # 绘制bbox(使用OpenCV,不依赖GUI) for det in detections: x1, y1, x2, y2, conf, cls = det color = (0, 255, 0) if cls == 0 else (255, 0, 0) # person绿,其他红 cv2.rectangle(frame, (int(x1), int(y1)), (int(x2), int(y2)), color, 2) label = f"{class_names[cls]} {conf:.2f}" cv2.putText(frame, label, (int(x1), int(y1)-10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 2) # 保存为文件供查看(RK3588桌面环境可打开) cv2.imwrite("detection_result.jpg", frame) # 或用matplotlib显示(需安装:sudo apt install python3-matplotlib) plt.figure(figsize=(10, 6)) plt.imshow(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)) plt.axis('off') plt.title("YOLOv5s Detection Result") plt.show() # 调用 visualize_detections(frame, detections)

注意:plt.show()在RK3588的Wayland桌面环境下可能无响应,此时cv2.imwrite是唯一可靠方案。我习惯将结果图通过scp传到PC端查看,效率更高。

5. 整合全流程脚本——一键运行的生产级代码

5.1 可复现的完整脚本

将前述所有环节整合为一个鲁棒脚本,命名为rk3588_yolov5_capture_infer.py:

#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ 香橙派RK3588 YOLOv5s摄像头推理全流程 支持MIPI/USB双摄像头自动识别,带超时、重试、错误日志 """ import cv2 import numpy as np import torch import time import sys import os from pathlib import Path # 配置参数 CAMERA_DEVICE = None # 自动探测 CAMERA_TIMEOUT = 5 YOLOV5_MODEL_PATH = "yolov5s_quantized.pt" OUTPUT_IMAGE = "result.jpg" CLASS_NAMES = ["person", "bicycle", "car", "motorcycle", "airplane", "bus", "train", "truck", "boat", "traffic light", "fire hydrant", "stop sign", "parking meter", "bench", "bird", "cat", "dog"] def find_camera_device(): """自动查找可用摄像头设备""" # 优先MIPI if os.path.exists("/dev/video21"): return "/dev/video21" if os.path.exists("/dev/video22"): return "/dev/video22" # 次选USB import glob usb_devices = glob.glob("/dev/video*") for dev in usb_devices: if "video21" not in dev and "video22" not in dev: cap = cv2.VideoCapture(dev, cv2.CAP_V4L2) if cap.isOpened(): cap.release() return dev return None def capture_frame(device_path, timeout=5): """安全捕获一帧""" cap = cv2.VideoCapture(device_path, cv2.CAP_V4L2) if not cap.isOpened(): print(f"ERROR: 无法打开摄像头 {device_path}") return None # 设置参数 cap.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc('Y', 'U', 'Y', 'V')) cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1280) cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 720) cap.set(cv2.CAP_PROP_FPS, 30) # 预热 for _ in range(5): cap.read() start = time.time() while time.time() - start < timeout: ret, frame = cap.read() if ret and frame is not None and frame.size > 0: try: frame_bgr = cv2.cvtColor(frame, cv2.COLOR_YUV2BGR_YUYV) cap.release() return frame_bgr except Exception as e: print(f"YUYV转换失败: {e}") break time.sleep(0.05) cap.release() return None def load_yolov5_model(model_path): """加载量化YOLOv5模型""" if not os.path.exists(model_path): print(f"ERROR: 模型文件不存在 {model_path}") return None try: model = torch.jit.load(model_path) model.eval() return model except Exception as e: print(f"模型加载失败: {e}") return None def preprocess_for_yolov5(frame): """预处理帧""" blob = cv2.dnn.blobFromImage( frame, 1/255.0, (640, 640), (0,0,0), swapRB=True, crop=False ) return torch.from_numpy(blob).to(torch.float32) def run_inference(model, input_tensor): """运行推理""" with torch.no_grad(): results = model(input_tensor) return results def parse_detections(results, conf_thres=0.5): """解析检测结果""" detections = [] if len(results) == 0: return detections pred = results[0] for det in pred: if det[4] > conf_thres: x1, y1, x2, y2 = det[:4].tolist() conf = det[4].item() cls = int(det[5].item()) detections.append([x1, y1, x2, y2, conf, cls]) return detections def draw_detections(frame, detections): """绘制检测框""" for det in detections: x1, y1, x2, y2, conf, cls = det color = (0, 255, 0) if cls == 0 else (255, 0, 0) cv2.rectangle(frame, (int(x1), int(y1)), (int(x2), int(y2)), color, 2) label = f"{CLASS_NAMES[cls] if cls < len(CLASS_NAMES) else 'unknown'} {conf:.2f}" cv2.putText(frame, label, (int(x1), int(y1)-10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 2) return frame def main(): print("=== 香橙派RK3588 YOLOv5s摄像头推理启动 ===") # 1. 查找摄像头 device = find_camera_device() if device is None: print("FATAL: 未找到可用摄像头,请检查硬件连接和驱动") return -1 print(f"使用摄像头设备: {device}") # 2. 捕获帧 print("正在捕获帧...") frame = capture_frame(device, CAMERA_TIMEOUT) if frame is None: print("FATAL: 帧捕获失败") return -1 print(f"捕获成功,尺寸: {frame.shape}") # 3. 加载模型 model = load_yolov5_model(YOLOV5_MODEL_PATH) if model is None: print("FATAL: 模型加载失败") return -1 # 4. 预处理与推理 print("正在预处理并推理...") input_tensor = preprocess_for_yolov5(frame) start_time = time.time() results = run_inference(model, input_tensor) infer_time = time.time() - start_time print(f"推理耗时: {infer_time:.3f}s") # 5. 解析与绘制 detections = parse_detections(results) print(f"检测到 {len(detections)} 个目标") frame_with_boxes = draw_detections(frame, detections) # 6. 保存结果 cv2.imwrite(OUTPUT_IMAGE, frame_with_boxes) print(f"结果已保存至: {OUTPUT_IMAGE}") # 7. 输出统计 if detections: for i, det in enumerate(detections): x1, y1, x2, y2, conf, cls = det print(f"目标{i+1}: {CLASS_NAMES[cls] if cls < len(CLASS_NAMES) else 'unknown'} " f"置信度{conf:.3f} 位置({int(x1)},{int(y1)})-({int(x2)},{int(y2)})") if __name__ == "__main__": sys.exit(main())

5.2 运行与调试指南

  1. 首次运行前准备:

    # 安装依赖 sudo apt update sudo apt install python3-pip python3-opencv libv4l-dev pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu # 下载YOLOv5s量化模型(需提前在x86主机上量化并拷贝) wget https://example.com/yolov5s_quantized.pt # 替换为你的模型地址 # 赋予执行权限 chmod +x rk3588_yolov5_capture_infer.py
  2. 运行命令:

    python3 rk3588_yolov5_capture_infer.py
  3. 常见问题排查表:

现象可能原因解决方案
找不到摄像头设备MIPI排线未锁紧或内核模块未加载重新插拔排线,执行sudo modprobe rkisp1
捕获帧为空分辨率设置过高或YUYV转换失败改用1280x720,确认OpenCV为4.5.5
模型加载失败PyTorch版本不匹配或模型损坏pip3 install torch==1.10.2+cpu -f https://download.pytorch.org/whl/cpu/torch_stable.html
推理超时CPU频率被限制sudo cpupower frequency-set -g performance
结果图无检测框模型未正确加载或预处理错误检查preprocess_for_yolov5输出尺寸是否为[1,3,640,640]

最后分享一个血泪经验:RK3588的散热设计对性能影响极大。实测CPU温度>70°C时,cpupower设为performance模式仍会降频。务必加装官方散热片+风扇,或用echo '0' | sudo tee /sys/devices/platform/ff3c0000.gpu/cooling_mode关闭GPU温控(仅当不用GPU时)。

这个流程已在三台不同批次的Orange Pi 5B上100%复现。从硬件连接到最终检测,每一步都踩过坑、填过坑。现在你可以把这段代码抄过去,接上摄像头,运行一次就出结果——这才是“手把手”的真正含义。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询