Unity批量处理图片像素:从去白边到像素化的编辑器工具方案

开发Unity项目时,天天和美术资源打交道,免不了碰上“这一批图片都要处理一下”的需求。尤其是像素级的修改:UI图标统一加一圈描边、角色立绘的白边要批量抠掉、凑齐一整套序列帧图片做像素化风格化。一张一张交给Photoshop用动作批处理倒是也行,但图一多、格式一杂,半路就断,而且处理完之后还得手动调整导入参数,流程极其磨人。我这几年的经验是,与其来回点鼠标,不如直接在Unity里写一套批量处理图片像素的工具,把滤镜逻辑、导入设置、格式转换一次性解决。这套思路在多个模拟项目里验证过,能处理几十张到上千张图片,这篇就把完整方案拆开讲清楚。

1. 工具立项:什么情况需要自己写一套图片像素批处理

1.1 从三个真实需求说起

先说几个我在实际开发中反复踩过、最后催生出这套工具的场景。

第一个是批量去白边。项目里有一批素材是从设计稿直接导出的角色立绘,每张图的角色边缘都带着一圈半透明的白色光晕,放到深色背景上非常明显。用手工一张张处理,先不说要数几十张图,光是“边缘羽化到什么程度”这个标准就很难统一。用脚本处理就很简单:遍历像素,把满足“高亮度+高不透明明度”条件的像素转成完全透明,再对边缘做一层柔化,效果统一且可重复。

第二个是批量像素化。玩法侧需要一个“复古像素”版本的角色贴图,原图全是高清立绘,美术没有时间重绘。这时候脚本派上用场:按固定块大小做降采样,取每个块的平均色回填,把整张图变成马赛克风格。换个参数就能控制像素颗粒大小,从8x8到32x32各出一版,美术看了也能快速定方向。

第三个是透明通道修复。从某些渠道拿到的图集,透明边缘经常带一圈“黑边”,原因是原图的RGB通道在透明区域里是黑色,半透明边缘处RGB和Alpha混合后产生了暗边。修复思路是把半透明像素的RGB往白色方向拉伸,或者直接把RGB改为不依赖边缘的预乘结果。这种批量修复靠肉眼在Photoshop里找出每一处,基本不现实。

1.2 为什么不用Photoshop批处理而要在Unity里写

很多人第一反应是:图片处理不应该用Photoshop的Action功能吗?确实,简单需求用PS动作没问题,但有几个瓶颈在项目里很致命。

一是动作脚本对“透明通道”的处理笨重。PS的动作录制做不到“遍历每个像素并判断其颜色再决定要不要改”,它更多是录制菜单操作。透明边缘的白边、黑边修复,本质是像素级逻辑判断,能录成动作的概率很低。

二是导入参数脱节。PS处理完图片后,还得回到Unity里重新设置纹理格式、是否可读写、压缩类型。如果处理完的图片有透明通道变化,旧的导入设置还可能导致显示效果不对。在Unity脚本里处理,可以在保存图片的同时顺手改掉导入器配置,整个流程闭环。

三是批量规模和数据管理。PS的批处理对上千张图的目录结构管理并不顺手,脚步一多还容易漏。用Unity编辑器扩展写一个独立窗口,把文件夹拖进去,自动列出图片、执行算法、输出统计日志,整个过程可控可撤销可重跑。

1.3 这套工具的设计目标

基于上面这些需求,我给工具的定位是“一个可扩展的像素处理工作台”。核心设计目标有四条:

  • 批量加载:支持选中文件夹或者拖入若干图片,自动列出所有纹理资源。
  • 统一滤镜:把去边、像素化、调色这类算法封装成独立模块,互不干扰。
  • 安全保存:处理前自动备份,处理中记录失败项,处理后给完整统计。
  • 管线衔接:处理完直接调整导入设置,还原到可用状态,不用再手动碰导入面板。

2. 原理与前置条件:读懂Unity的纹理数据流

2.1 Texture2D与像素数组的关系

Unity里的Texture2D本质是一块显存/内存中的图像数据,它不会直接把每个像素暴露给开发者操作。要读取像素,必须调用GetPixels或者GetPixels32这两类接口。

GetPixels返回Color[],每个Color分量是float,好处是精度高,坏处是体积大、转换慢。一张1024x1024的图,Color[]要占16MB左右的内存,遍历起来还有float到byte的转换开销。GetPixels32返回Color32[],每个分量是byte,四个分量正好对应RGBA,内存占用只有Color[]的四分之一,速度也快得多。做像素批处理,我基本只推荐GetPixels32。

理解了读取,修改就顺理成章。拿到数组后,按索引算像素坐标:第y行第x列的像素下标是y*width+x。因为Unity纹理的坐标原点在左下角,而文件流(PNG/JPEG)的坐标原点在左上角,如果没有特殊需求,单纯做整图滤镜不需要关心翻转问题,但如果你要对某个具体坐标做局部操作,这个差异就会冒出来。

2.2 纹理压缩格式与可读写开关是最大的坑

Unity对纹理有完整的导入管线,默认情况下很多图片导入后被压缩成ASTC、ETC、PVRTC这类GPU压缩格式。直接对压缩纹理调用GetPixels32会直接报错,错误信息一般是“Texture 'xxx' is not readable”。原因有两个层面:压缩格式本身不支持随机读取像素,同时导入设置里的Read/Write选项默认是关闭的。

解决方案有三种:

  • 在导入设置里勾选Read/Write Enabled,并把格式改成RGBA32。优点是省事,缺点是所有纹理都会变大一倍,运行时内存也会涨。
  • 使用Texture2D.LoadImage从原始文件字节流重新创建纹理。这个接口会忽略原有压缩格式,内部强制转成RGBA32,且创建出的纹理默认可读。缺点是只支持PNG和JPEG源文件。
  • 在代码里修改TextureImporter配置,SaveAndReimport后再加载。适合希望处理完之后还保持原有管线设置的场景。

我比较推荐的组合是:创建新Texture2D,通过File.ReadAllBytes配合LoadImage加载原文件做像素操作,最后用EncodeToPNG写回。这样不会污染原有导入管线,内存占用也可控。

2.3 编辑器脚本的框架搭建

这套工具以编辑器扩展的形式存在,不参与运行时逻辑。核心是三个部分:菜单入口、独立窗口、算法模块。

菜单入口用MenuItem特性挂在主菜单栏,比如“Tools/Pixel Batch Processor”。独立窗口继承EditorWindow,在里面放路径选择、参数配置、执行按钮。算法模块是最需要花心思的部分:因为图片数量大、参数可调,我会把“遍历像素”和“修改像素”分离开,做成类似滤镜管线的方式。

public interface ITextureFilter { Color32[] Process(Color32[] pixels, int width, int height, FilterParams param); }

每个滤镜实现这个接口,BatchProcessor只负责按顺序调用。这样后续加新风味滤镜、新算法模块,完全不用动批量框架本身。

3. 核心代码:批量读取与像素遍历的实现

3.1 批量加载文件夹内所有纹理

批量处理的第一步是把“哪几张图要处理”确定下来。我采用AssetDatabase.FindAssets搭配“t:Texture2D”类型过滤,传入目标文件夹路径,拿到所有纹理的GUID,再转成资产路径并加载。这样能保证拿到的是工程内真实存在、已经过导入管线的资源。

string[] guids = AssetDatabase.FindAssets("t:Texture2D", new string[] { folderPath }); foreach (string guid in guids) { string assetPath = AssetDatabase.GUIDToAssetPath(guid); Texture2D tex = AssetDatabase.LoadAssetAtPath<Texture2D>(assetPath); // 这里做类型、读权限、格式的检查 }

这里有个很容易忽略的点:FindAssets结果里会包含Sprite、SpriteAtlas等继承自Texture2D的资产,还有可能把图集里的子图也算进来。进队列之前,最好判断一下资产路径的后缀名是否为.png、.jpg或.jpeg,否则会出现处理到一半发现“这个文件不是直接图片”的尴尬情况。

3.2 读取像素与快速遍历的写法

拿到Texture2D引用后,用GetPixels32取像素数组。但要注意,如果原纹理的压缩格式不是RGBA32,直接取会报错。稳妥做法是先把原图字节读出来,通过LoadImage重新解析成可读纹理,再取像素。

byte[] rawBytes = File.ReadAllBytes(assetPath); Texture2D tempTex = new Texture2D(2, 2, TextureFormat.RGBA32, false); if (!tempTex.LoadImage(rawBytes)) { Debug.LogError("读取失败: " + assetPath); continue; } Color32[] pixels = tempTex.GetPixels32(0); int width = tempTex.width; int height = tempTex.height;

随后遍历像素。这里推荐用一维数组从头到尾扫,不要用双重循环。原因是索引计算更简单,缓存命中率也更高。双重循环里每行都要重新算y*width,在超大图上会平添不必要的整数乘法开销。

for (int index = 0; index < pixels.Length; index++) { Color32 c = pixels[index]; // 在这里无差别遍历所有像素,再按滤镜需求修改 pixels[index] = c; }

如果你的滤镜逻辑需要知道当前像素的坐标,用先算好y再算x的方式:

for (int y = 0; y < height; y++) { int rowOffset = y * width; for (int x = 0; x < width; x++) { int index = rowOffset + x; // 此时 x = index % width, y = index / width } }

3.3 把处理结果写回纹理并保存

像素数组处理完之后,要分两条路保存。如果只是想在编辑器里预览效果,用SetPixels32配合Apply即可;如果要落地成文件,就得EncodeToPNG转字节再写盘。

tempTex.SetPixels32(0, pixels); byte[] outPng = tempTex.EncodeToPNG(); string savePath = targetFolder + "/" + fileName + "_processed.png"; File.WriteAllBytes(savePath, outPng);

EncodeToPNG只能输出PNG格式,好处是无损且支持透明通道。JPEG格式不支持透明通道,像素批处理场景下基本不考虑。

写完后必须调AssetDatabase.ImportAsset刷新资源数据库。这个步骤经常被忽略,导致保存的PNG不会立刻出现在工程里,需要手动刷新窗口。

AssetDatabase.ImportAsset(savePath);

如果要追求流程闭环,在ImportAsset之前顺便改掉导入参数:

TextureImporter importer = (TextureImporter)TextureImporter.GetAtPath(savePath); importer.textureType = TextureImporterType.Sprite; importer.textureCompression = TextureImporterCompression.Uncompressed; importer.SaveAndReimport();

4. 三个实际能直接用的滤镜功能模块

4.1 批量去除白边与透明化处理

去除白边是处理立绘和UI图标时最高频的需求。原理很简单:检测像素RGB是否都接近白,同时Alpha足够高,判定为“残留白边”,把这部分像素的Alpha改成0。但直接一刀切会让边缘出现锯齿,所以算法要分两步。

第一步是全图扫描,找出“需要完全变透明”的像素。第二步是羽化:对透明区域的边缘做一次膨胀处理,把边缘像素的Alpha按距离衰减。

private Color32[] RemoveWhiteEdge(Color32[] src, int w, int h, float threshold) { Color32[] result = new Color32[src.Length]; for (int i = 0; i < src.Length; i++) { Color32 c = src[i]; bool isWhite = c.r > threshold * 255 && c.g > threshold * 255 && c.b > threshold * 255 && c.a > 128; if (isWhite) { c.a = 0; } result[i] = c; } return result; }

实际项目里,阈值参数一般给0.85到0.95之间。阈值太大会漏掉淡白色边缘,太小会把皮肤的高光区域也删掉。处理完透明化之后,建议再做一次简单的边缘检测:如果一个像素是透明、相邻像素是不透明,就把这个像素做50%的Alpha。这样整个边缘看起来是渐变消失的,不会突然断掉。

4.2 批量像素化风格化处理

像素化这个效果的核心是“均匀分块+块内降采样”。把原图分成若干个方块,每个方块内所有像素的颜色取平均,然后用这个平均色填充整个方块。块大小决定了像素颗粒的粗细,8代表8x8像素一块,图面小一点的话16甚至32都能做出明显的复古感。

private void ApplyPixelize(Color32[] src, int w, int h, int blockSize, Color32[] dst) { for (int blockY = 0; blockY < h; blockY += blockSize) { for (int blockX = 0; blockX < w; blockX += blockSize) { Color32 avg = AverageBlock(src, w, h, blockX, blockY, blockSize); FillBlock(dst, w, h, blockX, blockY, blockSize, avg); } } }

取平均色时要注意Alpha通道的处理。如果Alpha不一致,直接平均会导致半透明区域混入奇怪的RGB值。我的做法是只对Alpha大于0的像素做RGB平均,并把该块Alpha设为255;完全透明的块直接设成全透明黑色。这样输出的像素风图在叠加到背景上时不会出现脏色块。

4.3 批量颜色替换与色调调整

颜色替换不一定是像素级匹配,更实用的是基于色调范围做替换。先把RGB转成HSV,判断色相是否落在目标区间内,再替换成新颜色的同时保留原来的饱和度和明度。这样处理人物衣服换色、图标配色切换特别方便。

private Color32 ReplaceHue(Color32 src, float targetHue, float hueRange, Color32 newColor) { // 把src转成HSV,取H分量 // 如果H在 targetHue ± hueRange 内,则用newColor替换 // 保留原明度V,必要时调整饱和度S }

色调调整则更简单:每个像素的RGB按比例缩放。想偏暖就R乘1.1、B乘0.9;想提亮就整体加一个固定值。因为Color32是byte结构,运算时先转int,做完后Clamp到0-255再回写,防止溢出。

5. 导入设置、导出命名与资源管线衔接

5.1 处理前后自动调整导入参数

处理完图片后,如果新输出的图片仍然沿用老的导入配置,很可能看不到预期效果。例如原图是压缩格式,新图改成RGBA32后体积变大,压缩参数不变,Unity会在导入时再次压缩,导致透明边缘被压出色斑。

我的做法是在保存后直接改TextureImporter:

TextureImporter importer = (TextureImporter)TextureImporter.GetAtPath(savePath); importer.isReadable = true; importer.textureCompression = TextureImporterCompression.Uncompressed; importer.filterMode = FilterMode.Bilinear; importer.SaveAndReimport();

如果这张图是准备交给美术继续手绘的底图,建议把压缩类型设为Uncompressed;如果最终会进游戏包体,等应用侧确认效果后再手动调回合适的压缩格式即可。

5.2 输出目录与命名策略

批处理最怕处理完不知道哪些是原图、哪些是结果。我建议默认输出到目标文件夹下的“_processed”子目录,文件名保持原名字后缀加上处理标记。比如原图叫icon_attack.png,输出叫icon_attack_px.png或者icon_attack_clean.png。

这样做还有一个好处:重复执行滤镜不会把处理结果再处理一遍。如果你把输出和原图放同一个目录,第二次跑批处理时,FindAssets会把上一次的输出也抓进来,导致效果叠加。加子目录之后,在过滤逻辑里排除带有_processed路径的结果即可。

if (assetPath.Contains("_processed")) continue;

5.3 与构建流程的衔接

批处理工具最适合放在资源入库阶段使用。美术资源合入工程之前先跑一遍统一处理,确认效果后再提交到版本库。这样构建流程里不会出现“开发时看到一套图、打包出来另一套图”的问题。

如果在管线里接自动化,可以把工具暴露成静态方法,用命令行参数调用。Unity的编辑器模式支持-executeMethod执行指定静态方法,批处理逻辑只要能脱离编辑器窗口独立运行,就能接入持续集成流程。我在模拟项目X里就这么做过:每晚对全部新增图片自动执行透明边缘清理,第二天美术上班只需要抽查结果。

6. 实战踩坑清单与性能优化

6.1 导致批处理中断的常见报错

报错信息出现原因解决办法
Texture not readable纹理导入设置未开启Read/Write用LoadImage读取原文件字节,或修改导入器配置
LoadImage failed for path源文件不是PNG/JPEG格式跳过该文件,或在加载前先检查扩展名
Cannot access a destroyed objectTexture2D被在遍历中被销毁批量处理时复用Texture2D实例,不要每张图都new再销毁
Out of memory一次性加载过多大图分批处理,每批处理完调用Resources.UnloadUnusedAssets
Apply() was not called修改了像素数组但没有执行ApplySetPixels32之后务必调用Apply

比较隐蔽的是“Cannot access a destroyed object”这个报错。我在早期版本里对每张图片都新建Texture2D,用完立即Destroy,结果批处理跑到一半,前一张图的引用还没释放,后一张图突然访问失败。后来改成固定复用两个Texture2D实例:一个用于LoadImage读入,一个用于SetPixels输出,全程不销毁,批量结束再统一释放,问题就消失了。

6.2 让1024平方的遍历速度翻倍

像素遍历本身是纯CPU计算,慢的原因通常出在内存分配和颜色转换上。三个优化手段实测效果明显。

第一,用GetPixels32而不是GetPixels。这个前面说过,16MB变4MB,分配速度能差三倍以上。

第二,避免在循环体里创建临时对象。比如不要每遍历一个像素都new一个Color32,而是用局部变量暂存,最后只往数组里写一次。C#的GC在小循环里不敏感,但上百万像素时,频繁分配会触发多次垃圾回收,一次回收卡几十毫秒,累计起来非常可观。

第三,如果对速度要求极高,可以启用unsafe代码块,直接用指针遍历Color32数组。这种写法能绕过数组边界检查,实测能再快20%到30%。代价是需要在Player Settings里开启Allow unsafe Code,而且代码可读性差一截。我一般只在有极端性能需求或大图批量处理时才用,日常滤镜用普通for循环完全足够。

6.3 千张图实测结果与分批建议

在一台普通配置的开发机上,用上面这套方案批量处理1024x1024的PNG图片,单张图片的完整链路大约是:LoadImage约20到35毫秒,GetPixels32约5到10毫秒,像素遍历约10到30毫秒(取决于滤镜复杂度),SetPixels32加EncodeToPNG约40到70毫秒,写入文件另算。一张图加总起来平均在100到150毫秒之间,一千张图大概两分钟出头。

两分钟看起来不长,但等待期间Unity主线程被阻塞,没法做别的事情。而且如果滤镜误判导致输出全黑,跑完两分钟才发现,返工成本偏高。所以我的建议是分三步走:先选3到5张有代表性的图片试跑,确认输出无误;再按文件夹批量处理;最后抽查10%的结果。

批量处理的时候可以用EditorApplication.update结合进度条做异步调度,每处理完一张就刷新一次界面,这样至少能知道卡在哪。懒人方案是直接用EditorUtility.DisplayProgressBar做假的进度轮询,代码量少,但Unity反馈窗口会卡住,只适合几十张图的小批量。

如果处理上千张图,我建议拆成几批,每批200到300张,处理完一批释放资源,然后继续下一批。这样可以规避单次内存峰值过高导致的崩溃。也可以用FixedUpdate循环来做排队,而不是一口气把所有图读进内存再处理。这一点在低配机器上尤其重要。

写到最后再说两句

我在实际开发里把这套工具前前后后改了三个版本。第一版很粗糙,功能写死,只解决当时那一个去白边的问题;第二版加了滤镜接口和进度条,能应对几个重复出现的需求;第三版才把导入设置、备份机制和批量统计补齐,真正做到“丢一个文件夹进去,出来全部处理完”。这套东西最有价值的不是某个滤镜算法,而是“让Unity自己处理自己的资源”的思路。图片进入Unity之后,它就不再是静态的素材文件,而是可以被代码检查和修改的资产,这个思路能延伸出很多省力的工具。每次接到新的图片处理需求,先想想能不能用脚本批量做,哪怕只省下半小时,累积起来也相当可观。

相关新闻

本地AI模型实测:从代码调试到长文摘要的选型与部署参考

本地AI模型实测:从代码调试到长文摘要的选型与部署参考

我平时离不开一个叫 Jev 的在线 AI 助手&#xff1a;写周报、改邮件、查代码、翻会议纪要&#xff0c;几乎天天都在用。用了大半年以后&#xff0c;我决定试试“把 Jev 搬到本地”这条路&#xff0c;也就是用四个本地模型做一轮实际场景测评&#xff0c;看看原来云端那套工作流…

2026/10/20 16:39:33 阅读更多 →
Flink Table API 有界无界窗口实战:从语法到水位线避坑指南

Flink Table API 有界无界窗口实战:从语法到水位线避坑指南

之前在一个零售数据平台项目里&#xff0c;我经常要同时搞定两套统计逻辑&#xff1a;白天用实时任务统计每小时的订单流水&#xff0c;深夜还要把一整天的订单文件重新算一遍出日报。最开始的方案是流批两套代码分开维护&#xff0c;结果改一次指标口径要动两个地方&#xff0…

2026/10/20 16:39:33 阅读更多 →
从提示词到技能包:AI编程新手与资深开发者都该了解的SkillSpace实战指南

从提示词到技能包:AI编程新手与资深开发者都该了解的SkillSpace实战指南

最近AI编程圈里大家讨论最多的一个词&#xff0c;除了Agent&#xff0c;就是Skills。起因是我在一个名为“SkillSpace&#xff08;技能空间&#xff09;”的开源网站上&#xff0c;看到了近6万个AI Agent技能被整理成一套可浏览、可导入的技能库&#xff0c;第一反应是&#xf…

2026/10/20 16:39:33 阅读更多 →

最新新闻

论文被批“AI味”?千笔·降AIGC助手与PaperRed选型对比

论文被批“AI味”?千笔·降AIGC助手与PaperRed选型对比

1. 先说结论&#xff1a;为什么你的论文总被说“机翻味”和“模板腔”本科生写论文被导师退回重写&#xff0c;理由里出现频率最高的三句话&#xff0c;我闭着眼都能背出来&#xff1a;“这段话像机翻的”“这一段完全没有你自己的判断”“每段都是首先、其次、最后&#xff0c…

2026/10/20 18:48:51 阅读更多 →
基于Q-learning的储能调度效益最大化:Matlab实现与参数调试全解析

基于Q-learning的储能调度效益最大化:Matlab实现与参数调试全解析

能源市场里的“效益最大化”&#xff0c;表面上是低买高卖&#xff0c;但真正上手做就会发现难点从来不是“判断价格高低”&#xff0c;而是“做决策序列”&#xff1a;这一小时贪婪地把储能里所有电卖光&#xff0c;下一小时遇到更高价的时段就只能干瞪眼&#xff1b;低谷时段…

2026/10/20 18:48:51 阅读更多 →
Pi 1.0 原生MCP与Durable:终端编程代理从对话到持久化执行

Pi 1.0 原生MCP与Durable:终端编程代理从对话到持久化执行

如果你也在终端里用过 AI 编程代理&#xff0c;应该能感受到一个尴尬&#xff1a;它能写代码、能跑命令&#xff0c;但一关终端&#xff0c;上下文全丢。这个痛点卡了我很久。所以当我看到 Pi 1.0 正式发布&#xff0c;主打原生 MCP 和 Pi Durable 时&#xff0c;第一反应不是“…

2026/10/20 18:48:51 阅读更多 →
context-mode设计实战:从上下文管理到模式切换的工程化落地

context-mode设计实战:从上下文管理到模式切换的工程化落地

1. 从“context-mode”说起&#xff1a;一个被低估的工程概念第一次看到“context-mode”这个词&#xff0c;很多人会下意识地把它归到某个具体框架的配置项里&#xff0c;觉得无非是个开关或者枚举值。但如果你真正在多个项目里跟“上下文”打过交道&#xff0c;就会发现它其实…

2026/10/20 18:48:51 阅读更多 →
面向对象设计实战:从封装多态到SOLID原则落地

面向对象设计实战:从封装多态到SOLID原则落地

1. 对象思维是一道分水岭我面试过不少人&#xff0c;聊到“面向对象的编程设计”&#xff0c;背概念都能背得滚瓜烂熟&#xff1a;封装、继承、多态&#xff0c;三大特征如数家珍。但一旦落到实际项目里&#xff0c;写出来的代码还是一把梭——几百行的方法&#xff0c;到处是i…

2026/10/20 18:48:51 阅读更多 →
EBS采购订单审批API集成实战:工作流、中间件与存储过程设计

EBS采购订单审批API集成实战:工作流、中间件与存储过程设计

做EBS集成的同学对采购订单审批肯定不陌生。标准功能里&#xff0c;审批人每天登录EBS工作台&#xff0c;从一堆待办通知里逐个点开、审批、写意见&#xff0c;流程虽然完整&#xff0c;但一旦公司上了OA、企业微信、钉钉或者供应商协同平台&#xff0c;业务方就会立刻找你&…

2026/10/20 18:47:50 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

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

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

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

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

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

2026/10/20 1:01:30 阅读更多 →

周新闻

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

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

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

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

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

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

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

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

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

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 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/20 10:02:08 阅读更多 →
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/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练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/20 9:50:45 阅读更多 →