ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Audiveris GRID 步骤深度解析:从黑白图像到系统与谱表网格的完整构建流程

Audiveris GRID 步骤深度解析:从黑白图像到系统与谱表网格的完整构建流程 桌面应用计算机视觉图像处理OCR【免费下载链接】audiverisLatest generation of Audiveris OMR engine项目地址https://gitcode.com/gh_mirrors/au/audiveris点击查看免费下载导读GRID是 Audiveris OMR 引擎流水线中的关键步骤其任务是从二值化图像中恢复整张乐谱的系统systems与谱表staves网格——这是后续所有符号识别、节拍还原工作的空间骨架。本文以官方文档《GRID step》为主体结合仓库中LinesRetriever、BarsRetriever、GridBuilder等核心源码系统讲解该步骤的输入输出、Run/Section/LAG 组织、水平长线状物filament聚类、谱表垂直投影、峰值图peak graph与系统聚合的完整流程并给出每个环节在图形界面中的可视化验证方法。读完本文你将理解 Audiveris 是如何从一堆黑色像素逐步推断出谱表线、小节线、花括号、方括号以及最终系统网格的。一、GRID 步骤在流水线中的位置与职责Audiveris 的 OMR 处理链由一系列步骤组成GRID紧跟在负责图像缩放的SCALE步骤之后。其唯一目标如官方文档所述检索出当前 sheet 的所有系统与谱表The purpose of the GRID step is to retrieve the systems and staves of the sheet。从源码结构看这一步的落地实现集中在org.audiveris.omr.sheet.grid包中grid 包目录核心编排类是 GridStep.java其doit()方法依次执行三件事new GridBuilder(sheet).buildInfo()—— 构建系统网格主体L96-L97new StaffLineCleaner(sheet).process()—— 清理谱表线L99-L100sheet.getStub().getBook().updateScores(...)—— 更新评分L102-L103。而 GridBuilder.java 的类注释明确写道系统网格的计算基于水平谱表线与垂直小节线的检索实际处理委托给两个伴侣类companionLinesRetriever—— 负责检索水平谱表线createBothLags→retrieveLines→addShortSections→completeLines见 GridBuilder.buildInfoBarsRetriever—— 负责检索垂直小节线barsRetriever.process()L153。也就是说文档中描述的整个 GRID 处理本质上是水平线与垂直线两路信号的双向协作水平线定谱表框架垂直线定小节与系统边界。二、输入与输出输入GRID 步骤的输入来自前序步骤共三项黑白二值图像由BINARY步骤产生此后图像只包含黑色前景像素与白色背景最大谱表线厚度由SCALE步骤给出scale.getMaxFore()详见 SCALE 步骤输出典型 interline 值谱表线间距以及可选的小 interline 值当图像中存在两套不同尺寸的谱表时。输出GRID 步骤结束后产出以下结构化结果水平 sections 的 LAG与垂直 sections 的 LAG按谱表组织的谱表线整张图像的全局倾斜角skew对每个谱表小节线若有、上下谱表间的垂直连接符若有、起始花括号brace若有、起始方括号bracket若有谱表聚合成的系统systemno-staff 图像已擦除谱表线的二值图。其中 Section 与 LAGLinearAdjacencyGraph线性邻接图是 Audiveris 的底层像素组装概念可参考 Pixels assemblies 概念文档Run同一方向水平或垂直上颜色相同的连续像素序列见 Run 与 RunTableSection按兼容规则如 run 长度差上限、run 长度比上限、端部偏移上限等将同方向相邻黑色 run 传递性连接而成的组装体LAG同方向 sections 的集合水平与垂直各一个。从源码看这两个 LAG 的建立由 LinesRetriever.createBothLags() 完成它从二值图像的垂直 RunTable 出发将长垂直 run 分派到垂直 LAG其余像素进入水平 RunTable再进一步按最小 run 长度拆分为长水平 run与短水平 run两类表。三、处理流程详解3.1 过滤 Run 与 Section建立两个 LAG处理的第一步是将二值图像的所有前景黑色像素组织为垂直 run。随后引擎基于SCALE步骤提供的最大谱表线厚度略微放大得出一个判定阈值——放大的目的是容纳可能更厚的加线ledger lines即超出五线谱上下的临时短线。源码中该阈值通过scale.getMaxFore()与stickerThickness常量比值 1.0相乘得到见 LinesRetriever.Parameters 构造函数。判定逻辑非常直接任何长于最大谱表线厚度的垂直 run不可能是谱表线的纯净片段而必然是某种交叉对象如小节线、符干的一部分因此被放入垂直 LAGlongVertTable→buildVerticalLag其余所有像素组织为水平 run归入水平 LAGbuildHorizontalLag。进入 LAG 后相邻 run 按兼容规则聚合成 sections。水平 sections 还会进一步分为短 sections与长 sections因为长 sections 将主导后续谱表线检测。源码中createBothLags()先只把长水平 run填入水平 LAG短水平 run 暂存于shortHoriTable待谱表线初步成形后再由addShortSections()补入L582-L598、addShortSections。可视化验证打开Tools → Constants下拉菜单勾选布尔常量displayRuns位于LinesRetriever类中对应源码 Constants.displayRuns。即可依次查看以下视图示例素材为仓库data/examples中的chula.png内容视图二值图像长垂直 sections短水平 sections长水平 sections3.2 长水平线状物filaments与全局倾斜从长水平 sections 集合出发引擎逐步构建又长又细的 filaments——这些大概率对应谱表线的长片段。源码中对应 retrieveLines() 的主线构建初始 filamentsFilamentFactory.retrieveFilaments(hLag.getEntities())L1493-L1499剔除弯曲的 filamentspurgeCurvedFilaments()用样条NaturalSpline计算中点的旋转角若超过maxFilamentRotation0.1 弧度则丢弃L1149-L1189计算全局斜率retrieveGlobalSlope()取最长的前 10% filamentstopRatioForSlope 0.1求平均斜率存入Skew对象L1433-L1455、L1506-L1508剔除斜率偏离的 filamentspurgeSlopedFilaments()比较每个 filament 斜率与全局斜率的差值超过maxSlopeDiff0.025 弧度即丢弃——但对基于单个 section 的短 filament 放宽了阈值因为其天然接近水平L1205-L1248。接下来水平 filaments 按垂直方向聚合成簇cluster每个簇大概率代表一个谱表。簇内需满足两个约束filaments 间距应符合已知的谱表 interline 值filament 数量必须匹配用户声明的谱表规格1 线、4 线、5 线或 6 线由用户在Book 参数下拉菜单中设定。见 Book 参数之 Staves 声明1 线打击乐谱表、4 线低音 tablature、5 线标准谱表、5 线无音高打击乐谱表、6 线吉他 tablature。最终剩余的簇按线数转化为标准谱表Staff、一线谱表OneLineStaff或tablature。源码 buildStaves() 中可见清晰的类型分派L266-L2705 线 →Staff1 线 →OneLineStaff其他如 4 线、6 线→Tablature。在转化为谱表之前purgeClusters()会依据以下规则剔除伪簇L1032-L1077过短宽度小于minStaffLength30 个 interline过于倾斜对近乎水平的乐谱一线簇斜率超过maxOneLineSlope0.001即剔除近乎空洞真实长度低于最长簇真实长度的minTrueLengthRatio0.3倍。此时每个谱表的左右横坐标界限仅由检测到的线决定尚不精确后续会通过垂直投影细化。3.3 谱表垂直投影staff vertical projection既然引擎已知道每个谱表的顶线与底线就可以把这两条线之间的所有黑色像素投影到 x 轴上得到一维投影曲线。对 1 线谱表的特殊情况官方文档的脚注说明引擎会改用以 interline 数为单位的目标小节线高度来做投影该高度可通过Book 参数菜单调整对应 Book 参数中的 Barline height 规格four、twoThenFour、two、oneThenTwo四种取值。投影的可视化前提先在Tools → Advanced下拉菜单中激活PLOTS主题然后通过Sheet → Staves plots菜单或从谱表右键的popup Staff上下文菜单查看在该投影曲线上引擎检测峰值peaks它们可能代表小节线barlines半花括号half braces半方括号half brackets长符干long stems等。峰值内的细长垂直 sections 被用来构建垂直 filaments——注意这些 filaments 可能向上/向下超出谱表的顶/底线。源码中这一系列工作由 StaffProjector.java 与 BarsRetriever.java 协同完成BarsRetriever类注释明确其职责是检索垂直小节线、方括号与花括号L119-L120。可视化验证在Tools → Constants中勾选displayFilaments布尔常量定义于 GridBuilder.Constants界面会显示一个专门的Filaments标签页同时展示水平与垂直 filaments 的初始素材水平 filaments 为淡红色垂直 filaments 为淡蓝色。内容视图初始 Filaments3.4 峰值图peak graph与系统聚合所有垂直投影中的峰值都被视为sheet 级峰值图peak graph的顶点。若某谱表的峰值与下一谱表的峰值在垂直方向上对齐就在全局峰值图中记录一条边edge。随后每条对齐边都会被检验两个谱表峰值之间是否存在足够的前景像素以确认两者之间存在真实连接例如连接上下谱表的连接符、贯穿的小节线。同时任何超出谱表顶/底边界、又不是连接符的 filament都不可能成为小节线因此被丢弃。基于检测到的连接引擎现在能够把谱表聚合成系统system。这条峰值→对齐→连接判定的逻辑在 PeakGraph.java、BarAlignment.java 与 BarConnection.java 中实现BarsRetriever中定义的StaffPeak.AttributeTHICK、THIN、BRACE_TOP/MIDDLE/BOTTOM、BRACKET_MIDDLE等见 BarsRetriever.java则用于刻画每个峰值所代表的符号类型。3.5 系统内部对齐system internal alignments在每个系统内部谱表峰值被组织为基于系统的列system-based columns处理规则如下起始列starting column若存在用于细化系统与谱表的左横坐标起始列右侧的列必须覆盖整个系统高度否则被丢弃超出系统垂直界限的峰值也被丢弃花括号部分与方括号部分在起始列的左侧搜索左边缘是否存在花括号决定了谱表是否被聚合成parts声部组。最终在每个系统的 SIG符号交互图中创建以下 Inters符号实例小节线barlines连接符connectors花括号braces方括号brackets。源码中BarsRetriever大量引用BarlineInter、BraceInter、BracketInter、BarConnectorInter等 Inter 类型见 BarsRetriever.java并在 SIG 中建立BarConnectionRelation、BarGroupRelation等关系边——这正是Inters 被创建的实现落点。四、GRID 步骤的结果GRID 步骤结束时Data标签页已填充系统与谱表的网格可以分别用**物理模式Physical与逻辑模式Logical**查看模式视图PhysicalLogical一个值得注意的工程取舍GRID 步骤结束时可能残留少量误检的小节线false barlines。它们通常会在后续的 REDUCTION 步骤 中被清除——这是 Audiveris 各步骤渐进式精化设计哲学的典型体现宁可先保留候选由后续步骤结合更多上下文裁决。no-staff 图像由于引擎已确切知道哪些水平 sections 组成了谱表线它可以逻辑上擦除这些 sections从二值图像中生成所谓的no-staff 图像。该图像将供流水线后续多个步骤使用例如符号识别时避免谱表线干扰。可视化方式通过Sheet → No staff下拉菜单查看对应源码 GridStep.displayUI() 中的NO_STAFF_TAB标签页由常量displayNoStaff控制。内容视图No staff已擦除谱表线五、关键常量速查源码级为便于调优与深入阅读以下列出LinesRetriever中与 GRID 水平线检测直接相关的核心常量定义于 LinesRetriever.Constants单位与默认值均为源码原值常量单位默认值作用topRatioForSlope比例0.1用于计算全局斜率的最长 filaments 占比maxFilamentRotation弧度0.1filament 允许的最大中心旋转角弯曲剔除阈值maxSlopeDiff弧度0.025filament 与全局斜率的允许最大差值minRunLengthinterline0.25水平 run 被纳入考虑的最小长度minStaffLengthinterline30谱表簇的最小水平长度minSlope正切0.0002值得记录的最小绝对斜率maxOneLineSlope正切0.001完美 sheet 上一线谱表的最大绝对斜率minTrueLengthRatio比例0.3相对最长簇真实长度的最小占比空洞剔除patternWidthinterline1.0谱表端点模式探测的宽度patternJitterinterline0.25谱表端点模式的最大纵坐标抖动minRadiusinterline12曲率抛光polish的最小可接受半径displayRuns布尔false是否显示 runs 视图这些常量大多在 Parameters 构造函数 中按scale.toPixels(...)换算为像素值体现了 Audiveris 的**缩放无关scale-independent**设计同一套常量在不同分辨率乐谱下都能自适应。六、小结GRID 步骤以三条证据链完成了乐谱网格的复原水平证据链黑色像素 → 水平 run → 水平 sections长短分流→ filaments去弯、去偏斜→ 簇 → 谱表标准/一线/tablature垂直证据链黑色像素 → 垂直 run → 垂直 LAG → 谱表垂直投影峰值 → 垂直 filaments → 峰值图对齐与连接判定聚合证据链系统内列对齐 → 起始列细化 → 花括号/方括号搜索 → parts 聚合 → SIG 中创建小节线/连接符/花括号/方括号 Inters。每一步都配有图形界面中的可视化开关displayRuns、displayFilaments、PLOTS 主题等与对应源码实现便于开发者逐层调试与验证。理解了 GRID就理解了 Audiveris 如何在像素与音乐语义之间搭起第一座桥梁——后续的符号识别、节拍还原都将在这张网格上展开。延伸阅读SCALE 步骤interline 与谱表线厚度的测量Run、Section、LAG 与 Filament 概念详解SIG符号交互图概念Book 参数谱表规格与缩放参数设置核心实现LinesRetriever.java核心实现GridBuilder.java核心实现BarsRetriever.java核心实现GridStep.java赞分享桌面应用计算机视觉图像处理OCR【免费下载链接】audiverisLatest generation of Audiveris OMR engine项目地址https://gitcode.com/gh_mirrors/au/audiveris点击查看免费下载相关推荐Table Transformer实战指南3步实现文档表格智能提取的革命性方案Table Transformer实战指南3步实现文档表格智能提取的革命性方案 在数字化办公和文档智能处理的浪潮中PDF文档和图像中的表格数据提取一直是技术人工智能计算机视觉深度学习OCR3步完成Telegraf容器化从零到生产级监控采集实战3步完成Telegraf容器化从零到生产级监控采集实战 还在为服务器监控配置繁琐而头疼吗面对分布式系统的指标采集你是否希望找到一种更高效、更灵活的部署方案可观测性指标监控运维faster-whisper 批处理实战把长音频转写压到分钟级faster whisper 批处理实战把长音频转写压到分钟级 长音频转写拖慢服务响应。faster whisper 的批处理接口 BatchedInfere人工智能语音音频本地部署上一篇google-font-download高级技巧自定义字体格式与语言子集下一篇PostgresApp时间序列数据处理使用TimescaleDB扩展创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表