news 2026/10/5 12:37:59

YOLOv8钢材缺陷检测:从NEU-DET数据集到Qt界面部署全流程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
YOLOv8钢材缺陷检测:从NEU-DET数据集到Qt界面部署全流程

简介:YOLOv8钢材缺陷检测资源包整合了训练好的模型权重、LabelImg标注的数据集和可交互的PyQt界面程序,面向工业质检、计算机视觉学习者及需要快速落地缺陷检测的开发者,解决从数据标注、模型推理到界面演示的关键环节。压缩包共2000个文件、约94.62MB,核心内容包括1403个txt标签、346张jpg样本图、171个Python脚本,以及yaml配置、pt权重、ui界面等,目录按功能划分,便于直接查阅与二次开发。模型已训练完成并附带PR曲线、loss曲线等训练过程分析,能够直接用于钢材缺陷分类与定位;界面端支持图片检测、视频检测和摄像头实时检测,大幅降低使用门槛。资源目前已有605人学习下载,适合需要完整方案参考、希望快速复现训练与部署流程的读者。

1. YOLOv8钢材缺陷检测:一篇文章把数据集、权重到Qt界面的活全干完

车间里高速钢带一卷接一卷地过,质检员的眼睛盯在屏幕上,一盯就是几个小时——这就是YOLOv8钢材缺陷检测要接手的活。把轧制氧化皮、裂纹、夹杂、麻点、划痕、斑块这六类缺陷从画面里框出来,背后依赖三样东西:一个干净的数据集、一份训练好的缺陷检测权重、一个能让人点开就用的Qt界面GUI。这一篇按“数据集转换→训练权重→Qt界面→部署验证”的顺序拆开讲,每步都给能直接抄的命令和代码,也把损失不降、界面卡死、转RKNN精度掉这些坑提前标出来。适合正在搭桌面检测工具的一线工程师,也适合刚拿到真实数据集想跑通全流程的入门者。

2. 用NEU-DET搭建钢材缺陷数据集:VOC转YOLO格式脚本与6类缺陷说明

2.1 为什么选NEU-DET:1800张图、六类缺陷、公开可复现

做钢材表面缺陷检测,数据集绕不开NEU-DET。这是东北大学公开的热轧带钢表面缺陷数据集,共1800张灰度图,每张200×200像素,覆盖六类缺陷:crazing(网状裂纹)、inclusion(夹杂)、patches(斑块)、pitted_surface(麻点/凹坑)、rolled-in_scale(轧制氧化皮)、scratches(划痕)。六类各300张,看起来均衡,实际训练时感受完全不同——裂纹和斑块的纹理都偏碎,划痕和氧化皮都带细长条,模型很容易把相似类混在一起。

NEU-DET的标注是VOC格式的XML,每个XML对应一张PNG,里面用bndbox记录目标框。YOLOv8训练要求的标注是txt文本,每行一个目标,格式为“类别id 中心x 中心y 宽 高”,坐标都归一化到0~1。所以项目落地第一步不是训练,而是把XML批量转成YOLO格式,并保证类别顺序和后续data.yaml里的names完全一致。这个顺序一旦乱了,训练出来的权重就等于废的。

2.2 VOC标注转YOLO txt:转换脚本与参数说明

转换脚本我一般这样写:用ElementTree解析XML,图像宽高直接用cv2读取,不依赖XML里可能缺失的size节点。这样做更稳,因为有些版本的NEU-DET标注文件里size字段不完整,而图像本身一定在。

import os import cv2 import xml.etree.ElementTree as ET # 类别顺序必须和之后的 data.yaml 保持一致,不能随意调整 CLASSES = ['crazing', 'inclusion', 'patches', 'pitted_surface', 'rolled-in_scale', 'scratches'] def voc_to_yolo(xml_path, img_dir, label_dir): tree = ET.parse(xml_path) root = tree.getroot() img_name = root.find('filename').text img_path = os.path.join(img_dir, img_name) # 直接读图拿宽高,比信任 XML 里的 size 更可靠 img = cv2.imread(img_path) if img is None: print(f"图片读取失败: {img_path}") return h, w = img.shape[:2] lines = [] for obj in root.findall('object'): name = obj.find('name').text if name not in CLASSES: print(f"跳过未知类别: {name} in {img_name}") continue box = obj.find('bndbox') x1 = int(box.find('xmin').text) y1 = int(box.find('ymin').text) x2 = int(box.find('xmax').text) y2 = int(box.find('ymax').text) # 归一化到 0~1:中心点和宽高都除以图像宽高 cx = (x1 + x2) / 2.0 / w cy = (y1 + y2) / 2.0 / h bw = (x2 - x1) / float(w) bh = (y2 - y1) / float(h) lines.append(f"{CLASSES.index(name)} {cx:.6f} {cy:.6f} {bw:.6f} {bh:.6f}") txt_name = img_name.replace('.png', '.txt') with open(os.path.join(label_dir, txt_name), 'w') as f: f.write('\n'.join(lines)) # 批量处理 Images 和 Annotations 两个目录 xml_dir = 'NEU-DET/ANNOTATIONS' img_dir = 'NEU-DET/IMAGES' label_dir = 'NEU-DET/labels' os.makedirs(label_dir, exist_ok=True) for xml_file in os.listdir(xml_dir): if xml_file.endswith('.xml'): voc_to_yolo(os.path.join(xml_dir, xml_file), img_dir, label_dir)

这段代码有几个参数要留意。CLASSES的顺序是整个项目的基准,后面data.yaml里的names必须一字不差地照抄;坐标转换用的是图像真实宽高,而不是XML里的size字段,避免读到脏数据;宽高比直接用float转,避免整数除法把框算成0。跑完检查一下labels目录,随便打开一个txt,第一列应该是0~5的整数,后面四列都是0到1之间的小数。如果出现大于1的值,十有八九是XML里bndbox的坐标单位不统一,比如有的图标注直接用了绝对值像素。

2.3 数据集划分与增强:train/val怎么切才不翻车

NEU-DET只有1800张,划分比例建议8:1:1,切完训练集1440张、验证集180张、测试集180张。注意一个坑:不能直接对整个文件夹随机切,因为六类缺陷分布虽然各300张,但每张图里可能有多个类别、多个目标,全局随机可能导致某个类别在验证集里只剩十几张,导致评估结果波动大。

我一般先按图片名排序,再固定随机种子,确保每次跑出来的划分一致。更保险的做法是统计每张图包含的类别,按类别做分层抽样,保证验证集和测试集里六类都齐。划分之后,把训练集和验证集的图片路径分别写进train.txt和val.txt,供YOLOv8的data.yaml引用,或者直接把图片按目录放好,data.yaml里写目录路径即可。

数据增强方面,NEU-DET原图只有200×200,直接resize到640会损失细裂纹这类小目标的细节。常见做法是开启mosaic增强,让模型在拼接图里学习小目标上下文;同时把mosaic的缩放范围调小一点,避免缺陷被缩到几个像素。增强是给模型“加难度”防止过拟合,但难度加过头,小目标直接消失,训练反而更难收敛。这个度要在前面20个epoch里观察loss曲线再决定,别一上来把增强拉满。

3. 训练YOLOv8缺陷检测权重:环境、命令与三个必调参数

3.1 环境准备:GTX1660Ti也能跑的最小配置

训练YOLOv8缺陷检测权重,环境配置不算复杂。Python 3.8以上,装PyTorch,再装ultralytics库,一条pip命令搞定。显卡是GTX1660Ti这种6G显存的卡完全能跑,只是模型尺寸要选对:yolov8n权重约6M参数,yolov8s约11M,6G显存跑yolov8s在640输入下batch调到8是可以的,batch调16就会OOM。如果手上只有CPU,也能跑,但一个epoch要等很久,建议直接用yolov8n加降低输入尺寸。

权重选择上,我建议从COCO预训练权重开始,也就是yolov8n.pt。虽然COCO里没有钢材缺陷类别,但模型已经学好了边缘、纹理、形状这些底层特征,迁移到缺陷检测上收敛速度明显更快。彻底从零训练不是不行,但NEU-DET只有一千多张图,从零训很容易过拟合,效果还不见得好。预训练权重相当于给模型一个“已经会看图的底子”,这也是缺陷检测这类小数据集项目最常见的做法。

3.2 写data.yaml并跑通第一次训练:命令与参数

数据准备好之后,先写data.yaml。这个文件告诉ultralytics去哪里找图、类别叫什么。路径建议写绝对路径,因为CLI命令在不同目录下执行时相对路径容易找错。

# data.yaml path: D:/steel_defect/NEU-DET # 数据集根目录 train: images/train # 训练集相对路径 val: images/val # 验证集相对路径 nc: 6 # 类别数必须是6 names: 0: crazing 1: inclusion 2: patches 3: pitted_surface 4: rolled-in_scale 5: scratches

第一次训练,命令可以这样写:

yolo detect train \ data=data.yaml \ model=yolov8n.pt \ epochs=150 \ imgsz=640 \ batch=8 \ device=0 \ amp=True

几个参数值得说明。imgsz=640是训练输入尺寸,NEU-DET原图200×200,模型会把图拉大到640再训练,小目标细节会被插值放大,但不会丢失太多;如果显存紧张,降到512也能跑。batch=8是6G显存下的稳妥值,闭眼调到16大概率OOM。amp=True开启混合精度训练,显存占用大约能降三分之一,训练速度也更快,1660Ti这种卡必须开。epochs先设150,配合patience=20早停,如果验证集mAP连续20轮不涨会自动停,不会被无效训练耗时间。

训练中断了也不用从头来。继续训练的命令是:

yolo detect train resume=True model=runs/detect/train/weights/last.pt

last.pt是每个epoch结束都会存的检查点,resume会从最近一次保存的位置继续,训练进度、优化器状态都会恢复。我习惯每50个epoch手动看一眼loss曲线,确认方向没跑偏再让它接着跑。

3.3 从损失曲线判断训练状态:损失不降时先查这四项

训练完成后,runs/detect/train目录下会有results.png、results.csv和weights文件夹。results.png里画了box_loss、cls_loss、mAP50等曲线。判断训练状态主要看两条:训练集box_loss是不是稳步下降;验证集mAP50是不是在往上走。如果loss降了但mAP不涨,说明过拟合了;如果两个都不动,先查标注。

我想强调的是“先查标注,再调参数”。损失不降时,我按这个顺序排查:第一,随机抽三张训练图的txt和原图叠加可视化,看框是否贴目标、类别id是否正确;第二,确认data.yaml里的names顺序和转换脚本里的CLASSES顺序一致,这个错了模型白训;第三,看学习率,lr0=0.01是从COCO预训练权重继续训的常用值,如果是从零开始训练,建议降到0.001;第四,把mosaic关掉跑10个epoch做基准测试,如果关掉后loss明显下降,说明增强强度太大,模型学不过来了。

看损失曲线的具体数值时,不用纠结loss绝对值降到多小,不同数据集、不同增强配置下loss的量级差别很大。我更关注的是曲线的形态:平稳下降、没有突然跳变、验证loss和训练loss之间的差距没有越拉越大。这里不是玄学,而是“loss降了但mAP不动”和“loss都不降”是两类完全不同的排错路径,先分清楚是哪一类,再动手改。

4. 用Qt做缺陷检测界面:PyQt5布局、QThread推理与相机接入

4.1 界面怎么做:显示区、控制面板与结果表格

训练出best.pt之后,下一步就是把它装进一个能给人用的界面里。这里的“qt界面gui”,常见方案是用PyQt5或PySide6写桌面程序,因为Python生态和ultralytics配合最顺,不用跨语言调接口。界面布局我一般分为三块:左侧是图像/视频显示区,用QLabel控件显示检测结果帧;右侧是控制面板,放权重选择下拉框、置信度阈值和IOU阈值调节旋钮、图片/视频/相机切换按钮,以及一个检测结果表格;底部是状态栏,实时显示当前FPS和处理耗时。

布局的要点是显示区要能自适应缩放。QLabel显示QPixmap时,用scaled(self.label.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation)保持宽高比,避免图像被拉伸变形。控制面板里的置信度阈值默认设0.25,IOU阈值默认0.45,这两个值和训练时模型默认的NMS参数保持一致,界面里调了阈值能立刻看到检测结果变化,这是调参最快的方式。

结果表格可以用QTableWidget,每行显示一个检测框的类别、置信度、坐标。表格没必要实时刷新太频繁,视频流检测时,每帧都刷新表格会让界面闪烁,我一般只更新最后10条结果,或者只在单张图片检测时刷新表格。

4.2 把推理塞进QThread:主线程不卡的写法

这是整个Qt界面项目里最容易翻车的地方。如果直接把model.predict()写在按钮的槽函数里,点一下检测,界面立刻转圈卡死,窗口拖不动,严重时系统直接提示“未响应”。原因很简单:推理是耗时操作,放在GUI主线程里会阻塞Qt的事件循环,界面刷新、鼠标响应全部停摆。解决方法是把推理放进QThread子线程,通过信号把结果传回主线程更新界面。

import cv2 from PyQt5.QtCore import QThread, pyqtSignal from ultralytics import YOLO class DetectWorker(QThread): # 用 object 类型传递图像和检测结果,避免 PyQt 类型转换问题 frame_ready = pyqtSignal(object, object) def __init__(self, model_path, conf=0.25, iou=0.45): super().__init__() self.model = YOLO(model_path) self.conf = conf self.iou = iou self.cap = None self.running = True def set_capture(self, cap): self.cap = cap def run(self): while self.running and self.cap is not None: ret, frame = self.cap.read() if not ret: break # 推理必须在子线程里做,画框也在这里完成 results = self.model.predict( frame, conf=self.conf, iou=self.iou, imgsz=640, verbose=False ) boxes = results[0].boxes for b in boxes: x1, y1, x2, y2 = map(int, b.xyxy[0].tolist()) cls_id = int(b.cls[0]) label = results[0].names[cls_id] cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2) cv2.putText(frame, label, (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2) # 把画好框的帧发回主线程,主线程只负责显示 self.frame_ready.emit(frame, results) self.msleep(1) # 让出 CPU,避免子线程占满 def stop(self): self.running = False self.wait()

这段代码有几个关键参数。frame_ready用object而不是QImage或QPixmap,是为了避免大图像在信号传递时反复转换格式,直接把numpy数组emit过去,主线程收到后再转QImage显示;msleep(1)让子线程每帧之间稍微让出事件循环,防止CPU被占满;stop()里先置running为False,再调wait()等待线程真正结束,否则程序退出时线程还挂在后台,窗口关了进程却不退。

主线程这边的槽函数,收到frame_ready信号后,把BGR转RGB再转QImage,然后setPixmap显示。不要在槽函数里再做任何耗时操作,显示完就返回。

def update_frame(self, frame, results): rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) h, w, ch = rgb.shape qimg = QImage(rgb.data, w, h, ch * w, QImage.Format_RGB888) pixmap = QPixmap.fromImage(qimg) self.label.setPixmap(pixmap.scaled( self.label.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation))

这里最需要注意的是QImage的bytesPerLine参数,也就是代码里的ch * w。如果这个参数不写对,图像显示出来会斜着撕裂,这是QImage最常见的坑。另外rgb.data指向的numpy数组可能在函数结束后被回收,所以QImage最好用copy()持有数据,或者保证frame_ready信号的帧生命周期足够长。我在实际项目里遇到过偶发花屏,最后就是加了一层copy()解决的。

4.3 图片、视频、相机三路输入:cv2与QImage的格式衔接

界面要支持三种输入:单张图片、视频文件、USB相机或工业相机。图片最简单,QFileDialog选图后,cv2.imread读进来直接交给Worker推理一次,结果帧显示出来。视频和相机是连续的帧流,需要起一个循环读帧的线程,把每帧交给推理。

视频文件用cv2.VideoCapture(path)打开,相机的区别只是入参不同:USB相机用cv2.VideoCapture(0)或设备索引号;工业相机如果用的是海康MVS SDK,SDK的回调线程里会推帧,注意不要在SDK回调里直接做模型推理,回调里只做帧转发,把帧放到队列里,再由推理线程取走。这样做的原因是SDK回调线程的优先级和时序不受我们控制,直接在里面推理会导致帧率不稳、推理耗时忽高忽低。

格式衔接上,整个流程里要统一用BGR顺序:cv2读出来是BGR,模型内部会做RGB转换,画框时又回到BGR,最后界面显示时一次性转RGB。不要在中间环节反复转换,转一次是必要的,转多了颜色会偏,而且白费CPU。如果发现检测框位置对但颜色明显不对,先怀疑是不是哪一步多转了一次RGB。

5. 避坑:钢材缺陷检测从训练到上界面最常见的5个问题

5.1 现象:损失函数画出来像心电图,mAP卡在0.3

训练几十个epoch后,loss曲线忽高忽低,mAP50始终在0.3附近上不去。原因通常不是网络结构问题,而是标注数据出了问题。我见过最多的是两种情况:一是XML转txt时坐标没有除以图像宽高,txt里出现了大于1的坐标;二是类别id和names顺序对不上,模型一直用“错误的标签”在学习。

解决:先打开一张训练图的txt看内容,第一列必须是0~5的整数,后四列必须是0~1的小数。再把txt画回原图可视化,确认框的位置贴不贴目标。如果是坐标问题,重新跑转换脚本;如果是类别顺序问题,把data.yaml的names顺序和转换脚本CLASSES顺序统一,然后重新训练。这一步检查最多花10分钟,比在参数上瞎调半天值多了。

5.2 现象:斑块和裂纹总被模型混成一类,验证集上这两类的precision很低

原因:crazing和patches在纹理上都是碎块状,200×200原图里人眼都容易看花,加上两类缺陷的形状、灰度分布高度重叠,模型很难用浅层特征区分。

解决:从三个方向入手。第一,给这两类增加数据增强强度,用copy-paste把少数类目标复制到其他图上,增加样本多样性;第二,模型换大一点,yolov8s或yolov8m的深层特征能学到更多纹理差异,比yolov8n效果明显;第三,如果还是不行,考虑用crop切块训练,把原图放大后再切块,让模型看到缺陷的局部细节。这个问题的本质是类别相似度太高,不要指望调loss函数能解决,数据和模型容量才是关键。

5.3 现象:GTX1660Ti训练时显存不足OOM

训练命令刚跑起来就报RuntimeError: CUDA out of memory。原因很直白:batch太大、输入尺寸太大、模型参数量超出6G显存。有的项目组为了追求精度直接上yolov8x,1660Ti根本带不动。

解决:按优先级调参,先把batch降到8,再不行把imgsz从640降到512,模型从yolov8s降到yolov8n。amp=True一定要开着,混合精度能省下大量显存。还可以把workers降到4以下,减少数据加载时额外占用的显存。NEU-DET原图只有200×200,imgsz=512对这个小数据集完全够用,没必要死守640。

5.4 现象:Qt界面一推理就转圈卡死

点“开始检测”按钮后,窗口立刻无响应,鼠标变成转圈状态,标题栏显示“未响应”。原因是推理代码直接写在按钮的槽函数里,阻塞了Qt的事件循环,界面刷新、鼠标事件全部排队等待,看起来就是卡死。

解决:把推理逻辑全部搬进QThread子线程,通过信号把结果发回主线程。注意两个细节:子线程里不能直接操作任何UI控件,包括setText、setPixmap都不行,否则会报“QObject::setParent: Cannot set parent, new parent is in a different thread”这类错误;程序关闭时先调用worker.stop(),把线程停下来再关闭窗口,不然Qt会报“QThread: Destroyed while thread is still running”,严重时程序退出后进程还在后台占着GPU。

5.5 现象:转ONNX后精度掉、检测框偏移

best.pt用着没问题,导出ONNX后精度掉了好几个点,框的位置明显偏移。常见原因是导出时的输入尺寸和训练时不统一,或者导出后预处理归一化方式和PyTorch不一致。YOLOv8训练和推理默认都做letterbox,图像会填充成正方形,导出后推理时漏了letterbox步骤,框自然全部偏掉。

解决:导出和推理时imgsz必须一致,导出命令里写了640,推理时也要640;推理前做同样的letterbox填充,推理后把坐标按填充比例映射回原图;导出后用onnxruntime跑同一张图,对照PyTorch的输出,先确认输出一致,再去转RKNN。这一步是部署前的最后一道保险,别跳过。

6. 把best.pt部署到RK3588:INT8量化与同一组图的精度验证

6.1 pt转onnx再转rknn:核心代码与量化参数

模型在PC上能跑只是第一步,真正上线往往要部署到边缘设备。RK3588是工业视觉项目里很常见的载体,它的NPU能跑INT8量化模型,部署路线固定为pt→onnx→rknn三步。导出onnx用ultralytics自带命令:

yolo export model=best.pt format=onnx imgsz=640

然后用rknn-toolkit2转rknn,量化这一步有几个参数决定模型最终效果。

from rknn.api import RKNN rknn = RKNN() # mean/std 必须是模型导出时的预处理参数,YOLOv8 默认归一化到 0~1 rknn.config(mean_values=[[0, 0, 0]], std_values=[[255, 255, 255]], target_platform='rk3588') rknn.load_onnx(model='best.onnx') rknn.build(do_quantization=True, dataset='quant_dataset.txt') rknn.export_rknn('best.rknn')

量化时的dataset.txt里,每行写一张图片路径,我一般从验证集里抽200张覆盖六类缺陷的图。量化数据集太少,模型容易“偏科”,对没见过的缺陷表现很差;太多也没必要,几百张足够校准激活值的分布。mean和std这里用的0和255,和YOLOv8默认的归一化一致,如果自己改过预处理,这里必须同步改,否则量化后输出全是错的。

6.2 验证方法:用同一组图对比PyTorch与RKNN的检出

量化完成后,拿同一组图片分别跑PyTorch模型和RKNN模型,对比检测框和置信度差异。这个对比不能只看一两张,我习惯挑30张图,要求六类缺陷每类至少出现5次,统计量化前后每类的mAP50差异。差异在3个点以内属于正常范围,超过5个点就要检查是否量化数据集和模型预处理不一致。

RKNN的输入是RGB顺序,而cv2读出来是BGR,这个顺序搞反了,检测出来的置信度会明显偏低。部署代码里记得先做cv2.cvtColor转为RGB,再做letterbox,最后送入NPU,输出结果解析时按“中心坐标+宽高”还原成框,再映射回原图。这一步和之前ONNX推理的坐标映射逻辑完全一致,可以直接复用。

6.3 我的验收习惯

项目做完后做性能验收时,我会同时记录三组数据:单帧推理耗时、CPU占用、画面在界面上的显示延迟。只盯推理耗时不够——有时候推理只要30毫秒,但画框、转图像、信号传递加一起多花了50毫秒,用户体感就是卡顿。我的经验是先在界面上用单张图片跑通全流程,确认显示、表格、阈值调节都正常,再接视频流,最后再换相机,每一步都单独验证,别一上来就全接上,出了问题都不知道该看哪一层。我现在做新项目,第一步永远是先锁数据集和类别顺序,再碰界面和部署,顺序反了后面全是返工。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/5 12:36:33

MCP 的 initialize 握手真的没了?67 行标准库实测 2026-07-28 规范

刷 MCP 更新说明的时候看到一句话:2026-07-28 修订把 initialize 握手和协议层会话整个删掉了——那套每个教程都在教的「先 initialize、再发 initialized 通知」的连接仪式,从规范层面不存在了。教程没骗人,只是过时了。我不信邪&#xff0…

作者头像 李华
网站建设 2026/10/5 12:35:50

大模型与Agent工程实践:从基础理论到多智能体协作

1. 今日聚焦:大模型与Agent工程实践1.1 大模型基础理论正在走向实用化2026年9月25日的AI圈,最明显的一个变化是:讨论大模型的人不再只聊参数量和榜单,而是真正开始聊基础理论的工程落地。热搜里持续挂着“ai大模型基础理论”和“a…

作者头像 李华
网站建设 2026/10/5 12:35:09

Qt坦克大战开发指南:QGraphicsView与碰撞检测实战

简介:面向高校C课程设计场景的Qt坦克大战游戏项目,适合需要完成射击类大作业的学生,也适合希望借助完整实例入门Qt游戏开发的开发者。项目基于Qt 5.14.1与gcc 7.3.0构建,实现了35个关卡、每关20个敌方坦克、3条生命值以及大本营守…

作者头像 李华
网站建设 2026/10/5 12:34:59

多智能体持久化编排:AI Agent协作与状态管理实战指南

我们团队从上个季度开始,把所有零散的AI Agent逐步收拢到一套统一的编排框架里,这套框架就是我们内部命名为OpenRig的项目。起因很直接——单跑的Agent多了以后,代码重复不说,最头疼的是每个Agent都是“失忆体质”,用户…

作者头像 李华
网站建设 2026/10/5 12:34:57

OpenRig:将离散AI Agent编织成持久化协作系统

做多智能体编排这件事,我在OpenRig这个项目里折腾了快一个季度。最开始的想法非常简单:把已经造好的几个AI Agent用起来,让它们配合干活。结果一开始跑真实业务,就撞上了状态丢失、上下文割裂、任务分配混乱这些尴尬问题。单个Age…

作者头像 李华
网站建设 2026/10/5 12:34:55

Unity Shader实现Logo流光效果:从UV坐标到扫光Shader全解析

简介:面向Unity开发者的Logo流光Shader特效资源包,适合有一定Shader基础或希望快速实现动态光线效果的游戏UI、视觉设计师。资源完整覆盖两种实现路线:纯代码方式基于ShaderLab编写表面函数与顶点/片段着色器,利用时间变量与Lerp/…

作者头像 李华