news 2026/10/3 9:25:49

Ovito Expression Selection:分子链提取与模糊背景渲染实操

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Ovito Expression Selection:分子链提取与模糊背景渲染实操

做分子模拟的人应该都有这种体验:轨迹文件里粒子几万几十万个,渲染出来的图花花绿绿一片,导师看完只问了一句“链在哪儿呢?”这时候你才意识到,模拟跑完了,数据一大堆,但真正要把某一条分子链单独拎出来展示,比跑模拟还让人头大。

我在处理聚合物体系、表面吸附、水分子动力学这些场景时,反复用过很多种方案——手动删粒子、写脚本按ID筛选、甚至导出到VMD里再处理。最后发现,最顺手的反而是大部分人都忽略的Ovito Expression Selection功能。它不需要写完整Python脚本,不用切软件,直接在Ovito的Modifier列表里敲几行表达式,就能按条件把链挑出来,而且配合渲染设置还能直接出“背景虚化、主体清晰”的科研级示意图。

这篇就完整整理一下我用Expression Selection提取分子链的完整思路、表达式的写法、对应的参数配置,以及最后模糊背景渲染的具体参数。文章会比较长,但每一步都是实测过的,照着操作基本能复现。

1. 为什么偏偏选Expression Selection来挑分子链

1.1 它和手动筛选、Python脚本的差别在哪

先说结论:Expression Selection在Ovito里是一个Modifier,界面上的全称是“Select Particle Expression”,老版本里可能写作Expression Selection。它的作用是按你输入的表达式,把满足条件的粒子标记为选中状态。选中之后你可以删除、上色、计算、导出,一气呵成。

我之前试过两种土办法。第一种是直接隐藏其他粒子,把视角拉近,然后用鼠标框选目标链。这个方法在粒子少、链短的时候勉强能用,一旦体系里有几十条链相互缠绕,框选就变成了一场灾难——你永远无法保证选出来的粒子属于同一条链,一个不小心就把邻居链的粒子圈进来了。第二种是写Python脚本做后处理,灵活是灵活,但对不熟悉Ovito Python API的人来说,光查文档就能耗掉一晚上,而且脚本要处理文件读写、数据结构、属性映射,只是为了“挑一条链”来说,投入产出比太低。

Expression Selection的优势在于它把“筛选”变成了“写条件”。你不需要关心体系里有多少粒子、粒子在什么位置,只需要找到区分这条链和其他粒子的“身份标签”。这个标签可以是粒子编号、分子ID、坐标范围、甚至是某个自定义属性。表达式写好后,点一下Apply,所有满足条件的粒子瞬间被选中,干净利索。

1.2 说到底,它就是一套“粒子筛选器”

从底层逻辑讲,Expression Selection就是遍历粒子集合,对每个粒子计算你输入的表达式,结果为真则选中,为假则不选。它的表达式语法接近Python,支持算术运算、比较运算、逻辑运算和常见的数学函数。

我举一个最简单的例子。如果轨迹里每个原子都有“Particle Identifier”这个属性(也就是粒子编号),你想选出编号从100到200之间的粒子,表达式就写成:

ParticleIdentifier >= 100 && ParticleIdentifier <= 200

如果是LAMMPS跑出来的dump文件,里面往往有Molecule ID这个属性(由分子拓扑识别生成),想选某一条链就更简单了:

MoleculeID == 3

这里MoleculeID是LAMMPS在输出时通过分子拓扑赋予的属性,代表每个粒子属于第几条链。用这个条件,一次就能选中整条链的全部原子。

关键点是,你得知道自己手头的数据有哪些属性。可以在Ovito里选中粒子后,在右侧的Particle属性面板里查看。我一般会先加载一帧轨迹,点击一个粒子,看它有哪些属性字段,再决定用哪个字段做筛选标签。没有属性标签的话,就先做一个Create Bonds或者自己载入一个MoleculeID属性,这属于进阶操作,后文会讲到。

2. 快速提取分子链:从数据准备到最终导出

2.1 第一步:搞清楚你的体系里链是怎么编号的

在写任何表达式之前,必须搞清楚目标链和编号规则。不同的模拟软件、不同的输出设置,粒子属性的含义差异很大。

我自己的习惯是,先加载轨迹第一帧,在Ovito的渲染窗口里点选几个粒子,打开粒子表(Particle List),看属性面板。这一步非常关键,它决定了你后面表达式的写法。如果看到属性列表里已经有“Molecule ID”或者“Molecule Identifier”,那恭喜你,直接用它最省事;如果只有“Particle Identifier”和坐标属性,那你需要试试用粒子编号范围来筛;如果编号完全无规律,那就得先做一步拓扑识别。

实际案例里,我最常遇到的是LAMMPS的data文件或dump文件。LAMMPS输出通常包含id、type、x、y、z这些字段,如果模拟体系是用molecule命令创建并写入拓扑的,dump文件里也可能有mol字段。这个mol字段就是天然的MoleculeID。没有mol字段时,也可以用atom_style里包含molecule的版本重新导出。

如果用的是GROMACS,轨迹通常是.xtc格式,Ovito读入后会自动做分子识别,生成Molecule ID属性,但这一步有时需要手动添加“Create Bonds”Modifier才能正确生成。

2.2 第二步:用Create Bonds把“分子链”从一堆点里识别出来

有些轨迹文件里只有粒子坐标,没有任何分子信息。这种情况下,直接写表达式就无从下手,因为粒子之间没有“链关系”。

解决办法是先加一个Create Bonds修饰器。它可以根据粒子间的距离自动成键,一旦粒子连成链状,Ovito就能识别出独立的分子。Create Bonds有一个关键参数是“Cutoff distance”,也就是原子间距离小于多少时认为成键。这个值需要参考你体系的键长,或者看径向分布函数的第一个峰位置。设置得太小,链会断裂;设置得太大,会把相邻链的粒子误连在一起。

我个人经验是,对碳链体系(C-C键长约1.54埃),cutoff设在1.7到1.8埃比较安全;对水分子(O-H键约0.96埃),cutoff设在1.2埃左右。不同力场、不同原子类型会有差异,建议先用单帧测试,观察成键效果是否合理。

成键生成后,Ovito会自动计算出Molecule ID属性,每条链就拥有了独立的ID编号。接下来再添加Expression Selection,筛选条件直接写:

MoleculeID == 目标链编号

选中后右键点击“Invert Selection”,把非目标粒子删除或隐藏,整条链就提取出来了。

2.3 第三步:当ID无规律时,用“链长片段的编号范围”兜底

有些模拟轨迹里,每条链的原子编号是连续的,但链与链之间编号有断层。比如链A是粒子1到50,链B是粒子101到150,链C是粒子201到250。这种情况完全不需要MoleculeID,直接用ParticleIdentifier范围就能选。

例如我要选粒子101到150这条链,表达式写:

ParticleIdentifier >= 101 && ParticleIdentifier <= 150

如果链的编号在文件中并不是规规矩矩的连续段,只是每个粒子有唯一ID,那我还用过一种偏方:先看目标链上任意几个粒子的ID,再用“或”连接多个单点条件。比如:

ParticleIdentifier == 102 || ParticleIdentifier == 145 || ParticleIdentifier == 78

这种方式能帮你快速“点选”一小撮粒子,然后把它们作为种子,再配合Create Bonds延伸成全链。不过说实话,这个办法适合预处理和Debug,不适合规模化操作。

2.4 第四步:提取之后,别忘了“删除其他”和“导出选中粒子”

这是很多人容易漏掉的一步。Expression Selection只是把粒子标记为选中,并不会主动删除其他未选中的粒子。如果你想获得“只剩一条链”的模型,还需要在选中后使用Delete Selected Particles操作。

一个常用的操作序列是:

  1. 右键点击Expression Selection修饰器,选择Toggle Selection,得到当前筛选结果。
  2. 再添加一个Delete Selected Particles修饰器,把所有未选中粒子全部删掉。
  3. 只保留目标链的粒子,这时模型窗口里就只剩一条干净的链了。

如果不想破坏原始数据,我建议不要用Delete修改原始轨迹,而是把处理管线保存成Ovito的.ovito文件,后续再加载这个管线来渲染。用管线的好处是原始轨迹文件不会被改动,随时可以调整参数重新提取。

提取完成后,如果你需要把这一帧的选中粒子导出成单独的数据文件,可以使用Ovito的File > Export File功能,导出格式可以选择CSV、XYZ或者LAMMPS data format,粒子范围选择“Selected particles”即可。

2.5 一个完整的操作流程示例(以LAMMPS轨迹为例)

我以一套LAMMPS粒子轨迹为例,完整走一遍从加载到导出的流程,方便你对照操作。

假设轨迹文件是dump.lammpstrj,相同目录下还有一份data文件。操作流程:

  1. 打开Ovito,把dump.lammpstrj拖进窗口。
  2. 在Modifier列表里点击Add Modification,选择Create Bonds,把Cutoff设为1.75(如果模拟的是聚乙烯链,C-C键长范围可参考该值)。
  3. 依次点击“Apply”,确认生成Molecule ID属性。
  4. 再次Add Modification,选择Select Particle Expression,输入表达式:
MoleculeID == 5

如果编号0是第一条链,5就是第6条链,这个编号对应关系要心里有数。

  1. 点击Apply后,观察视口。第6条链的原子变成高亮选中状态,其他粒子变暗。
  2. 确认无误后,再添加Delete Selected Particles,点击Apply,视口里就只剩第6条链了。
  3. 想导出一步到位:菜单File > Export File,格式选LAMMPS Data,选择Selected particles,写出一个只含单链的data文件。这个文件可以在其他软件里继续做分析,也可以回灌到LAMMPS里做后续模拟。

这个流程全程不到5分钟,比起我以前用脚本折腾半天,效率提升了不止一个量级。

3. 模糊背景配置参数:让渲染图摆脱“实验室风”的关键设置

3.1 Ovito里没有“一键模糊背景”,但有更专业的景深方案

很多人第一次听到“模糊背景”会到处找按钮,实际上Ovito并不像美图工具那样提供一个“背景模糊”滑块。它实现背景虚化的方式,是借助渲染器里的Depth of field(景深)功能。

这个功能模拟的是相机的光学特性:当你把焦点对准画面中某个位置时,位于焦平面附近的物体是清晰的,离焦平面越远,就越模糊。用这个原理,可以把视角对准分子链主体,让背景里的周期性镜像和远处颗粒自然虚化,产生“主体跳出来”的效果。

Ovito 3.x版本中,景深功能在渲染设置的Camera选项卡下。打开方式是最上方工具栏的“Render”按钮,进入渲染设置后,寻找Camera选项区域。其中有两个关键参数:Focus distance(焦点距离)和Focal length(焦距),部分版本还提供Aperture(光圈)相关参数。

需要特别说明的是,这三个参数是配合使用的。焦点距离决定从相机位置到清晰平面的距离,实际上就是你希望“最清晰那个点”离相机有多远;焦距决定视角范围和总的透视效果;光圈值决定模糊的强度。光圈数字越小,背景虚化越明显(这和我们用相机拍照的逻辑一致,f/1.8比f/8背景更糊)。

3.2 我实测下来比较稳的模糊背景参数组合

参数的具体数值,和你的模型尺度、相机距离、目标链的位置高度相关。下面给一组针对“中等尺寸模拟盒子(边长约50到80埃)、相机距离目标链约150到250埃”场景的参考值。这套参数我在多个体系里试过,效果相对可控。

Focus distance: 200 Focal length: 35 Aperture (F-stop): 2.8

这三项设置的效果是:焦点落在相机前方200埃的位置,这个位置的分子链保持清晰;35毫米焦距相当于“小广角”,能容纳足够多的分子链细节;F2.8光圈让背景产生明显的虚化,而不会糊到完全不可辨。

如果你的体系特别大,比如盒子边长200埃,那Focus distance需要相应调大,否则清晰面会在链条前方或后方,导致主体发虚。我遇到这种情况时会把Focus distance调整到离目标链中心的实际距离,比如300到400,Aperture再降到4.0左右,这样在保证主体清晰的同时,背景虚化依然比较明显。

3.3 背景渐变色的配置参数

除了镜头景深,背景本身的颜色渐变也能让“模糊背景”更有层次感。Ovito的渲染设置里,背景类型可以选纯色或渐变色。渐变色背景配合景深虚化,画面立体感明显更强。

我在Offscreen渲染设置里,把背景类型选为Gradient,并设置两个颜色:

Background gradient top: #1e1e2e (深灰蓝) Background gradient bottom: #f5f5f5 (浅白)

顶部深色、底部浅色的垂直渐变,会让画面有一种自上而下的光感,主体链条在中间高亮区域自然成为视觉焦点。如果希望更“科研冷淡风”,可以统一用白到浅灰的渐变,比如顶部#fafafa,底部#e0e0e0。

这里提醒一下,如果渲染窗口里看不到背景变化,要去渲染设置里勾选“Show background”并确认预览模式是“Full render”,而不是交互式OpenGL模式。OpenGL模式下景深效果有时不显示,最容易让人误以为参数没生效。

3.4 渲染成图后的后处理补充

Ovito渲染出来的图片,景深虚化是定死的,不能再调。如果你想后期再调整模糊强度,我建议把渲染尺寸设置得大一些,比如4096×4096,输出PNG无损格式,然后用图像处理软件做局部模糊微调。但注意,如果你已经用景深渲染了模糊,后期再叠加模糊容易让边缘发脏,反而显得不自然。我现在的习惯是Ovito里把模糊控制在适中档位,后期只做轻微对比度和饱和度的调整,不再修饰模糊本身。

如果你不想用景深,只想在后期软件里手动模糊背景,也完全可行。那就把景深关掉,背景渲染成渐变,粒子主体保持清晰。把图导入Photoshop或GIMP里,用选择工具框出背景区域,加高斯模糊滤镜,半径参数一般在5到15像素之间,根据画面分辨率调整。这个方法自由度更高,但前提是你的主体边缘要抠得干净,否则模糊会侵入分子链区域。

3.5 一套完整的出图参数表

为了方便你直接抄作业,我把一套比较通用的出图参数整理成表格。每个参数都标注了用途和调整建议。

参数项推荐值作用与调整建议
Focus distance200(按实际相机到主体距离调整)清晰面位置,数值等于相机到目标链的距离
Focal length35 mm画面透视感,小数值视野广但畸变稍大
Aperturef/2.8图像中模糊强度,数值越小背景越糊
背景类型Gradient用渐变背景增强层次
背景顶部颜色#1e1e2e深色背景,适合浅色粒子主体
背景底部颜色#f5f5f5浅色背景,渐变过渡更柔和
渲染分辨率4096×4096高分辨率保细节,可用于论文插图
输出格式PNG无损格式,保留颜色渐变细节
渲染器Tachyon推荐Tachyon,速度快且景深效果好

这套参数并不保证所有场景都完美,但结合前面章节里你对模型尺寸的理解,微调Focus distance和Aperture,很快就能找到适合自己体系的组合。

4. 常见问题与排查技巧实录

4.1 表达式写了但没有任何粒子被选中

这个情况我遇到太多次了。通常有三个原因:第一,属性名写错了。Ovito对属性名大小写敏感,比如是ParticleIdentifier而不是particleid,是Position.X而不是Position.x。第二,属性在当前数据源里根本不存在。如果你没有Create Bonds,那MoleculeID这个属性就是不存在的,表达式里写MoleculeID == 5会直接报错或返回空。第三,数值超出范围。链的编号可能从0开始,也可能从1开始,建议先用“可视化右键选中粒子查看属性值”的方式,确认目标链的ID值到底是多少。

排查方法很简单:先在添加Expression Selection之前,点击一个目标链上的粒子,看属性面板里MoleculeID的值。条件顺序方面,也可以先在Expression Selection里只写一个粒子ID的最小范围,比如ParticleIdentifier == 目标链第一个粒子ID,验证筛选是否生效,再逐步扩展成整条链。

4.2 分子链提取出来是断的,连不成完整一条

这个问题通常出在Create Bonds的截断距离上。截断值太小,链上的部分键没被识别,链就断成了几段,每一段会被当成一个独立MoleculeID,导致你MoleculeID == 数字只选中了其中一小段。

解决办法是调大Create Bonds的Cutoff,一点一点试。从1.5开始,每次加0.05到0.1,直到整条链连续为止。但也要小心别调过头,不然相邻链会串键。最稳妥的判断方式是,在添加Create Bonds后,先给粒子按照MoleculeID上色,如果看到目标链是一条颜色均匀的连续长链,说明拓扑识别成功。

如果确信键长没问题,但链还是断的,可以检查一下你的轨迹文件是不是经过了周期性边界包装。跨边界原子的坐标被折叠到盒子另一边,直接计算距离会出错。这时要在Create Bonds里打开“Ongoing bonds across periodic images”或者类似的周期性镜像选项,让成键计算考虑周期性边界的影响。

4.3 景深参数调了没反应

景深效果在OpenGL交互式显示模式下经常会“失灵”,这是最迷惑人的一点。你打开Render设置里的Camera选项卡,调好Focus distance和Aperture,但视口里的画面毫无变化,不清楚的人就开始怀疑软件出bug了。

实际原因很简单:OpenGL模式是实时预览模式,并不支持全部的景深渲染效果。你需要切换到Offscreen渲染模式,也就是选择Render按钮后,让Ovito重新渲染一帧,才能看到景深生效后的画面。

我在操作时通常这样:先把视角调整好,切换到Offscreen模式,渲染一张低分辨率的预览图(如1024×1024),观察虚化效果,然后微调参数,再渲染最终的高分辨率大图。这比在OpenGL模式里盯着看要高效得多。

4.4 模糊过度导致主体也跟着糊

很多新手的误区是把Aperture光圈拉到最小值,比如f/1.0,结果背景是糊了,但主体链的边缘也模糊不清。原因是景深范围太浅,只要主体有厚度,超出焦深的部分就会跟着虚化。

解决方法是适当调大F-stop值,从f/2.8调到f/4.0或f/5.6,同时把Focus distance对准目标链的中心位置。如果想进一步增大清晰范围,可以把Focal length从35毫米改到50毫米,长焦距下景深范围会相对增加,虽然视野变小,但主体更容易保持清晰。实际操作中,我经常在f/4.0下把焦点对准链的中心原子,让两端略有虚化,这种“浅景深但有主体”的效果在论文配图里既专业又有动感。

4.5 导出选中粒子后,链的坐标和原轨迹对不上

导出功能里的“Selected particles”有一定概率让你困惑:导出的坐标是当前帧的坐标,还是原始轨迹的坐标?实际上,Ovito导出时默认导出经过所有Modifier处理后的数据。如果你在管线里删除了其他粒子,导出的只包含剩余粒子的当前帧数据。

项目场景中,我常常需要在提取链条后,再导出每帧的链构象做统计计算。这时候不要用Delete Selected Particles,而要用Expression Selection标记选中状态,然后导出时选择“Selected particles only”。关键是,仅在导出时限制范围,在显示管线里保留全部粒子,这样原始轨迹的粒子编号和拓扑顺序不会被破坏,后续计算时链条ID依然可以对照原轨迹。

5. 进阶玩法和最后的一点心得体会

5.1 把提取流程保存成模板,后续一键复用

当你成功提取过一次分子链之后,后续再有类似需求就不必从头操作了。Ovito支持把整条Pipeline保存为.ovito文件,也可以把某个Modifier保存为预设。

我会在第一次调试好之后,把Create Bonds和Expression Selection存成一个预设组合。这样下一次打开新轨迹,直接加载这个预设,修改目标链的MoleculeID值和Create Bonds截断距离,点几下Apply就完成了筛选。这个习惯在我最近处理多条不同链构象的对比分析时帮了大忙,省下的时间至少按小时计。

5.2 可以把它和Python脚本结合做批处理

如果你的量很大,比如几十条轨迹都要提取链,手动点就太蠢了。这时候可以把管线和Ovito的Python脚本接口结合,写一个简单的循环,自动加载每个轨迹文件,加载预设管线,修改Expression Selection里的目标ID值,再导出结果。我写过一版不到60行的脚本,把原来一下午的操作压缩到了10分钟以内。

不过这里不展开脚本的具体代码,因为对大多数人来说,交互式操作已经足够。只提供一个思路:Ovito的Run Python Script模块可以读取当前Pipeline里某个Modifier的属性并做修改。如果你有一定Python基础,顺着“pipeline.modifiers”这个方向查文档,再结合官方自带的脚本示例,基本能够拼出你需要的批处理逻辑。

5.3 几个让我少走弯路的细节

最后分享几个小细节,都是我踩过坑之后才真正重视起来的。

第一,Expression Selection选择的是粒子,不是键。哪怕你看着画面里“一条链”被选中了,Ovito帮你选中的也是这条链上的所有粒子节点,而不是连接它们的化学键。如果需要保留键的信息,确保在Create Bonds之后、导出之前不要删除相关的拓扑修饰器。

第二,MoleculeID在不同帧之间可能是变动的。如果体系里有分子解体、再结合的过程,MoleculeID的编号方案可能会随时间变化。你必须在目标帧上查看当前帧的MoleculeID,确认后再提取。沿着一整条轨迹用固定编号提取链,有可能会在中间某帧突然失效。

第三,背景模糊是为了突出主体,千万不要喧宾夺主。论文配图的原则是“一眼看到主链”,背景虚化到位就行。我在f/2.8和圆形渐变背景的组合下出过一组图,导师看完只回了一句“这样清楚多了”。这是这个技巧最好的反馈。

如果你也在为分子链展示、轨迹可视化、出图发论文这些事情头疼,Ovito的Expression Selection配上景深渲染,是我目前能找到的性价比最高的方案。上手快,效果直观,还不用写一堆脚本。照着这篇文章操作一遍,下次再被问“链在哪儿”的时候,你应该已经能直接甩出一张主体清晰、背景干净的专业渲染图了。

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

MySQL CRUD深度解析:事务、锁、索引与误操作恢复实战

1. 从热搜词里看见的真相&#xff1a;简单CRUD背后藏着生产事故 如果你去翻一下最近的MySQL热搜词&#xff0c;会看到一大堆与增删改查毫无直接关系的词条&#xff1a;"mysql update 还原"、"mysql锁的分类"、"mysql事务处理"、"mysql数据库…

作者头像 李华
网站建设 2026/10/3 9:24:54

遥感图像识别的四模并举:KNN/SVM/CNN/LSTM分层验证框架

简介&#xff1a;本资源是一套面向计算机专业本科生与AI初学者的遥感图像识别综合实践项目&#xff0c;聚焦课程设计、期末大作业及算法对比学习需求&#xff0c;完整实现KNN、SVM、CNN与LSTM四种主流模型在遥感图像分类任务中的建模、训练与评估全流程。压缩包共33个文件&…

作者头像 李华
网站建设 2026/10/3 9:23:48

React Native混合开发实战:存量Android应用集成与踩坑指南

1. 内容整体设计与思路拆解1.1 为什么要在存量原生应用里引入React Native最近一年多&#xff0c;我一直在维护一个已经上线三年多的Android原生应用&#xff0c;日活大概几十万规模。业务方的需求越来越离谱&#xff0c;从“下周上线一个新活动页”发展到“今天下午能不能先出…

作者头像 李华
网站建设 2026/10/3 9:23:46

基于Python的Boss直聘数据可视化分析系统实践

简介&#xff1a;一份基于 Python 的 Boss 直聘数据可视化分析系统源码&#xff0c;面向正在准备期末大作业、毕业设计或想提升数据综合能力的高校学生&#xff0c;解决招聘岗位数据从爬取、清洗到分析、展示的完整链路问题。压缩包仅 426KB&#xff0c;共 26 个文件&#xff0…

作者头像 李华
网站建设 2026/10/3 9:23:45

基于Neo4j与Flask的电影知识图谱问答系统实战:从爬虫到小程序全链路

简介&#xff1a;这是一套面向计算机相关专业毕业设计与课程设计场景的知识图谱电影问答系统完整项目源码&#xff0c;基于Python与Neo4j构建&#xff0c;适合正在准备毕设、需要项目实战练习的学生参考使用。项目采用前后端分离结构&#xff0c;后端以Flask搭建问答服务&#…

作者头像 李华
网站建设 2026/10/3 9:22:49

DEMON谱分析:从舰船辐射噪声中提取轴频的完整实践

简介&#xff1a;在复杂海洋环境下&#xff0c;水声信号常呈现非平稳、多调制特征&#xff0c;Demon谱分析作为一种经典的包络解调方法&#xff0c;能够在强噪声背景下剥离包络结构&#xff0c;是水下目标识别和声源特征提取的重要手段。这份以Demon谱分析为核心的仿真资源&…

作者头像 李华