
Primitive 算法原理详解为什么逐形状贪心爬山法能一步步逼近目标图像【免费下载链接】primitiveReproducing images with geometric primitives.项目地址: https://gitcode.com/gh_mirrors/pr/primitivePrimitive 是一个用 Go 语言编写的图像重绘工具它把一张照片当作目标图像只用三角形、矩形、椭圆等几何图元geometric primitives一个形状一个形状地往画布上叠最终拼出一张既像原作又极具艺术感的抽象画。整套算法的精髓就是两句话逐形状贪心每次只挑误差下降最多的那个形状爬山法对候选形状反复微调只接受变好的改动。本文带你从第一性原理出发看懂它为什么能一步步逼近目标图像。1. 算法总览一局每次只走一步的贪心游戏把整条流水线拆开只有四个角色角色作用对应实现目标图像Target我们要逼近的原图primitive/model.go 中的Target当前图像Current已画好的画布初始为纯色primitive/model.go 中的Current候选形状Shape待评估的几何图元primitive/shape.go 的Shape接口得分Score当前图像与目标的均方根误差 RMSEprimitive/core.go 的differenceFull初始化时画布被填充为目标图像的平均颜色NewModel中通过uniformRGBA完成此时误差就是起点。之后进入主循环找到能让误差下降最多的单个形状 → 把它画上去并永久固定→ 重新找下一个形状 → 重复 N 次这就是逐形状贪心不把几十个形状放在一起做联合优化而是每一步都做出局部最优的落笔决策。50~200 个形状后画面就能达到可辨识但抽象的效果——这正是该算法的艺术风格来源。形状落笔的动作在 primitive/model.go 的Add方法中光栅化形状、计算颜色、绘制、更新得分一气呵成。2. 得分标准用 RMSE 当眼睛算法每一步都要回答这样改画了吗。Primitive 使用**均方根误差RMSE**作为得分对两个图像的每个像素求颜色差的平方和、取平均再开方值越小越接近目标。一个关键提速技巧藏在 primitive/core.go 的differencePartial里部分图像差分。加了一个形状后只有形状覆盖到的像素发生了变化其余像素的误差贡献不变。因此不需要重新比较整张图只需新总分 旧总分 - 变化区域的旧误差 变化区域的新误差这让每次试画一个形状的代价从 O(全图像素) 降到 O(形状面积)是贪心爬山能跑上千次评估的关键。3. 爬山法对同一个形状反复微调-取舍贪心解决了选哪个形状爬山法Hill Climbing则解决把这个形状调成什么样。核心循环在 primitive/optimize.go 的HillClimb中逻辑极其朴素变异随机微调形状的一个参数——比如把三角形某个顶点挪几像素、改椭圆的半径或中心三角形变异的实现见 primitive/triangle.go评估重新计算 RMSE 得分取舍得分变好就保留否则回滚到上一个状态只要还在进步就继续循环直到连续多轮都没有改进。这就是爬山的由来把误差想象成地形算法只沿着下坡方向走。它天生容易卡在山谷里局部最优别急——下一节就是对策。 为什么不用模拟退火primitive/optimize.go 里其实也实现了Anneal但作者实测发现多组随机起点 爬山效果与退火相当、速度却更快所以默认走爬山路线。4. 多起点 并行 Worker对抗局部最优单次爬山只能保证找到附近的好形状Primitive 用两层赛马机制来逼近全局最优实现在 primitive/worker.go随机起点赛马先随机生成n个候选形状各打一次分留下最好的那个再开始爬山——避免从一个糟糕起点出发并行 Worker 赛马每个 CPU 核心是一个 Worker见 primitive/model.go 的runWorkers各自独立执行随机起点 爬山最后跨 Worker 取得分最低者落笔。一句话总结单次爬山是一条路走到黑多起点并行是同时派很多人探路谁走得顺听谁的。随机性也因此成为特性而非缺陷——对同一张图重复运行会生成不同但都好看的版本。5. 隐藏巧思颜色不优化直接算出通常形状 颜色要一起搜索维度会翻倍。Primitive 的 primitive/core.go 中computeColor给了一个优雅的捷径给定形状的位置和覆盖区域使误差最小的颜色存在闭式解——只需对该区域像素做一次加权平均即可直接算出最优 RGB。于是搜索空间只剩形状几何参数颜色永远免费且最优。另外注意 primitive/triangle.go 的Valid约束三角形任意内角不得小于 15°防止爬山法把形状爬成细线或退化图形。6. 原理如何映射到参数看懂主循环再动手主循环在 main.go读入图像 → 缩放到处理尺寸 → 每调用一次model.Step就贪心落笔一次 → 写输出。常用参数对应关系参数默认对应原理-n必填贪心迭代次数即总共画多少个形状-m1三角形选择哪种几何图元-a128形状透明度设为 0 则让算法连透明度一起爬-j全部核心并行 Worker 数直接决定赛马规模-r/-s256 / 1024处理尺寸 / 输出尺寸处理越小跑得越快7. 小结为什么这套组合能一步步逼近贪心保证每一步都是当前最优的落笔误差曲线单调下降永不画后悔的形状爬山让每个形状落笔前都被充分打磨而非随机摆放多起点 并行用随机性跳出局部最优用算力换质量RMSE 部分差分 颜色闭式解把单次评估压到极低成本让上千次试探变得可行。四个机制环环相扣搜索空间大 → 用并行赛马单次评估贵 → 用差分量与闭式解单点易陷局部最优 → 用随机起点。理解了这套结构你就能明白为什么几十到几百个最简单的几何图元足以逼近一张复杂照片 【免费下载链接】primitiveReproducing images with geometric primitives.项目地址: https://gitcode.com/gh_mirrors/pr/primitive创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考