发布时间:2026/7/14 3:45:15
基于YOLOv8的杂草识别系统:从环境配置到UI开发完整指南 在农业智能化快速发展的今天杂草识别一直是精准农业中的关键挑战。传统人工除草效率低下且成本高昂而基于深度学习的杂草识别系统能够显著提升农业生产的自动化水平。本文将详细介绍如何基于YOLOv8构建一个完整的杂草识别检测系统涵盖从环境配置、数据集准备、模型训练到UI界面开发的完整流程。无论你是刚接触深度学习的新手还是有经验的开发者希望将YOLOv8应用于农业场景本文都将提供实用的代码示例和详细的实现步骤。我们将使用Python作为开发语言结合PySide6构建用户友好的图形界面最终实现一个支持图像、视频和实时摄像头输入的杂草识别系统。1. 杂草识别背景与核心概念1.1 杂草识别的农业意义杂草识别在精准农业中具有重要的应用价值。传统农业生产中农民通常采用大面积均匀喷洒除草剂的方式这不仅造成了农药的浪费还可能对环境造成污染。通过基于深度学习的杂草识别系统可以实现对杂草的精准定位和识别为精准施药提供技术支持从而降低农业生产成本提高作业效率。1.2 YOLOv8在杂草识别中的优势YOLOv8作为YOLO系列的最新版本在目标检测任务中表现出色。相比前代版本YOLOv8在精度和速度之间取得了更好的平衡特别适合农业场景中的实时检测需求。其Anchor-free的设计简化了模型结构DFL损失函数有效处理了类别不平衡问题这些特性使得YOLOv8在杂草识别任务中具有明显优势。1.3 系统整体架构本系统采用模块化设计主要包含以下几个核心模块数据预处理模块负责图像增强、标注格式转换等模型训练模块基于YOLOv8进行模型训练和优化推理检测模块实现图像、视频和实时摄像头的杂草检测用户界面模块提供友好的交互界面和结果可视化2. 环境配置与依赖安装2.1 基础环境要求在开始项目之前需要确保系统满足以下基础要求操作系统Windows 10/11、Ubuntu 18.04 或 macOS 10.15Python版本3.8-3.10CUDA支持建议使用支持CUDA的GPU以获得更好的训练和推理性能2.2 创建虚拟环境首先创建一个独立的Python虚拟环境避免包版本冲突conda create -n weed_detection python3.9 conda activate weed_detection2.3 安装核心依赖包安装项目所需的主要依赖包# 安装PyTorch根据CUDA版本选择 pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 # 安装YOLOv8相关包 pip install ultralytics # 安装图形界面相关包 pip install PySide6 opencv-python # 安装其他工具包 pip install numpy pandas matplotlib seaborn pip install scikit-learn pillow2.4 验证安装创建一个简单的验证脚本来检查环境配置是否正确# check_environment.py import torch import cv2 from PySide6 import QtWidgets from ultralytics import YOLO print(fPyTorch版本: {torch.__version__}) print(fCUDA是否可用: {torch.cuda.is_available()}) print(fOpenCV版本: {cv2.__version__}) # 测试YOLOv8模型加载 try: model YOLO(yolov8n.pt) print(环境配置成功) except Exception as e: print(f环境配置失败: {e})3. 数据集准备与预处理3.1 数据集结构设计一个标准的YOLOv8数据集应该包含以下目录结构weed_dataset/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ └── labels/ ├── train/ ├── val/ └── test/3.2 数据标注格式YOLOv8使用特定的标注格式每个标注文件对应一个图像文件包含以下内容class_id x_center y_center width height其中坐标值都是相对于图像宽度和高度的归一化值0-1之间。3.3 数据增强策略为了提高模型的泛化能力我们需要实施有效的数据增强策略# data_augmentation.py import albumentations as A from albumentations.pytorch import ToTensorV2 def get_train_transforms(image_size640): return A.Compose([ A.HorizontalFlip(p0.5), A.RandomBrightnessContrast(p0.2), A.HueSaturationValue(p0.2), A.RandomGamma(p0.2), A.Blur(p0.1), A.MotionBlur(p0.1), A.RandomResizedCrop(heightimage_size, widthimage_size, scale(0.8, 1.0)), A.Normalize(mean[0, 0, 0], std[1, 1, 1]), ToTensorV2(), ]) def get_val_transforms(image_size640): return A.Compose([ A.Resize(heightimage_size, widthimage_size), A.Normalize(mean[0, 0, 0], std[1, 1, 1]), ToTensorV2(), ])3.4 数据集配置文件创建YAML格式的数据集配置文件# weed_dataset.yaml path: /path/to/weed_dataset train: images/train val: images/val test: images/test nc: 3 # 类别数量 names: [broadleaf, grassweed, soil] # 类别名称 # 下载脚本可选 download: | # 数据集下载指令 # 这里可以添加自动下载数据集的代码4. YOLOv8模型原理与训练4.1 YOLOv8网络架构详解YOLOv8采用了创新的架构设计主要包含三个部分Backbone基于CSPDarknet53的改进版本通过CSPNet设计减少计算量同时保持性能。Neck使用PAN-FPN结构进行多尺度特征融合SPPF模块增强不同尺度特征的聚合能力。Head采用Anchor-free设计简化模型结构使用DFL损失函数处理类别不平衡。4.2 模型训练代码实现下面是完整的模型训练代码# train_weed_detection.py import os import yaml from ultralytics import YOLO import argparse def train_model(config_path, model_sizen, epochs100, imgsz640): 训练杂草检测模型 Args: config_path: 数据集配置文件路径 model_size: 模型大小 (n, s, m, l, x) epochs: 训练轮数 imgsz: 输入图像大小 # 加载模型 model YOLO(fyolov8{model_size}.pt) # 训练参数配置 train_args { data: config_path, epochs: epochs, imgsz: imgsz, batch: 16, workers: 4, patience: 10, save: True, exist_ok: True, pretrained: True, optimizer: auto, lr0: 0.01, lrf: 0.01, momentum: 0.937, weight_decay: 0.0005, warmup_epochs: 3.0, warmup_momentum: 0.8, warmup_bias_lr: 0.1, box: 7.5, cls: 0.5, dfl: 1.5, fl_gamma: 0.0, } # 开始训练 results model.train(**train_args) return results if __name__ __main__: parser argparse.ArgumentParser() parser.add_argument(--config, typestr, requiredTrue, help数据集配置文件路径) parser.add_argument(--model-size, typestr, defaultn, choices[n, s, m, l, x]) parser.add_argument(--epochs, typeint, default100) parser.add_argument(--imgsz, typeint, default640) args parser.parse_args() # 训练模型 results train_model(args.config, args.model_size, args.epochs, args.imgsz) print(训练完成)4.3 训练过程监控训练过程中需要监控的关键指标包括损失函数变化box_loss, cls_loss, dfl_loss精度指标precision, recall, mAP0.5, mAP0.5:0.95学习率变化模型性能验证# monitor_training.py import matplotlib.pyplot as plt import pandas as pd def plot_training_results(results_csv_path): 绘制训练结果图表 # 读取训练结果 results_df pd.read_csv(results_csv_path) fig, axes plt.subplots(2, 2, figsize(15, 10)) # 绘制损失函数 axes[0, 0].plot(results_df[epoch], results_df[train/box_loss], labelBox Loss) axes[0, 0].plot(results_df[epoch], results_df[train/cls_loss], labelCls Loss) axes[0, 0].plot(results_df[epoch], results_df[train/dfl_loss], labelDFL Loss) axes[0, 0].set_title(Training Loss) axes[0, 0].legend() # 绘制验证损失 axes[0, 1].plot(results_df[epoch], results_df[val/box_loss], labelVal Box Loss) axes[0, 1].plot(results_df[epoch], results_df[val/cls_loss], labelVal Cls Loss) axes[0, 1].plot(results_df[epoch], results_df[val/dfl_loss], labelVal DFL Loss) axes[0, 1].set_title(Validation Loss) axes[0, 1].legend() # 绘制精度指标 axes[1, 0].plot(results_df[epoch], results_df[metrics/precision(B)], labelPrecision) axes[1, 0].plot(results_df[epoch], results_df[metrics/recall(B)], labelRecall) axes[1, 0].set_title(Precision Recall) axes[1, 0].legend() # 绘制mAP指标 axes[1, 1].plot(results_df[epoch], results_df[metrics/mAP50(B)], labelmAP0.5) axes[1, 1].plot(results_df[epoch], results_df[metrics/mAP50-95(B)], labelmAP0.5:0.95) axes[1, 1].set_title(mAP Metrics) axes[1, 1].legend() plt.tight_layout() plt.savefig(training_results.png, dpi300, bbox_inchestight) plt.show()5. 系统界面开发与集成5.1 主界面设计使用PySide6开发系统的主界面# main_window.py import sys import os from PySide6.QtWidgets import (QApplication, QMainWindow, QVBoxLayout, QHBoxLayout, QWidget, QPushButton, QLabel, QComboBox, QSlider, QGroupBox, QFileDialog, QMessageBox, QTabWidget, QTextEdit) from PySide6.QtCore import Qt, QTimer, QThread, Signal from PySide6.QtGui import QPixmap, QImage import cv2 import numpy as np from ultralytics import YOLO class DetectionThread(QThread): 检测线程 frame_processed Signal(np.ndarray) def __init__(self, model_path, source0): super().__init__() self.model_path model_path self.source source self.running False self.confidence 0.5 self.iou_threshold 0.45 def run(self): 运行检测线程 self.running True # 加载模型 try: self.model YOLO(self.model_path) except Exception as e: print(f模型加载失败: {e}) return # 打开视频源 if isinstance(self.source, str) and os.path.isfile(self.source): cap cv2.VideoCapture(self.source) else: cap cv2.VideoCapture(self.source) if not cap.isOpened(): print(无法打开视频源) return while self.running: ret, frame cap.read() if not ret: break # 进行检测 results self.model(frame, confself.confidence, iouself.iou_threshold) # 绘制检测结果 annotated_frame results[0].plot() # 发送处理后的帧 self.frame_processed.emit(annotated_frame) cap.release() def stop(self): 停止检测线程 self.running False self.wait() class WeedDetectionApp(QMainWindow): 杂草检测应用主窗口 def __init__(self): super().__init__() self.model None self.detection_thread None self.current_source 0 # 默认摄像头 self.init_ui() self.load_default_model() def init_ui(self): 初始化用户界面 self.setWindowTitle(杂草识别检测系统) self.setGeometry(100, 100, 1200, 800) # 创建中心部件 central_widget QWidget() self.setCentralWidget(central_widget) # 主布局 main_layout QHBoxLayout() central_widget.setLayout(main_layout) # 左侧控制面板 control_panel self.create_control_panel() main_layout.addWidget(control_panel, 1) # 右侧显示区域 display_panel self.create_display_panel() main_layout.addWidget(display_panel, 3) def create_control_panel(self): 创建控制面板 control_group QGroupBox(控制面板) layout QVBoxLayout() # 模型选择 model_layout QHBoxLayout() model_layout.addWidget(QLabel(模型选择:)) self.model_combo QComboBox() self.model_combo.addItems([yolov8n, yolov8s, yolov8m, yolov8l, yolov8x]) model_layout.addWidget(self.model_combo) layout.addLayout(model_layout) # 置信度阈值 conf_layout QVBoxLayout() conf_layout.addWidget(QLabel(置信度阈值:)) self.conf_slider QSlider(Qt.Horizontal) self.conf_slider.setRange(10, 90) self.conf_slider.setValue(50) conf_layout.addWidget(self.conf_slider) layout.addLayout(conf_layout) # 控制按钮 self.camera_btn QPushButton(开启摄像头) self.image_btn QPushButton(选择图片) self.video_btn QPushButton(选择视频) self.stop_btn QPushButton(停止检测) self.camera_btn.clicked.connect(self.start_camera) self.image_btn.clicked.connect(self.select_image) self.video_btn.clicked.connect(self.select_video) self.stop_btn.clicked.connect(self.stop_detection) layout.addWidget(self.camera_btn) layout.addWidget(self.image_btn) layout.addWidget(self.video_btn) layout.addWidget(self.stop_btn) # 统计信息 stats_group QGroupBox(检测统计) stats_layout QVBoxLayout() self.stats_text QTextEdit() self.stats_text.setMaximumHeight(150) stats_layout.addWidget(self.stats_text) stats_group.setLayout(stats_layout) layout.addWidget(stats_group) control_group.setLayout(layout) return control_group def create_display_panel(self): 创建显示面板 display_group QGroupBox(检测结果显示) layout QVBoxLayout() # 图像显示标签 self.image_label QLabel() self.image_label.setAlignment(Qt.AlignCenter) self.image_label.setMinimumSize(640, 480) self.image_label.setText(等待检测...) self.image_label.setStyleSheet(border: 1px solid gray;) layout.addWidget(self.image_label) display_group.setLayout(layout) return display_group def load_default_model(self): 加载默认模型 try: self.model YOLO(yolov8n.pt) QMessageBox.information(self, 成功, 默认模型加载成功) except Exception as e: QMessageBox.critical(self, 错误, f模型加载失败: {e}) def start_camera(self): 开启摄像头检测 self.current_source 0 self.start_detection() def select_image(self): 选择图片进行检测 file_path, _ QFileDialog.getOpenFileName( self, 选择图片, , 图片文件 (*.jpg *.jpeg *.png *.bmp) ) if file_path: self.current_source file_path self.detect_image(file_path) def select_video(self): 选择视频进行检测 file_path, _ QFileDialog.getOpenFileName( self, 选择视频, , 视频文件 (*.mp4 *.avi *.mov) ) if file_path: self.current_source file_path self.start_detection() def start_detection(self): 开始检测 if self.detection_thread and self.detection_thread.isRunning(): self.detection_thread.stop() self.detection_thread DetectionThread(yolov8n.pt, self.current_source) self.detection_thread.frame_processed.connect(self.update_frame) self.detection_thread.start() def stop_detection(self): 停止检测 if self.detection_thread and self.detection_thread.isRunning(): self.detection_thread.stop() self.image_label.setText(检测已停止) def detect_image(self, image_path): 检测单张图片 if not self.model: QMessageBox.warning(self, 警告, 请先加载模型) return try: # 读取并检测图片 image cv2.imread(image_path) results self.model(image) # 绘制结果 annotated_image results[0].plot() # 显示结果 self.display_image(annotated_image) except Exception as e: QMessageBox.critical(self, 错误, f图片检测失败: {e}) def update_frame(self, frame): 更新视频帧 self.display_image(frame) def display_image(self, image): 显示图像 # 转换颜色空间 image_rgb cv2.cvtColor(image, cv2.COLOR_BGR2RGB) # 调整图像大小 h, w, ch image_rgb.shape bytes_per_line ch * w # 创建QImage并显示 qt_image QImage(image_rgb.data, w, h, bytes_per_line, QImage.Format_RGB888) pixmap QPixmap.fromImage(qt_image) # 缩放图像以适应标签 scaled_pixmap pixmap.scaled(self.image_label.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation) self.image_label.setPixmap(scaled_pixmap) def main(): app QApplication(sys.argv) window WeedDetectionApp() window.show() sys.exit(app.exec()) if __name__ __main__: main()5.2 实时检测功能实现实现实时摄像头检测功能# realtime_detection.py import cv2 import numpy as np from ultralytics import YOLO import time class RealTimeWeedDetector: 实时杂草检测器 def __init__(self, model_path, camera_index0): self.model_path model_path self.camera_index camera_index self.model None self.cap None self.is_running False self.load_model() self.setup_camera() def load_model(self): 加载YOLOv8模型 try: self.model YOLO(self.model_path) print(f模型加载成功: {self.model_path}) except Exception as e: print(f模型加载失败: {e}) def setup_camera(self): 设置摄像头 self.cap cv2.VideoCapture(self.camera_index) if not self.cap.isOpened(): print(无法打开摄像头) return False return True def start_detection(self): 开始检测 self.is_running True while self.is_running: ret, frame self.cap.read() if not ret: print(无法读取视频帧) break # 进行检测 start_time time.time() results self.model(frame, conf0.5, iou0.45) inference_time time.time() - start_time # 绘制检测结果 annotated_frame results[0].plot() # 显示FPS fps 1.0 / inference_time cv2.putText(annotated_frame, fFPS: {fps:.2f}, (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2) # 显示结果 cv2.imshow(Weed Detection, annotated_frame) # 按q退出 if cv2.waitKey(1) 0xFF ord(q): break self.cleanup() def cleanup(self): 清理资源 self.is_running False if self.cap: self.cap.release() cv2.destroyAllWindows() # 使用示例 if __name__ __main__: detector RealTimeWeedDetector(best.pt) # 使用训练好的模型 detector.start_detection()6. 模型优化与性能提升6.1 模型量化与加速为了提高推理速度我们可以对模型进行量化# model_optimization.py import torch from ultralytics import YOLO def optimize_model(model_path, output_path): 优化模型以提高推理速度 Args: model_path: 原始模型路径 output_path: 优化后模型保存路径 # 加载模型 model YOLO(model_path) # 导出为ONNX格式支持GPU推理 model.export(formatonnx, imgsz640, halfTrue, simplifyTrue) # 量化模型PTQ quantized_model torch.quantization.quantize_dynamic( model.model, # 原始模型 {torch.nn.Linear}, # 量化层类型 dtypetorch.qint8 ) # 保存量化模型 torch.save(quantized_model.state_dict(), output_path) print(f优化后的模型已保存到: {output_path}) # 使用TensorRT进一步加速可选 def export_to_tensorrt(model_path): 导出为TensorRT引擎 model YOLO(model_path) model.export(formatengine, imgsz640, halfTrue)6.2 多尺度检测优化针对不同大小的杂草目标实现多尺度检测# multi_scale_detection.py import cv2 import numpy as np from ultralytics import YOLO class MultiScaleWeedDetector: 多尺度杂草检测器 def __init__(self, model_path, scales[0.5, 1.0, 1.5]): self.model_path model_path self.scales scales self.model YOLO(model_path) def detect_multi_scale(self, image, conf_threshold0.3): 多尺度检测 all_detections [] original_h, original_w image.shape[:2] for scale in self.scales: # 调整图像尺寸 new_w int(original_w * scale) new_h int(original_h * scale) resized_image cv2.resize(image, (new_w, new_h)) # 进行检测 results self.model(resized_image, confconf_threshold) # 转换检测框坐标到原始图像尺寸 for result in results: boxes result.boxes for box in boxes: # 获取检测框信息 x1, y1, x2, y2 box.xyxy[0].cpu().numpy() conf box.conf[0].cpu().numpy() cls int(box.cls[0].cpu().numpy()) # 缩放回原始尺寸 x1 int(x1 / scale) y1 int(y1 / scale) x2 int(x2 / scale) y2 int(y2 / scale) detection { bbox: [x1, y1, x2, y2], confidence: conf, class: cls, scale: scale } all_detections.append(detection) return all_detections def non_max_suppression(self, detections, iou_threshold0.5): 非极大值抑制 if len(detections) 0: return [] # 按置信度排序 detections.sort(keylambda x: x[confidence], reverseTrue) keep [] while len(detections) 0: # 取置信度最高的检测结果 best detections.pop(0) keep.append(best) # 计算与剩余检测框的IoU to_remove [] for i, det in enumerate(detections): iou self.calculate_iou(best[bbox], det[bbox]) if iou iou_threshold: to_remove.append(i) # 移除重叠的检测框 for i in sorted(to_remove, reverseTrue): detections.pop(i) return keep def calculate_iou(self, box1, box2): 计算IoU x11, y1

相关新闻

2026/7/14 3:45:15

浪潮服务器RAID配置与系统安装:从BMC到BIOS的实战避坑指南

1. 浪潮服务器RAID配置前的准备工作第一次接触浪潮服务器的RAID配置时,我被各种专业术语和复杂的操作界面搞得晕头转向。后来才发现,只要做好准备工作,整个过程其实并不复杂。首先需要确认服务器的硬件配置,特别是RAID卡型号和硬盘…

2026/7/14 3:40:14

大语言模型中Dropout技术原理与优化实践

1. Dropout在LLM中的核心作用解析Dropout这项技术最早由Hinton团队在2012年提出,原本是为了解决传统神经网络中的过拟合问题。在大语言模型时代,它的作用发生了有趣的演变。以GPT-3为例,在1750亿参数的庞大架构中,Dropout率通常设…

2026/7/14 3:40:14

Linux内核开发与开源协作:从Linus TED演讲看操作系统工程实践

今天我们来聊聊Linux操作系统创始人Linus Torvalds在TED上的经典演讲。这段演讲不仅是技术分享,更是开源理念的生动诠释,对于理解Linux成功背后的哲学思想至关重要。Linus Torvalds作为Linux内核和Git版本控制系统的创造者,在TED演讲中坦诚分…

2026/7/14 6:20:22

LLM注意力可视化在医疗诊断中的实践与应用

1. 项目背景与核心价值医疗诊断领域正面临一个关键矛盾:AI模型的诊断准确率不断提升,但医生群体对"黑箱算法"的信任度始终难以建立。去年某三甲医院的调研显示,78%的临床医生表示"无法理解AI的诊断依据"会直接影响其采用…

2026/7/14 6:20:22

移动端水体渲染实战:Easy Water v2.96性能优化与配置详解

1. 项目概述:为什么是Easy Water v2.96?在移动游戏开发中,水面效果一直是个让人又爱又恨的“钉子户”。爱的是,一汪清澈或汹涌的水体,能瞬间提升场景的氛围感和沉浸度;恨的是,移动设备的性能天花…

2026/7/14 6:20:22

VLM 发展脉络

Vision-Language Model(VLM)的发展逻辑可以概括为: 图文对齐 → 多模态预训练 → 连接LLM → 指令微调 → 大规模统一多模态模型 传统CV│▼ ──────────────────────────────────── ① 图文表示学习&…

2026/7/14 6:15:22

TVA具身智能的概念、架构与应用(15)

前沿技术探索:AI智能体视觉(TVA,Transformer-based Vision Agent)是依托Transformer架构与“因式智能体”理论所构建的颠覆性工业视觉技术,是集深度强化学习(DRL)、卷积神经网络(CNN…

2026/7/13 6:38:38

3步解锁音乐自由:ncmdumpGUI终极NCM文件解密转换指南

3步解锁音乐自由:ncmdumpGUI终极NCM文件解密转换指南 【免费下载链接】ncmdumpGUI C#版本网易云音乐ncm文件格式转换,Windows图形界面版本 项目地址: https://gitcode.com/gh_mirrors/nc/ncmdumpGUI 你是否曾在网易云音乐下载了心爱的歌曲&#…

2026/7/13 14:26:14

CANoe 19 SP3 配置 GB/T 27930-2023 A类系统:3步搭建BMS仿真测试环境

CANoe 19 SP3 配置 GB/T 27930-2023 A类系统:3步搭建BMS仿真测试环境随着新能源汽车行业的快速发展,充电通信协议的标准化和测试验证变得尤为重要。GB/T 27930-2023作为中国智能充电协议的最新版本,对充电机与电动汽车之间的通信提出了更严格…

2026/7/13 18:07:53

3步搞定RTL8852BE驱动:从零开始配置Wi-Fi 6网卡

3步搞定RTL8852BE驱动:从零开始配置Wi-Fi 6网卡 【免费下载链接】rtl8852be Realtek Linux WLAN Driver for RTL8852BE 项目地址: https://gitcode.com/gh_mirrors/rt/rtl8852be 还在为Linux系统无法识别RTL8852BE Wi-Fi 6网卡而烦恼吗?&#x1f…

2026/7/14 0:04:21

5分钟掌握足球PBR材质制作:Photoshop与Unity高效工作流

1. 项目概述:为什么是足球PBR材质?在游戏开发,尤其是体育竞技类游戏的制作中,一个看起来“对味”的足球,往往比我们想象中更重要。它不仅是赛场上的核心道具,更是玩家视觉焦点和沉浸感的重要来源。一个塑料…

2026/7/14 0:04:21

ChatGPT联网搜索失败,92%开发者误判为网络问题——真实根因竟是LLM推理会话上下文污染导致Search Agent进程静默退出(含strace复现脚本)

更多请点击: https://intelliparadigm.com 第一章:ChatGPT 联网搜索失败 当 ChatGPT 的联网搜索功能无法正常工作时,用户常遇到“搜索不可用”“未连接到互联网”或空白响应等现象。该问题并非模型本身缺陷,而是由权限配置、网络…

2026/7/13 11:33:05

3个高效策略:快速掌握Axure中文界面配置

3个高效策略:快速掌握Axure中文界面配置 【免费下载链接】axure-cn Chinese language file for Axure RP. Axure RP 简体中文语言包。支持 Axure 11、10、9。不定期更新。 项目地址: https://gitcode.com/gh_mirrors/ax/axure-cn 还在为Axure RP的英文界面感…