C++游戏主循环优化:Coze-Loop模式实战,帧率提升30%
1. 项目概述当C游戏开发遇上Coze-Loop最近在优化一个自研的C游戏引擎时我遇到了一个经典的性能瓶颈主循环Game Loop的逻辑与渲染耦合过紧导致帧率FPS在复杂场景下波动剧烈难以稳定在目标60帧。尝试了各种传统的多线程渲染、指令缓冲优化后效果都不尽理想。直到我将目光投向了“Coze-Loop”这个设计模式——准确说是借鉴了其核心思想并将其与C游戏开发中成熟的架构进行了一次深度“嫁接”。结果出乎意料在相同的硬件条件下目标场景的帧率从平均45 FPS提升并稳定到了58 FPS以上CPU的利用率也更加平滑。这不是某个神秘新库的魔法而是一次关于“解耦”与“调度”的思维实践。如果你也在为C游戏或高性能实时应用的帧率优化头疼尤其是感觉CPU明明没跑满但帧时间Frame Time就是下不来那么这次关于“Coze-Loop”在游戏主循环中的优化实战或许能给你带来一些新的思路。简单来说Coze-Loop并非一个可以直接#include的C库。根据其公开的设计理念它本质上是一种面向异步、事件驱动架构的循环调度模式核心在于将一个大循环内的不同任务如AI计算、物理模拟、用户输入、渲染提交视为独立的“协程”Coroutine或“任务流”Task Flow并由一个中央调度器Scheduler来协调它们的执行时机与依赖关系而非传统的、僵硬的顺序执行。在游戏开发语境下这直接对应了我们最核心的游戏主循环的优化。传统的while(isRunning){ ProcessInput(); Update(); Render(); }模式在面临现代游戏复杂的子系统时已显得力不从心。Coze-Loop的思想为我们重构主循环实现逻辑帧Tick与渲染帧Frame的分离、以及子系统间的并行化提供了一个清晰的理论框架。2. 核心需求解析为什么传统游戏循环会卡顿在深入Coze-Loop的改造之前我们必须先搞清楚传统游戏循环的痛点。假设我们有一个简单的2D游戏循环代码如下void Game::RunLoop() { while (m_isRunning) { auto frameStart std::chrono::high_resolution_clock::now(); // 阶段1处理输入 ProcessInput(); // 阶段2更新游戏状态物理、AI、动画等 UpdateGameLogic(); // 阶段3生成渲染命令并提交 Render(); // 阶段4帧率控制 auto frameEnd std::chrono::high_resolution_clock::now(); std::chrono::durationdouble elapsed frameEnd - frameStart; double frameTime elapsed.count(); double targetFrameTime 1.0 / 60.0; // 目标60FPS if (frameTime targetFrameTime) { std::this_thread::sleep_for( std::chrono::durationdouble(targetFrameTime - frameTime) ); } // 否则说明这一帧已经超时我们丢帧了。 } }这个循环看起来清晰但隐藏着几个致命问题正是它们导致了帧率不稳定2.1 强耦合的串行执行ProcessInput、UpdateGameLogic、Render三个阶段必须顺序执行。如果UpdateGameLogic因为复杂的AI寻路或物理碰撞计算耗时20毫秒那么Render阶段就必须等待这20毫秒结束后才能开始。即使GPU空闲画面也无法开始渲染直接拉长了整个帧时间。2.2 渲染与逻辑的“锁步”逻辑更新和渲染以相同的频率如60Hz运行。但很多时候游戏逻辑特别是AI、经济系统并不需要如此高的更新频率。30Hz甚至10Hz可能就足够了。让它们以60Hz运行是在浪费宝贵的CPU时间片这些时间本可以用于渲染线程或更复杂的图形计算。2.3 阻塞式I/O与耗时操作如果在UpdateGameLogic中同步加载了一个资源如从磁盘读取一个纹理整个主线程都会被阻塞游戏直接“卡住”。传统的循环结构对此没有抵抗力。2.4 难以利用多核CPU所有逻辑都在主线程中串行执行现代CPU的多个核心无法被有效利用。虽然可以将渲染丢到另一个线程但游戏状态更新本身包含大量可并行计算如多个独立NPC的AI计算、粒子系统更新等在传统循环中很难优雅地拆分。注意你可能会想到使用“双缓冲”状态和独立的渲染线程。这确实是迈向高级循环的第一步但Coze-Loop模式提供了更系统化的任务划分与调度方案管理起来更清晰。我们的优化目标很明确解耦、并行化、按需调度。让CPU和GPU都能尽可能持续、饱满地工作减少相互等待的时间从而提升帧率与流畅度。这正是Coze-Loop设计思想可以大显身手的地方。3. Coze-Loop架构思想与游戏主循环的融合Coze-Loop的核心是“任务”与“调度”。我们可以将游戏中的每一项工作都抽象为一个Task。例如InputTask: 收集和处理本帧的输入事件。PhysicsTask: 执行物理模拟。AITask: 更新所有NPC的AI决策。AnimationTask: 更新骨骼动画状态。RenderSubmissionTask: 将渲染所需的数据变换矩阵、材质参数等准备好提交到命令队列。RenderPresentTask: 通知GPU执行渲染并呈现到屏幕。这些任务之间存在依赖关系。例如RenderSubmissionTask依赖AnimationTask和PhysicsTask的输出最终的世界矩阵而AnimationTask可能依赖本帧的InputTask结果角色移动指令。3.1 设计我们的“游戏任务调度器”我们不直接使用某个Coze-Loop的实现而是用C17/20的标准库或简单的自定义调度器来模拟这一思想。首先定义一个任务基类class GameTask { public: enum class State { Pending, Ready, Executing, Completed }; virtual ~GameTask() default; virtual void Execute() 0; // 任务执行的具体逻辑 State GetState() const { return m_state; } void AddDependency(GameTask* task) { m_dependencies.push_back(task); } bool IsReady() const { return std::all_of(m_dependencies.begin(), m_dependencies.end(), [](const GameTask* t) { return t-GetState() State::Completed; }); } protected: std::vectorGameTask* m_dependencies; std::atomicState m_state{State::Pending}; };然后我们实现一个简单的调度器它每一帧或每个逻辑Tick收集所有Ready状态的任务并将它们提交到线程池中执行class TaskScheduler { public: void SubmitTask(std::unique_ptrGameTask task) { m_tasks.push_back(std::move(task)); } void Update() { // 1. 找出所有就绪的任务 std::vectorGameTask* readyTasks; for (auto task : m_tasks) { if (task-IsReady() task-GetState() GameTask::State::Pending) { readyTasks.push_back(task.get()); } } // 2. 使用线程池并行执行这里简化表示 std::vectorstd::futurevoid futures; for (auto* task : readyTasks) { futures.push_back(std::async(std::launch::async, [task]() { task-m_state GameTask::State::Executing; task-Execute(); task-m_state GameTask::State::Completed; })); } // 3. 等待本帧所有任务完成可根据需要调整比如渲染任务不在此等待 for (auto fut : futures) { fut.wait(); } // 4. 清理已完成的任务或进行下一轮调度 // ... 实际项目中可能需要更复杂的生命周期管理 } private: std::vectorstd::unique_ptrGameTask m_tasks; };3.2 重构游戏循环逻辑帧与渲染帧分离这是最关键的一步。我们引入两个核心概念逻辑更新频率Tick Rate: 比如 30 Hz。这是游戏世界状态物理、AI更新的频率。渲染频率Frame Rate: 比如 60 Hz 或 144 Hz。这是画面生成的频率。它们独立运行。主循环的核心变为一个高优先级的“渲染循环”它尽可能快地运行。而逻辑更新则作为一个周期性任务由调度器在固定的时间间隔如每33.3ms触发一次。void Game::RunCozeLoop() { auto scheduler std::make_uniqueTaskScheduler(); // 初始化各种任务并建立依赖关系... // 例如RenderTask 依赖 LogicUpdateTask 完成。 double tickInterval 1.0 / 30.0; // 逻辑更新30Hz double accumulatedTime 0.0; auto previousTime std::chrono::high_resolution_clock::now(); while (m_isRunning) { auto currentTime std::chrono::high_resolution_clock::now(); double deltaTime std::chrono::durationdouble(currentTime - previousTime).count(); previousTime currentTime; accumulatedTime deltaTime; // **关键点1固定时间步长的逻辑更新** while (accumulatedTime tickInterval) { // 提交本Tick的所有逻辑任务物理、AI等到调度器 SubmitLogicTasks(scheduler.get()); // 调度并等待逻辑任务完成使用独立的逻辑线程池 scheduler-UpdateLogicTasks(); // 这是一个会等待逻辑任务完成的更新 accumulatedTime - tickInterval; m_currentTick; // 逻辑Tick计数 } // **关键点2不受限的渲染循环** // 渲染任务不等待逻辑Tick它总是基于最新的、已完成的逻辑状态进行插值。 SubmitRenderTasks(scheduler.get()); // 渲染任务的更新通常是异步的不阻塞主循环直接提交到GPU命令队列。 scheduler-UpdateRenderTasks(); // 帧率控制可以放在渲染呈现之后或者使用垂直同步VSync PresentFrame(); } }在这个架构下即使某一帧的逻辑计算特别耗时比如用了15ms只要它发生在独立的逻辑Tick中渲染循环仍然可以基于上一Tick完成的状态通过插值如物体位置在两个逻辑Tick之间线性插值来生成平滑的中间帧画面。用户感知到的渲染帧率可以保持高位而逻辑世界的更新则在后台以稳定的、可能较低的频率运行。4. 实战优化将子系统任务化与并行化理论有了我们来看具体如何将游戏引擎的常见子系统改造成“Coze-Loop”风格的任务。4.1 物理系统任务化物理模拟通常是CPU密集型的。我们可以将世界中的物理实体分组创建多个PhysicsTask每个任务负责更新一组刚体的位置、速度并检测组内碰撞。这些任务可以并行执行。组间的碰撞检测Broad Phase Narrow Phase可以作为另一个依赖任务在所有PhysicsTask完成后执行。class PhysicsTask : public GameTask { public: PhysicsTask(PhysicsWorld world, int startIdx, int endIdx) : m_world(world), m_start(startIdx), m_end(endIdx) {} void Execute() override { for (int i m_start; i m_end; i) { m_world.UpdateRigidBody(i, m_deltaTime); } } void SetDeltaTime(float dt) { m_deltaTime dt; } private: PhysicsWorld m_world; int m_start, m_end; float m_deltaTime; }; // 在主循环中创建任务 void Game::SubmitLogicTasks(TaskScheduler* scheduler) { int numBodies m_physicsWorld.GetBodyCount(); int groupSize numBodies / 4; // 假设分4组并行 std::vectorstd::unique_ptrGameTask physicsTasks; for (int i 0; i 4; i) { int start i * groupSize; int end (i 3) ? numBodies : start groupSize; auto task std::make_uniquePhysicsTask(m_physicsWorld, start, end); task-SetDeltaTime(static_castfloat(m_tickInterval)); physicsTasks.push_back(std::move(task)); } // 创建一个碰撞检测任务依赖所有PhysicsTask auto collisionTask std::make_uniqueCollisionDetectionTask(m_physicsWorld); for (auto pt : physicsTasks) { collisionTask-AddDependency(pt.get()); scheduler-SubmitTask(std::move(pt)); } scheduler-SubmitTask(std::move(collisionTask)); }4.2 AI与动画系统的异步更新非玩家角色NPC的AI决策如行为树遍历、寻路请求也可以任务化。寻路等耗时操作可以设计成异步任务在它计算的同时渲染和其他逻辑照常进行。动画系统的状态更新根据速度、状态机计算骨骼权重同样可以并行处理多个模型。4.3 渲染命令的生成与提交这是提升帧率最立竿见影的地方。我们将渲染分为两个阶段RenderSubmissionTask渲染提交任务: 遍历场景图收集渲染指令Draw Call填充到渲染命令队列中。这个任务依赖本帧所有逻辑任务特别是变换更新任务的完成。RenderPresentTask渲染呈现任务: 将命令队列提交给GPU并执行缓冲区交换Swap Buffers。这个任务在GPU端执行CPU几乎不阻塞。关键在于RenderSubmissionTask完成后CPU就可以立即开始准备下一帧的逻辑或渲染数据而不用等待GPU完成RenderPresentTask。这就是经典的“CPU-GPU并行流水线”。// 伪代码展示双缓冲渲染命令队列 class RenderCommandQueue { std::arrayCommandBuffer, 2 m_buffers; int m_currentBufferIndex 0; std::atomicbool m_buffersReady[2] {false, false}; public: CommandBuffer GetCurrentBuffer() { return m_buffers[m_currentBufferIndex]; } void SwapAndSubmit() { int submittingBufferIndex m_currentBufferIndex; m_currentBufferIndex (m_currentBufferIndex 1) % 2; // 标记当前Buffer已就绪可供GPU消费 m_buffersReady[submittingBufferIndex] true; // 异步通知渲染线程/API去提交 submittingBufferIndex 的命令 SubmitToGPUAsync(submittingBufferIndex); } bool IsBufferReadyForCPU(int index) { return !m_buffersReady[index]; } }; // 在RenderSubmissionTask中 void RenderSubmissionTask::Execute() { auto cmdBuffer m_renderQueue.GetCurrentBuffer(); cmdBuffer.Reset(); // ... 填充渲染命令到cmdBuffer // 完成后由主循环调用RenderCommandQueue::SwapAndSubmit() }通过这种方式CPU和GPU像流水线上的两个工人交替处理不同的数据缓冲区极大地减少了空闲等待。5. 性能对比、调试与常见陷阱在我自己的2D动作游戏原型上实施上述优化后性能数据对比如下场景描述传统单线程循环 (FPS)Coze-Loop风格重构后 (FPS)CPU核心利用率 (峰值)空旷场景100个静态物体6262 (VSync限制)25% - 30%复杂场景1000个动态物理物体41-55 (剧烈波动)58-60 (稳定)65% -85%同场景额外触发大量AI寻路28-35 (严重卡顿)52-58 (轻微波动)90% -95%实测心得帧率提升最明显的场景恰恰是那些逻辑计算物理、AI负载重但GPU压力不大的场景。优化后逻辑计算被平摊到多个核心以及更长的周期30Hz Tick内给渲染线程留出了更多连续的执行时间从而稳定了帧时间。GPU受限的场景如大量粒子特效、复杂后期处理提升可能不明显但CPU端的卡顿感会显著减轻。5.1 必须面对的挑战与陷阱数据竞争与同步多线程任务化最大的敌人。当物理任务和动画任务同时读写同一个物体的变换矩阵时就会出问题。解决方案严格区分“只读”和“读写”数据。为每个逻辑Tick使用双缓冲或三缓冲的游戏状态。写入方总是写入“下一帧”缓冲区读取方渲染任务读取“上一帧”已完成的缓冲区。这需要精细的内存序std::memory_order或锁来控制。对于简单的标量原子操作就足够了。任务依赖管理复杂手动管理几十上百个任务的依赖关系极易出错。建议不要过度设计。初期可以按粗粒度划分任务如“所有物理更新”、“所有AI更新”、“所有动画更新”、“渲染提交”。使用现成的任务图Task Graph库如enkiTS或Intel的 TBB 它们能帮你自动处理依赖和调度。插值Interpolation带来的额外开销与精度问题渲染帧基于两个逻辑Tick的状态进行插值意味着每个渲染帧都需要为每个运动的物体计算插值位置。这会增加一些CPU计算量。同时对于高速运动的物体线性插值可能产生视觉上的“抖动”或“穿越”现象。解决方案a) 确保逻辑Tick的频率足够高通常30Hz对大多数游戏足够。b) 对于特别高速的物体如子弹可以采用“客户端预测”或“航位推测法”Dead Reckoning或者在渲染时使用更精确的插值方法如考虑加速度的二次插值。调试与Profiling困难当逻辑分散在多个线程中传统的单步调试变得几乎不可能。必须依赖强大的性能分析工具CPU Profiler使用Visual Studio Profiler、VerySleepy、Intel VTune等工具查看每个任务、每个函数的耗时找到新的热点。Frame Debugger使用RenderDoc、PIX等图形调试器确保渲染命令的提交顺序和内容正确。自定义性能计数器在代码中插入高精度计时器记录每个任务、每个阶段的耗时并实时显示在游戏画面上。5.2 一个典型的性能问题排查流程假设优化后在某个特定场景帧率反而下降了。第一步用Profiler抓取一帧。发现RenderSubmissionTask耗时异常高。第二步深入该任务。发现是场景中某个特定类型的物体比如带有复杂骨骼动画的角色在提交渲染数据时进行了大量的矩阵运算。第三步分析原因。因为逻辑和渲染分离渲染任务需要为每个角色基于两个逻辑Tick的骨骼姿势进行插值这个插值计算是串行的成了瓶颈。第四步优化。将骨骼插值计算也并行化为每个角色或每组建一个BoneInterpolationTask并入调度器。或者探索是否可以使用GPU Skinning将插值计算完全卸载到GPU。6. 进阶思考与现有引擎架构的适配你可能会问如果我在用Unity或Unreal Engine还需要自己搞这套吗答案是不需要但理解它有助于你更好地使用引擎。像Unreal Engine其内部早已实现了复杂的多线程任务系统Task Graph系统和游戏线程/渲染线程的分离。Unity的DOTS面向数据的技术栈和Job SystemBurst Compiler其核心思想也是将工作拆分为可并行的小任务并进行高效调度。你使用Unity Jobs或Unreal Async Task时本质上就是在应用类似Coze-Loop的思想。对于自研引擎或深度定制的大型项目直接借鉴Coze-Loop的思想来设计核心循环会让你对性能的掌控力达到一个新的高度。你可以根据项目特点定制调度策略如优先级调度、资源感知调度甚至实现动态的任务粒度调整在负载高时拆分更细的任务以利用更多核心负载低时合并任务以减少调度开销。最后记住一点没有银弹。Coze-Loop模式不是万能药它引入了复杂性。对于小型项目或原型传统的单线程循环可能更简单高效。但当你的游戏世界变得复杂帧率成为瓶颈时这种基于任务和调度的、解耦的架构将是通往60帧乃至144帧稳定体验的坚实桥梁。优化的过程就是不断寻找CPU与GPU、逻辑与渲染、性能与复杂度之间那个最佳平衡点的过程。从我实战的结果来看为游戏主循环引入Coze-Loop的思想是一次非常值得的投入。

相关新闻

2026年降AI率工具测评:8款哪个最值得用

2026年降AI率工具测评:8款哪个最值得用

知网、维普相继升级AIGC检测功能之后,论文降AI率成了毕业季绕不开的环节。这半年陆续试了市面上八款主流工具,从生成逻辑、改写质量到实际处理效果逐一做了对比,下面把实测过程中的真实差异写出来。 为什么今年降AI率成了刚需 高校对AIGC检…

2026/10/17 21:02:50 阅读更多 →
现代进销存系统为什么也需要做多国语言支持?

现代进销存系统为什么也需要做多国语言支持?

进销存系统做多语言支持,核心是服务全球化与跨地域协同。外贸、跨境电商、海外仓及跨国制造等企业,员工、供应商、客户分处不同语种环境,单语系统会引发录单歧义、库存状态误读、单据来回翻译等低效与错漏。 多语言支持让员工用母语操作降培训…

2026/10/17 21:02:35 阅读更多 →
开源社区协作模式与开源项目维护经验:选型别只看功能清单

开源社区协作模式与开源项目维护经验:选型别只看功能清单

开源社区协作模式与开源项目维护经验:选型别只看功能清单 选择图表等前端依赖时,功能清单、Star 数和演示效果只能提供初步信号,不能代表库在长期使用中的维护成本。 例如,频繁切换视图时未释放 DOM 节点或事件监听器,…

2026/10/18 12:24:14 阅读更多 →

最新新闻

如何重建 reference_only 语料?humanizer-data 重建脚本 rebuild_reference_only.py 源码深度剖析

如何重建 reference_only 语料?humanizer-data 重建脚本 rebuild_reference_only.py 源码深度剖析

【免费下载链接】humanizer-data 项目地址: https://ai.gitcode.com/hf_mirrors/jialinyyzz/humanizer-data 点击查看 免费下载 humanizer-data 是为 12B 文本重写模型 humanizer v2 准备的训练语料集,其中 reference_only 分片因版权限制不含原文文本。…

2026/10/19 0:56:09 阅读更多 →
如何加速机器人评测:EasyWAM-Unified-Cosmos25 多卡分布式部署与调优教程

如何加速机器人评测:EasyWAM-Unified-Cosmos25 多卡分布式部署与调优教程

【免费下载链接】EasyWAM-Unified-Cosmos25 项目地址: https://ai.gitcode.com/OpenMOSS/EasyWAM-Unified-Cosmos25 点击查看 免费下载 EasyWAM-Unified-Cosmos25 是 OpenMOSS 基于 Cosmos-Predict2.5-2B 发布的 World-Action Model 评测检查点仓库,配合…

2026/10/19 0:56:09 阅读更多 →
2026年远控软件市场六大主流产品对比与选型指南

2026年远控软件市场六大主流产品对比与选型指南

干远控这行久了,每年年底都要把市面上主流产品拉出来过一遍,看技术走向、看打法变化。2026年的这份答卷,变化比我预想的要大。前几年大家聊远程控制,张口闭口都是“能不能连上”“快不快”,现在所有人问的是“连得稳不…

2026/10/19 0:55:09 阅读更多 →
基于单片机的门禁系统设计:从硬件选型到状态机实现

基于单片机的门禁系统设计:从硬件选型到状态机实现

简介:这份资源是一篇完整的学位论文文档,主题为基于单片机的门禁系统设计,面向计算机、电子信息及自动化相关专业的本科生与研究生,可用于毕业设计选题参考、课程设计借鉴或论文写作模板学习。文档围绕写字楼安全管理场景&#xf…

2026/10/19 0:55:09 阅读更多 →
天然气管道内检测机器人检测节设计:漏磁检测、图纸与说明书

天然气管道内检测机器人检测节设计:漏磁检测、图纸与说明书

做天然气管道内检测机器人,最容易被外行低估的就是“检测节”这个部分。很多人以为检测节就是一根芯轴加一圈传感器探头,等真正动手画图、出三维、写说明书的时候才发现:既要保证漏磁信号采集质量,又要整套设备在管道里跑得过去、…

2026/10/19 0:54:08 阅读更多 →
天地图API开发实战:源码解析、密钥配置与WMTS瓦片加载

天地图API开发实战:源码解析、密钥配置与WMTS瓦片加载

简介:面向 Vue 前端开发者的一套天地图 API 完整源码示例包,基于 Element Plus UI 框架构建地图应用,系统演示了从初始化地图、点标记管理、位置搜索、距离测量到卫星/地图切换、全屏显示等核心交互功能的完整编码流程,适合需要快…

2026/10/19 0:54:08 阅读更多 →

日新闻

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

简介:本资源为电源技术方向的学术研究文档,聚焦介质阻挡放电型臭氧发生器电源的频率跟踪型PWM控制策略,面向电力电子、高压电源及臭氧应用领域的科研人员与工程技术人员。针对负载呈容性、等效电容随外加电压升高而增大、谐振频率随之漂移的难…

2026/10/19 0:00:47 阅读更多 →
Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 0:00:47 阅读更多 →
HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

【免费下载链接】HundredCV-Chat 项目地址: https://ai.gitcode.com/hf_mirrors/Jax-dan/HundredCV-Chat 点击查看 免费下载 HundredCV-Chat 是一个由 100 位青年简历数据开发而来的中文多轮对话数据集,共包含 24,750 组日常闲聊对话和 4,871 个话题标签…

2026/10/19 0:00:47 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 0:55:02 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →