HarmonyOS应用开发实战:猫猫大作战-@State 数组项替换的浅观察陷阱、@Observed 数组深观察机制、ForEach 密钥与项替换的协
前言上一篇我们用ObservedObjectLink让「改猫咪内部属性」直接触发重渲染。但游戏中还有种操作——替换数组某一项合并时把cats[0]替换成新等级的猫、升级时把inventory[3]换成新道具。this.cats[0] newCat这种数组项替换浅观察的State监听不到引用没变怎么破本篇以「猫猫大作战」合并时替换数组项为锚点把State 数组项替换的浅观察陷阱、Observed 数组深观察机制、ForEach 密钥与项替换的协同、三种替换方式对比四大要点讲透。提示本系列不讲 ArkTS 基础语法与环境搭建假设你已跟完第 1–43 篇。本篇是阶段二第十四篇。一、场景拆解合并替换数组项回顾「猫猫大作战」合并逻辑第 121、125 篇会专讲此处简提// 来源entry/src/main/ets/components/GameEngine.ets tryMergeAt() private tryMergeAt(x: number, y: number): boolean { const cat this.board[y][x]; if (!cat) return false; const sameLevelNeighbors: Cat[] []; /* ... 找相邻同级猫 ... */ if (sameLevelNeighbors.length GameConfig.MERGE_COUNT) { const newLevel (cat.level 1) as CatLevel; const newCat: Cat new Cat(cat_${this.catCounter}, newLevel, x, y, false); // 移除被合并的猫 this.removeCat(cat); const toRemove sameLevelNeighbors.slice(0, GameConfig.MERGE_COUNT); toRemove.forEach((c) this.removeCat(c)); // 放置新猫 this.cats.set(newCat.id, newCat); this.board[y][x] newCat; return true; } return false; }痛点合并后 UI 层的State cats: Cat[]怎么同步当前解法第 31 篇引擎返回新数组UI 整体赋值this.cats this.gameEngine.getAllCats()——靠数组引用变化触发重渲染。但如果只想替换其中一项this.cats[0] newCat浅观察监听不到。Observed 数组深观察的解法// 1. Cat 是 Observed class第 43 篇 Observed export class Cat { /* ... */ } // 2. 数组也用 Observed 标记不ArkUI 用「数组项是 Observed 实例 ForEach 密钥」自动深观察 // 3. 替换数组项时密钥变化触发 ForEach diff this.cats[0] newCat; // 替换项 // ForEach 用 cat.id 做密钥旧 cat-0 销毁新 cat 摆上关键经验数组项替换靠「ForEach 密钥 diff」「Observed 项深观察」双机制——密钥变触发项销毁/新建密钥同但内部属性变触发深观察。二、State 数组项替换的浅观察陷阱2.1 浅观察只监听引用和增删State cats: Cat[] []; // ✅ 触发重渲染引用变 this.cats [...this.cats]; // ✅ 触发重渲染增删 this.cats.push(newCat); this.cats.splice(0, 1); // ❌ 不触发重渲染替换项引用没变 this.cats[0] newCat; // ❌ 不触发重渲染改项内部属性 this.cats[0].y 1;机制State浅观察只监听数组引用变化和增删——this.cats[0] newCat替换项数组引用没变长度没变浅观察视为「没变」。2.2 当前解法整体赋值this.cats[0] newCat; // 替换项 this.cats [...this.cats]; // 整体赋值触发缺点每次替换一项都要重建整个数组N 只猫整体 diff浪费。2.3 期望只重渲染被替换的那项this.cats[0] newCat; // 只想重渲染第 0 项 // 其他 N-1 只猫不动这就是 Observed 数组深观察的用武之地。三、ForEach 密钥与项替换的协同3.1 ForEach 用密钥做 diff回顾「猫猫大作战」猫咪渲染第 15、43 篇ForEach(this.cats, (cat: Cat) { CatItem({ cat: cat }) }, (cat: Cat) cat.id) // ← 密钥 cat.idForEach diff 机制数组变化时ForEach 用密钥对比旧新数组。新增密钥→ 渲染新项。删除密钥→ 销毁旧项。密钥同但项变→ 复用项传新数据深观察触发内部刷新。3.2 项替换 删旧密钥 增新密钥// 原 cats [{ id: cat_0, level: 1, ... }, { id: cat_1, ... }] // 合并cat_0 和 cat_1 合并成新猫 cat_2 this.cats[0] new Cat(cat_2, 2, 0, 5, false); // 替换第 0 项 // 数组变成 [{ id: cat_2, ... }, { id: cat_1, ... }] // ForEach diff // 旧密钥 [cat_0, cat_1] // 新密钥 [cat_2, cat_1] // cat_0 删了 → 销毁旧 CatItem // cat_2 新增 → 渲染新 CatItem // cat_1 同 → 复用不重渲染关键经验项替换时密钥变cat_0 → cat_2ForEach 销毁旧项新建新项——只重渲染被替换的那项其他不动。3.3 密钥不变的项替换陷阱// 假设替换时密钥不变复用同一 id this.cats[0] new Cat(cat_0, 2, 0, 5, false); // id 还是 cat_0但 level 变了 // 数组 [{ id: cat_0, level: 2, ... }, { id: cat_1, ... }] // ForEach diff // 旧密钥 [cat_0, cat_1] // 新密钥 [cat_0, cat_1] // 密钥全同 → 复用所有 CatItem不销毁不新建 // 但 cat_0 的 level 变了 → 靠 ObjectLink 深观察触发内部刷新两种情况对比替换方式密钥变ForEach 行为触发机制new Cat(cat_2, ...)新 id✅销毁旧项 新建新项ForEach diffnew Cat(cat_0, ...)同 id❌复用项ObjectLink 深观察关键经验密钥变靠 ForEach diff密钥同靠 ObjectLink 深观察——双机制覆盖所有替换场景。四、实战合并替换数组项4.1 引擎合并后返回新数组// 来源entry/src/main/ets/components/GameEngine.ets updateCats(): Cat[] { let hasMerge false; const sortedCats Array.from(this.cats.values()) .filter(cat cat.falling) .sort((a, b) b.y - a.y); sortedCats.forEach((cat) { /* ... 下落或着陆 ... */ }); if (hasMerge) { this.checkAllMerges(); // 合并会改 cats Map } return Array.from(this.cats.values()); // 返回新数组快照 }4.2 UI 层整体赋值当前稳定解法// 来源entry/src/main/ets/pages/Index.ets 主循环 this.gameLoopTimer setInterval(() { if (this.gameState ! GameState.PLAYING) return; this.cats this.gameEngine.updateCats(); // 整体赋值新数组 this.score this.gameEngine.getScore(); this.combo this.gameEngine.getCombo(); }, 100);机制引擎返回新数组引用UI 整体赋值this.cats ...引用变触发 ForEach 全 diff。ForEach 用密钥cat.id对比旧新落的猫 id 没变 → 复用靠 ObjectLink 深观察刷新移动的 position。合并的猫 id 删了 → 销毁旧 CatItem。新合并的猫 id 新增 → 渲染新 CatItem。关键经验整体赋值 ForEach 密钥 diff ObjectLink 深观察 三重协同——引用变触发 diff密钥变触发增删密钥同深观察内部。4.3 进阶只替换数组项不整体赋值如果想优化性能不整体赋值只替换变化的项// 假设引擎暴露 mergeAt(index) 返回新猫 const newCat this.gameEngine.mergeAt(0); this.cats[0] newCat; // 替换第 0 项 // ⚠️ 浅观察不触发要手动触发两种手动触发方式// 方式 A整体赋值简单但浪费 this.cats[0] newCat; this.cats [...this.cats]; // 方式 B用 Observed 数组深观察进阶 // ArkUI 的 State 数组本身不深观察项替换 // 要靠 ForEach 密钥 diff必须让数组引用变 // 所以实际上方式 A 是当前最稳定的解法实战经验当前 ArkUI V1 的 State 数组不支持「项替换深观察」——必须整体赋值让引用变ForEach 才 diff。V2 的 ObservedV2 数组才支持项替换深观察第 50 篇会讲。五、三种替换方式对比5.1 方式 A整体赋值推荐本项目this.cats this.gameEngine.getAllCats(); // 整体赋值新数组优点缺点简单稳定N 只猫整体 diffForEach 自动 diff性能 N 大时浪费兼容 V1 V2—5.2 方式 B增删 APIthis.cats.splice(0, 1, newCat); // 删第 0 项并插入 newCat优点缺点显式增删API 略繁琐触发浅观察增删仍是整体 diff5.3 方式 C项替换 整体赋值this.cats[0] newCat; // 替换 this.cats [...this.cats]; // 整体赋值触发优点缺点语义清晰先改再触发两步操作ForEach diff仍是整体 diff5.4 对比表方式代码触发性能推荐A 整体赋值this.cats getAll()引用变中✅ 本项目B splicethis.cats.splice(0,1,newCat)增删中增删场景C 替换赋值this.cats[0]newCat; this.cats[...this.cats]引用变中语义清晰关键经验当前 V1 三种方式本质都是「让数组引用变」触发 ForEach diff——性能差异微乎其乎方式 A 最简洁。六、ForEach 密钥的实战坑6.1 密钥必须唯一// ❌ 错误密钥不唯一ForEach diff 错乱 ForEach(this.cats, (cat: Cat) { CatItem({ cat: cat }) }, (cat: Cat) cat.level) // ← 用 level 做密钥 // 两只 level1 的猫密钥都 1冲突 // ✅ 正确密钥唯一 ForEach(this.cats, (cat: Cat) { CatItem({ cat: cat }) }, (cat: Cat) cat.id) // ← id 唯一6.2 密钥用坐标会踩坑// ❌ 错误用坐标做密钥移动时密钥变导致销毁新建 ForEach(this.cats, (cat: Cat) { CatItem({ cat: cat }) }, (cat: Cat) ${cat.x}_${cat.y}) // ← 坐标做密钥 // 猫从 (0,5) 移到 (0,6)密钥 0_5 → 0_6 // ForEach 销毁旧 CatItem 新建新 CatItem失去移动动画连续性 // ✅ 正确用不变的 id 做密钥 ForEach(this.cats, (cat: Cat) { CatItem({ cat: cat }) }, (cat: Cat) cat.id) // ← id 不随坐标变 // 移动时密钥同复用 CatItem靠 ObjectLink 深观察刷新 position动画连续关键经验密钥用不变的字段id别用会变的字段坐标、等级——否则移动/升级都变成销毁新建失去动画连续性。第 15 篇讲过这个坑。6.3 合并时密钥的正确处理// 合并cat_0 和 cat_1 合并成新猫 // 引擎内部 this.removeCat(cat_0); // cats Map 删 cat_0 this.removeCat(cat_1); // cats Map 删 cat_1 this.cats.set(cat_2, newCat); // cats Map 加 cat_2 // UI 整体赋值后 ForEach diff // 旧密钥 [cat_0, cat_1, cat_3, ...] // 新密钥 [cat_2, cat_3, ...] // cat_0 cat_1 销毁cat_2 新建cat_3 复用关键经验合并时引擎删旧 id 加新 idForEach 自然销毁旧项新建新项——这就是「合并动画」的本质旧猫消失 新猫出现。七、完整代码合并替换数组项// 来源entry/src/main/ets/pages/Index.etsObserved 改造后 import { Cat, CatLevel, GameConfig, CatConfig, GameState, ComboInfo } from ../components/GameTypes; import { GameEngine } from ../components/GameEngine; import { GameHUD } from ../components/GameHUD; import { CatItem } from ../components/CatItem; import { PauseOverlay } from ../components/PauseOverlay; Entry Component struct Index { State Watch(onGameStateChange) gameState: GameState GameState.IDLE; State score: number 0; State cats: Cat[] []; // Cat 是 Observed class State combo: ComboInfo { count: 0, multiplier: 1, lastMergeTime: 0 }; State nextCatLevel: CatLevel CatLevel.SMALL; State highScore: number 0; State gameTime: number 0; State maxCombo: number 0; State mergeCount: number 0; State highestLevel: CatLevel CatLevel.SMALL; Provide(gameState) providedGameState: GameState this.gameState; Provide(score) providedScore: number this.score; private gameEngine: GameEngine new GameEngine(); private gameLoopTimer: number -1; private spawnTimer: number -1; private timeTimer: number -1; private readonly cols: number[] [0, 1, 2, 3, 4]; private readonly rows: number[] [0, 1, 2, 3, 4, 5, 6, 7]; startGame() { this.clearTimers(); this.gameEngine.reset(); this.gameState GameState.PLAYING; this.score 0; this.cats []; this.gameTime 0; this.combo { count: 0, multiplier: 1, lastMergeTime: 0 }; this.nextCatLevel this.gameEngine.getNextCatLevel(); // 主循环整体赋值 cats 数组本篇重点 this.gameLoopTimer setInterval(() { if (this.gameState ! GameState.PLAYING) return; this.cats this.gameEngine.updateCats(); // 整体赋值触发 ForEach diff this.score this.gameEngine.getScore(); this.combo this.gameEngine.getCombo(); if (this.gameEngine.isGameOver()) { this.endGame(); } }, 100); this.spawnTimer setInterval(() { if (this.gameState ! GameState.PLAYING) return; if (this.gameEngine.getCatCount() GameConfig.MAX_CATS) { this.gameEngine.autoSpawnCat(); this.cats this.gameEngine.getAllCats(); // 整体赋值 this.nextCatLevel this.gameEngine.getNextCatLevel(); } }, GameConfig.SPAWN_RATE); this.timeTimer setInterval(() { if (this.gameState GameState.PLAYING) { this.gameTime; } }, 1000); } handleColumnClick(column: number) { if (this.gameState ! GameState.PLAYING) return; if (this.gameEngine.dropCat(column)) { this.cats this.gameEngine.getAllCats(); // 整体赋值 this.nextCatLevel this.gameEngine.getNextCatLevel(); } } /* pauseGame / resumeGame / endGame / clearTimers / formatTime / aboutToDisappear / onGameStateChange 等略 */ Builder GameView() { Column() { GameHUD() Column() { Row() { /* 预告区 */ } Stack() { Column() { /* 棋盘背景 ForEach rows × cols */ } // 猫咪渲染Observed Cat ForEach 用 id 做密钥 ForEach(this.cats, (cat: Cat) { CatItem({ cat: cat }) // ObjectLink 深观察 }, (cat: Cat) cat.id) // ← 密钥用 id Row() { ForEach(this.cols, (col: number) { Column() .width(GameConfig.CELL_SIZE) .height(GameConfig.BOARD_HEIGHT * GameConfig.CELL_SIZE) .backgroundColor(rgba(0,0,0,0)) .onClick(() { this.handleColumnClick(col); }) }, (col: number) click_${col}) } } .width(GameConfig.BOARD_WIDTH * GameConfig.CELL_SIZE) .height(GameConfig.BOARD_HEIGHT * GameConfig.CELL_SIZE) .borderRadius(12).clip(true).backgroundColor(#D6EEF5) }.alignItems(HorizontalAlign.Center) Spacer() Row() { /* 底部控制栏 */ } .width(100%).padding({ left: 24, right: 24, bottom: 24, top: 12 }) } .width(100%).height(100%) .linearGradient({ direction: GradientDirection.Bottom, colors: [[#E8F4F8, 0.0], [#D6EEF5, 0.5], [#C9E8F2, 1.0]] }) .alignItems(HorizontalAlign.Center) } /* MainMenuView / PauseOverlay 引用 / GameOverOverlay / StatItem 等略 */ }八、踩坑提示8.1 项替换后忘整体赋值// ❌ 错误替换项没整体赋值浅观察不触发 this.cats[0] newCat; // 数组引用没变不触发 // ✅ 正确替换后整体赋值 this.cats[0] newCat; this.cats [...this.cats]; // 引用变触发 ForEach diff8.2 密钥用会变的字段// ❌ 错误用坐标做密钥移动时销毁新建 ForEach(this.cats, (cat: Cat) { /* ... */ }, (cat: Cat) ${cat.x}_${cat.y}) // ✅ 正确用不变的 id ForEach(this.cats, (cat: Cat) { /* ... */ }, (cat: Cat) cat.id)8.3 密钥不唯一// ❌ 错误多只同级猫密钥都 level冲突 ForEach(this.cats, (cat: Cat) { /* ... */ }, (cat: Cat) cat.level.toString()) // ✅ 正确id 唯一 ForEach(this.cats, (cat: Cat) { /* ... */ }, (cat: Cat) cat.id)8.4 合并忘删旧猫密钥// ❌ 错误引擎合并只加新猫没删旧猫密钥冲突 this.cats.set(cat_2, newCat); // 加新 // 忘了 this.removeCat(cat_0); this.removeCat(cat_1); // getAllCats 返回 [cat_0, cat_1, cat_2, ...]密钥都唯一但内容错乱 // ✅ 正确合并时删旧加新 this.removeCat(cat_0); this.removeCat(cat_1); this.cats.set(cat_2, newCat);九、调试技巧console.info打 cats.length 和密钥合并后 log追项数和密钥变化。合并后猫不消失排查检查引擎是否 removeCat 旧猫检查 ForEach 密钥是否唯一。移动不连续排查检查密钥是否用了坐标会变的字段检查 ObjectLink 是否深观察。DevEco ArkUI Inspector查看 ForEach 子项和密钥绑定。十、性能与最佳实践当前 V1 数组项替换靠整体赋值——this.cats getAll()让引用变触发 ForEach diff。ForEach 密钥用不变字段——id 唯一且不随坐标/等级变移动/升级连续。密钥变 销毁新建——合并时删旧 id 加新 id自然销毁旧项新建新项。密钥同 复用深观察——移动时 id 不变复用 CatItem靠 ObjectLink 刷新 position。合并时引擎删旧加新——removeCat 旧猫 set 新猫ForEach diff 正确。V2 数组支持项替换深观察——ObservedV2 数组直接监听arr[i]newCat第 50 篇会讲。总结本篇我们从数组项替换切入掌握了**State 数组浅观察陷阱项替换不触发**、ForEach 密钥 diff 协同密钥变销毁新建密钥同深观察、三种替换方式对比整体赋值最简、密钥用不变字段的实战坑四大要点并给出了合并替换数组项的完整代码。核心要点V1 项替换靠整体赋值触发 diff密钥用 id 不用坐标合并删旧加新密钥变销毁新建密钥同深观察。下一篇我们将拆解批量状态更新——单次 re-render 的优化。如果这篇文章对你有帮助欢迎点赞、收藏⭐、关注你的支持是我持续创作的动力相关资源「猫猫大作战」项目源码本仓库entry/src/main/ets/pages/Index.ets、entry/src/main/ets/components/GameEngine.ets、entry/src/main/ets/components/GameTypes.etsForEach 循环渲染与密钥官方指南ArkUI Observed 深观察官方指南ArkUI 数组与列表性能最佳实践开源鸿蒙跨平台社区HarmonyOS 开发者官方文档首页系列索引本仓库articles/INDEX.md

相关新闻

Unix操作系统设计实验指导 --- 20个实验步骤及代码

Unix操作系统设计实验指导 --- 20个实验步骤及代码

Unix操作系统设计实验指导 --- 20个实验步骤及代码 摘要:以下是针对“Unix操作系统设计”课程的20个实验设计。这些实验基于Unix-like系统(如Linux),旨在帮助学生理解操作系统核心概念,包括进程管理、文件系统、内存管理、系统调用和内核相关操作。实验使用C语言编…

2026/7/28 22:32:17 阅读更多 →
解锁Blink本地存储:blinkpy视频下载高级技巧与最佳实践

解锁Blink本地存储:blinkpy视频下载高级技巧与最佳实践

解锁Blink本地存储:blinkpy视频下载高级技巧与最佳实践 【免费下载链接】blinkpy A Python library for the Blink Camera system 项目地址: https://gitcode.com/gh_mirrors/bl/blinkpy Blink相机系统的本地存储功能是保护家庭安全的重要一环,而…

2026/7/28 22:32:17 阅读更多 →
国产数据库基于PostgreSQL的创新之路:从兼容到超越的技术实践

国产数据库基于PostgreSQL的创新之路:从兼容到超越的技术实践

如果你是一名数据库工程师,或者在过去几年里关注过国产数据库的新闻,你很可能听过这样的说法:“很多国产数据库都是基于 PostgreSQL 改的”。这句话背后,是赞誉、是质疑,还是一个被简化了的复杂现实?当“自…

2026/7/28 22:31:17 阅读更多 →

最新新闻

M9A自动化引擎架构解析:如何构建基于图像识别的游戏智能代理系统

M9A自动化引擎架构解析:如何构建基于图像识别的游戏智能代理系统

M9A自动化引擎架构解析:如何构建基于图像识别的游戏智能代理系统 【免费下载链接】M9A 重返未来:1999 小助手 | Assistant For Reverse: 1999 项目地址: https://gitcode.com/gh_mirrors/m9/M9A M9A是基于MaaFramework图像识别框架构建的《重返未…

2026/7/28 22:39:24 阅读更多 →
爱译客翻译工具:游戏与语言学习的终身免费解决方案

爱译客翻译工具:游戏与语言学习的终身免费解决方案

1. 项目概述:爱译客翻译工具的定位与核心价值作为一名在本地化行业摸爬滚打十年的老鸟,我见过太多翻译工具昙花一现。今天要聊的这个"爱译客翻译工具"有点特别——它瞄准了两个看似不相关却实际高度契合的场景:外服游戏玩家和语言学…

2026/7/28 22:39:24 阅读更多 →
OpenClaw多代理系统token优化:记忆存储与检索增强策略

OpenClaw多代理系统token优化:记忆存储与检索增强策略

1. OpenClaw的token消耗问题本质分析OpenClaw作为多代理协同系统,其token消耗爆炸问题主要发生在记忆存储和检索增强两个环节。当系统运行时间较长或处理复杂任务时,记忆库中的上下文信息会不断累积,导致每次调用语言模型时都需要消耗大量tok…

2026/7/28 22:39:24 阅读更多 →
FunClip终极指南:5分钟掌握AI智能视频剪辑全流程

FunClip终极指南:5分钟掌握AI智能视频剪辑全流程

FunClip终极指南:5分钟掌握AI智能视频剪辑全流程 【免费下载链接】FunClip FunASR-powered video transcription, subtitle generation, and LLM-assisted clipping tool with a local Gradio UI. 项目地址: https://gitcode.com/GitHub_Trending/fu/FunClip …

2026/7/28 22:39:24 阅读更多 →
LangChain4j工具调用机制与Java AI集成实践

LangChain4j工具调用机制与Java AI集成实践

1. LangChain4j工具调用核心机制解析在Java生态中集成AI能力时,LangChain4j提供了优雅的解决方案。其Tool注解作为工具调用的入口点,通过反射机制将普通Java方法转化为AI可调用的功能单元。我们先看一个典型示例:public class CalculatorTool…

2026/7/28 22:39:24 阅读更多 →
Chrome插件安全最佳实践:防止XSS、CSRF攻击

Chrome插件安全最佳实践:防止XSS、CSRF攻击

Chrome插件安全最佳实践:防止XSS、CSRF攻击 前言 Chrome 插件运行在浏览器的高权限环境里,content script 又能直接接触网页 DOM,稍不注意就会引入 XSS(跨站脚本)和 CSRF(跨站请求伪造)风险。一…

2026/7/28 22:38:22 阅读更多 →

日新闻

告别臃肿!3步让你的暗影精灵笔记本重获新生

告别臃肿!3步让你的暗影精灵笔记本重获新生

告别臃肿!3步让你的暗影精灵笔记本重获新生 【免费下载链接】OmenSuperHub Control Omen laptop performance, fan speeds, and keyboard lighting, and unlock power limits. 项目地址: https://gitcode.com/gh_mirrors/om/OmenSuperHub 你是否也曾为官方Om…

2026/7/28 0:00:43 阅读更多 →
RAG必踩坑!财报法规检索不准?这款开源工具让答案浮出水面,准确率飙升98.7%!

RAG必踩坑!财报法规检索不准?这款开源工具让答案浮出水面,准确率飙升98.7%!

做 RAG 的人应该都踩过这个致命的坑:把几百页的财报、法规、技术手册扔给向量库,问一个具体问题,搜出来的全是沾边但没用的内容 —— 关键信息要么被硬切块拆碎了,要么藏在几十条结果的最下面。语义相似≠真正相关,这个…

2026/7/28 0:00:43 阅读更多 →
抖音视频文案提取工具全指南:免费2026版、手机App、在线工具一网打尽

抖音视频文案提取工具全指南:免费2026版、手机App、在线工具一网打尽

2026年做短视频运营,从抖音上扒文案早就不是偷偷抄笔记的事了。我刚开始做内容的时候,每天刷半小时抖音,手动把爆款视频的口播敲进备忘录,一条2分钟的视频得花十来分钟,碰到语速快的还要反复回听。后来试了一圈工具&am…

2026/7/28 0:00:43 阅读更多 →

周新闻

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 数据集6000张 完整源码已标注数据集训练好的模型环境配置教程程序运行说明文档,可以直接使用!系统支持图片、视频、摄像头等多种方式检测裂缝,功能强大实用。 1数据集6000张 8各类别

2026/7/28 12:04:22 阅读更多 →
深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

pubg数据集 精选原图1.42万数据 1.49万标签 无任何重复、算法增强或冗余图像! pubg绝地求生目标检测数据集 1分类:e_body,14905个标签,txt格式 共计14244张图,99%为640*640尺寸图像 适合yolo目标检测、AI训练关键词&am…

2026/7/28 8:29:16 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex检测数据集数据集详情检测类别: allies enemy tag图片总量:7247张训练集:5139张验证集:1425张测试集:683张标注状态:全部已标注,即拿即用数据格式:支持YOLO格式及其他格式&#…

2026/7/28 5:03:42 阅读更多 →

月新闻