RK3588 + YOLOv8 田块分割实战指南:从环境搭建到部署落地全流程

RK3588 + YOLOv8 田块分割实战指南:从环境搭建到部署落地全流程

引言:在智慧农业领域,田块分割是实现精准灌溉、变量施肥、作物长势监测的核心前提。依托 RK3588 强大的 NPU 算力(算力高达 6TOPS)与 YOLOv8 高效的实例分割能力,我们能快速构建低成本、高性能的田块分割系统。本文将从 0 到 1 拆解全流程,涵盖环境安装、数据集准备、模型训练、RKNN 模型转换、板端推理测试,新手也能轻松跟进!

一、环境搭建:PC 端训练环境 + RK3588 部署环境

核心需求:PC 端完成模型训练与导出,RK3588 端完成模型部署与推理,需保证两端环境兼容性。

1.1 PC 端训练环境搭建(Ubuntu 20.04 为例)

推荐使用 Anaconda 管理环境,避免依赖冲突:

  1. 安装 Anaconda 并创建虚拟环境
    # 下载并安装 Anaconda(略,官网可查) conda create -n yolov8-rk3588 python=3.9 conda activate yolov8-rk3588

  2. 安装 PyTorch 与 TorchVision(适配 YOLOv8,推荐 1.13.1 版本)
    pip3 install torch==1.13.1+cu117 torchvision==0.14.1+cu117 --extra-index-url https://download.pytorch.org/whl/cu117

  3. 安装 YOLOv8 核心依赖

    `# 安装 ultralytics(YOLOv8 官方库)

    pip install ultralytics

安装数据集标注工具(可选,用于自制数据集)

pip install labelme

安装其他辅助依赖

pip install opencv-python matplotlib numpy`

  1. 验证环境:运行如下命令,若无报错则环境正常
    from ultralytics import YOLO model = YOLO('yolov8n-seg.pt') # 加载预训练分割模型 print("环境验证成功!")

1.2 RK3588 端部署环境搭建(Ubuntu 22.04 系统)

核心依赖:RKNN Toolkit2(模型转换与推理)、OpenCV(图像处理)

  1. 安装 RKNN Toolkit2(适配 RK3588,推荐 1.4.0 版本)
    `# 安装依赖
    sudo apt-get install -y python3-pip python3-dev libopencv-dev

安装 RKNN Toolkit2(根据系统架构选择,RK3588 为 aarch64)

pip3 install rknn-toolkit2==1.4.0 -i https://pypi.tuna.tsinghua.edu.cn/simple\`

  1. 安装 OpenCV 开发库
    sudo apt-get install -y libopencv-core-dev libopencv-highgui-dev libopencv-imgproc-dev

  2. 验证环境:
    from rknn.api import RKNN rknn = RKNN() print("RK3588 部署环境验证成功!")

二、数据集准备与模型训练

田块分割属于实例分割任务,需标注田块区域的掩码(mask)信息。

2.1 数据集准备

  1. 数据采集:收集不同光照、不同角度的农田图像(建议至少 500 张,越多训练效果越好),分辨率统一调整为 640×640(适配 YOLOv8 输入)。

  2. 数据标注:使用 LabelMe 工具标注,打开终端输入 labelme,选择图像文件夹,点击"Create Polygons"标注田块轮廓,标签设为"field",标注完成后生成 JSON 文件。

  3. 格式转换:将 LabelMe 生成的 JSON 文件转换为 YOLOv8 所需的 txt 格式(包含目标框与掩码信息),可使用如下脚本:

    `import json

    import os

    import cv2

    import numpy as np

def labelme2yolo(labelme_dir, yolo_dir, class_names):

if not os.path.exists(yolo_dir):

os.makedirs(yolo_dir)

for json_file in os.listdir(labelme_dir):

if json_file.endswith('.json'):

读取 JSON 文件

with open(os.path.join(labelme_dir, json_file), 'r') as f:

data = json.load(f)

读取图像

img = cv2.imread(os.path.join(labelme_dir, data['imagePath']))

h, w = img.shape[:2]

生成 txt 文件

txt_path = os.path.join(yolo_dir, json_file.replace('.json', '.txt'))

with open(txt_path, 'w') as f:

for shape in data['shapes']:

label = shape['label']

if label not in class_names:

continue

class_id = class_names.index(label)

转换坐标(LabelMe 为像素坐标,YOLO 为归一化坐标)

points = np.array(shape['points'])

points[:, 0] /= w

points[:, 1] /= h

写入 txt(格式:class_id x1 y1 x2 y2 ...)

f.write(f"{class_id} " + " ".join(f"{x:.6f} {y:.6f}" for x, y in points) + "\n")

保存图像到 yolo 目录

cv2.imwrite(os.path.join(yolo_dir, data['imagePath']), img)

执行转换(class_names 为标注的标签列表)

labelme2yolo("labelme_data", "yolo_data", ["field"])`

  1. 数据集划分:将 yolo_data 文件夹分为 train(80%)、val(20%),目录结构如下:
    yolo_field_data/ ├── train/ │ ├── images/ # 训练图像 │ └── labels/ # 训练标签 └── val/ ├── images/ # 验证图像 └── labels/ # 验证标签

2.2 模型训练

  1. 创建 YOLOv8 配置文件:在 ultralytics/cfg/datasets/ 目录下创建 field_seg.yaml,内容如下:
    # field_seg.yaml path: ./yolo_field_data # 数据集根目录 train: train/images # 训练图像路径 val: val/images # 验证图像路径 nc: 1 # 类别数(仅田块一个类别) names: ['field'] # 类别名称

  2. 启动训练:使用 YOLOv8n-seg 轻量化模型(适合嵌入式部署),执行训练命令:
    yolo segment train data=field_seg.yaml model=yolov8n-seg.pt epochs=100 batch=16 imgsz=640 lr0=0.01 device=0参数说明:epochs(训练轮数)、batch(批次大小)可根据 PC 显存调整;device=0 表示使用 GPU 训练(无 GPU 可去掉此参数,用 CPU 训练,速度较慢)。

  3. 训练监控:训练过程中会自动生成 runs/segment/train 目录,包含训练日志、损失曲线、验证指标(mIoU 是分割任务核心指标,越高越好)。若验证集 mIoU 不再提升,可提前停止训练。

  4. 导出训练好的模型:训练完成后,在 runs/segment/train/weights 目录下有 best.pt(最优模型)和 last.pt(最后一轮模型),导出为 ONNX 格式(后续转换 RKNN 需此中间格式):
    yolo export model=runs/segment/train/weights/best.pt format=onnx imgsz=640导出成功后,会生成 best.onnx 文件。

三、模型转换:ONNX → RKNN

RK3588 需加载 RKNN 格式模型才能调用 NPU 加速,需使用 RKNN Toolkit2 完成转换,支持量化(INT8 量化可提升推理速度、降低功耗)。

3.1 编写转换脚本(PC 端执行)

python 复制代码
from rknn.api import RKNN

if __name__ == "__main__":
    # 1. 初始化 RKNN 对象
    rknn = RKNN(verbose=True)
    
    # 2. 配置模型参数(输入图像预处理)
    ONNX_MODEL = "best.onnx"  # 输入 ONNX 模型
    RKNN_MODEL = "best.rknn"  # 输出 RKNN 模型
    DATASET = "dataset.txt"   # 量化数据集路径(包含少量验证集图像路径)
    INPUT_SIZE = [640, 640]   # 输入尺寸
    
    # 3. 加载 ONNX 模型
    print("Loading ONNX model...")
    ret = rknn.load_onnx(model=ONNX_MODEL, input_size_list=[INPUT_SIZE])
    if ret != 0:
        print("Load ONNX model failed!")
        exit(ret)
    
    # 4. 配置量化参数(INT8 量化,提升性能)
    print("Configuring model...")
    ret = rknn.config(mean_values=[[0, 0, 0]],  # 图像归一化均值(YOLOv8 已预处理,设为 0)
                      std_values=[[255, 255, 255]],  # 图像归一化标准差
                      quant_img_RGB2BGR=True,  # YOLOv8 输入为 RGB,RK3588 偏好 BGR,需转换
                      quantize_mode="float16"  # 若需更高速度,可改为 "int8",需准备量化数据集
                      )
    if ret != 0:
        print("Configure model failed!")
        exit(ret)
    
    # 5. 构建 RKNN 模型
    print("Building RKNN model...")
    ret = rknn.build(do_quantization=False)  # 先不量化,验证转换是否成功;成功后再改为 True 量化
    if ret != 0:
        print("Build RKNN model failed!")
        exit(ret)
    
    # 6. 导出 RKNN 模型
    print("Exporting RKNN model...")
    ret = rknn.export_rknn(RKNN_MODEL)
    if ret != 0:
        print("Export RKNN model failed!")
        exit(ret)
    
    # 7. 释放资源
    rknn.release()
    print("Model converted successfully!")

3.2 关键说明

  1. 量化数据集:若使用 INT8 量化,需创建 dataset.txt 文件,每行填写一张验证集图像的绝对路径(如 /home/user/yolo_field_data/val/images/1.jpg),建议至少 50 张图像。

  2. 转换验证:先以 float16 模式转换,成功后再尝试 INT8 量化,避免因量化问题导致转换失败。

  3. 模型传输:将转换好的 best.rknn 文件通过 scp 或 U 盘拷贝到 RK3588 开发板(如 /home/rk3588/field_seg/ 目录)。

四、推理测试:RK3588 板端部署

编写推理脚本,调用 RK3588 NPU 加载 RKNN 模型,对田块图像进行分割测试。

4.1 板端推理脚本

python 复制代码
from rknn.api import RKNN
import cv2
import numpy as np

def preprocess_image(image_path, input_size):
    # 读取图像
    img = cv2.imread(image_path)
    # 调整尺寸
    img_resized = cv2.resize(img, input_size)
    # 归一化(与训练时一致)
    img_normalized = img_resized / 255.0
    # 转换为 NCHW 格式(RKNN 输入要求)
    img_transposed = np.transpose(img_normalized, (2, 0, 1))
    # 扩展维度(添加 batch 维度)
    img_input = np.expand_dims(img_transposed, axis=0).astype(np.float32)
    return img, img_input

def postprocess_output(output, input_size, img_origin, class_names, conf_thres=0.5):
    # YOLOv8 分割输出包含:目标框、置信度、类别、掩码
    # 此处简化处理,提取掩码并可视化
    # 实际项目需根据 YOLOv8 输出格式解析(可参考 ultralytics 官方后处理代码)
    masks = output[0]  # 掩码输出(假设第一个输出为掩码)
    # 调整掩码尺寸为原始图像尺寸
    masks_resized = cv2.resize(masks.squeeze(0).transpose(1,2,0), (img_origin.shape[1], img_origin.shape[0]))
    # 过滤低置信度掩码
    masks_filtered = (masks_resized[..., 0] > conf_thres).astype(np.uint8) * 255
    # 可视化:将田块区域标记为绿色
    img_result = img_origin.copy()
    img_result[masks_filtered == 255] = [0, 255, 0]  # 田块区域设为绿色
    return img_result

if __name__ == "__main__":
    # 1. 初始化 RKNN 对象
    rknn = RKNN()
    
    # 2. 加载 RKNN 模型
    RKNN_MODEL = "best.rknn"
    INPUT_SIZE = (640, 640)
    CLASS_NAMES = ["field"]
    ret = rknn.load_rknn(RKNN_MODEL)
    if ret != 0:
        print("Load RKNN model failed!")
        exit(ret)
    
    # 3. 初始化运行环境
    print("Initializing runtime environment...")
    ret = rknn.init_runtime(target="rk3588", device_id="0")  # target 指定为 rk3588
    if ret != 0:
        print("Init runtime environment failed!")
        exit(ret)
    
    # 4. 读取并预处理图像
    IMAGE_PATH = "test_field.jpg"  # 测试图像路径
    img_origin, img_input = preprocess_image(IMAGE_PATH, INPUT_SIZE)
    
    # 5. 执行推理
    print("Running inference...")
    outputs = rknn.inference(inputs=[img_input])
    
    # 6. 后处理并可视化
    img_result = postprocess_output(outputs, INPUT_SIZE, img_origin, CLASS_NAMES)
    
    # 7. 显示与保存结果
    cv2.imshow("Field Segmentation Result", img_result)
    cv2.waitKey(0)
    cv2.imwrite("result.jpg", img_result)
    print("Inference completed! Result saved as result.jpg")
    
    # 8. 释放资源
    rknn.release()
    cv2.destroyAllWindows()

4.2 测试步骤与结果验证

  1. 准备测试图像:在 RK3588 开发板上放置一张农田测试图像(test_field.jpg)。

  2. 运行推理脚本:
    python3 rknn_inference.py

  3. 结果查看:脚本会显示分割结果(田块区域标记为绿色),并保存为 result.jpg。若分割区域准确、无明显漏检/误检,说明部署成功。

  4. 性能测试:可添加计时代码,统计推理耗时(RK3588 NPU 推理 YOLOv8n-seg 模型,640×640 输入下耗时可低至 20ms 以内,满足实时需求)。

五、总结与优化方向

5.1 全流程总结

本文完成了从 PC 端环境搭建、数据集标注与训练,到 ONNX 模型导出、RKNN 模型转换,再到 RK3588 板端推理的全流程实现。核心优势在于利用 YOLOv8 高效的分割能力与 RK3588 强大的 NPU 算力,实现了低成本、实时性的田块分割系统。

5.2 优化方向

  • 数据集优化:增加更多场景(如雨天、阴天、不同作物类型)的田块图像,提升模型泛化能力。

  • 模型优化:使用 YOLOv8s-seg 模型(精度更高)或通过剪枝、量化进一步提升推理速度。

  • 应用扩展:结合视频流推理,实现实时田块监测;添加田块面积计算、边界提取等功能。

  • 部署优化:将 Python 脚本封装为 C++ 程序,进一步降低 latency,适配嵌入式实时系统。

结语:通过本文的全流程指南,相信你已掌握 RK3588 + YOLOv8 实现田块分割的核心技术。后续可根据实际应用场景持续优化,推动智慧农业相关产品的落地。如果在操作过程中遇到问题,欢迎在评论区交流!

相关推荐
NAGNIP10 小时前
一文搞懂深度学习中的通用逼近定理!
人工智能·算法·面试
冬奇Lab11 小时前
一天一个开源项目(第36篇):EverMemOS - 跨 LLM 与平台的长时记忆 OS,让 Agent 会记忆更会推理
人工智能·开源·资讯
冬奇Lab11 小时前
OpenClaw 源码深度解析(一):Gateway——为什么需要一个"中枢"
人工智能·开源·源码阅读
AngelPP15 小时前
OpenClaw 架构深度解析:如何把 AI 助手搬到你的个人设备上
人工智能
宅小年15 小时前
Claude Code 换成了Kimi K2.5后,我再也回不去了
人工智能·ai编程·claude
九狼15 小时前
Flutter URL Scheme 跨平台跳转
人工智能·flutter·github
ZFSS16 小时前
Kimi Chat Completion API 申请及使用
前端·人工智能
天翼云开发者社区17 小时前
春节复工福利就位!天翼云息壤2500万Tokens免费送,全品类大模型一键畅玩!
人工智能·算力服务·息壤
知识浅谈17 小时前
教你如何用 Gemini 将课本图片一键转为精美 PPT
人工智能
Ray Liang17 小时前
被低估的量化版模型,小身材也能干大事
人工智能·ai·ai助手·mindx