陈颂光
全栈工程师,能够独立开发从解释器到网站和桌面/移动端应用的各类软件。
关注我的 GitHub

基于图神经网络的联机手写五线谱识别

通过把手写看作图(Graph),其中每个顶点代表一条笔画,可以利用图神经网络对笔画进行分类和挖掘笔画间关系。最近几年来,它已经被应用于包括文本行分割、文本/非文本分类、表格检测/分析、图表分析、数学公式检测/识别在内的多种任务。值得注意的是,常用于音乐领域的五线谱实际上相当适合用图表示,其中每个音乐记号对应于一个顶点,而不同符号间的关联则对应于边,相反符号间错综复杂的平面位置关系更使得序列或者树都不能自然地表示五线谱。因此,图神经网络正是一种可以被用于分析和识别联机手写五线谱的利器。

联机手写五线谱识别

联机手写五线谱识别旨在把在触摸屏等电子设备上书写的五线谱转换为方便计算机程序使用的电子化形式。

联机手写五线谱识别示例

动机

电子化乐谱的应用

不同人可以在计算机的协助下对电子化的乐谱进行不同的处理,从而实现不同的目的。

  • 排版
    • 出版商可以印刷样式专业和一致的乐谱
    • 合唱团、乐团和其它演出者可以打印需要演奏或唱出的乐谱
    • 爱好者可以在网上分享自己的创作
  • 播放
    • 歌者可以生成纯音乐伴奏
    • 媒体(如视频、游戏)创作者可以生成声音效果
    • 作曲人和学生可以快速预览编辑乐谱的效果
    • 编曲人和学生可以快速预览用不同乐器演奏乐谱的效果
    • 调音师可以得到类似音叉的绝对音高
  • 常规编辑
    • 创作者可以通过复制和粘贴节省重复工作
    • 创作者可以容易地删除小节、合并/分解谱表和重组节奏
    • 歌者可以通过移调使音域更适合自己
  • 协同编辑
    • 作曲人、填词人和编曲人可以在同一份云乐谱协作
    • 创作者可以放心尝试修改并在需要时回滚
    • 历史学家可以通过版本管理回溯创作过程
  • 分析
    • 作曲人和编曲人可以快速发现乐谱中的错误或者不合理之处
    • 研究人员可以自动化地批量分析乐谱的统计特征
  • 检索
    • 创作者可以通过搜索发现灵感或侵权风险
    • 听众可以通过搜索音乐片段找到作品

现有的乐谱录入/编辑方法

为了享用电子化乐谱的优点,首先需要把乐谱输入计算机,不同的录入方法有各自的强项和局限性,适用场景也因而有所差异。

  • 基于键盘和/或鼠标的输入
    • 优点:
      • 熟练使用者打谱/编辑可以做到非常快
      • 可靠
    • 缺点
      • 需要学习快捷键等操作方式
      • 不方便在没有物理键盘的设备上使用
  • 基于物理或虚拟乐器的输入
    • 优点:
      • 对于会钢琴或其它电子乐器的人容易上手
      • 符合不少音乐人的创作习惯
    • 缺点
      • 在屏幕不够宽而没有外接电子乐器时不方便
      • 不适合录入某些音乐记号
  • 基于音频识别的输入
    • 优点:
      • 可以复用现有的音频文件
      • 可以通过录音快速记录听到的音乐
      • 不懂乐理的人也能使用
    • 缺点
      • 会有识别错误
      • 主要只适用于录入而非编辑
  • 基于图像识别的输入
    • 优点:
      • 可以电子化现有的纸质乐谱
    • 缺点
      • 会有识别错误
      • 主要只适用于录入而非编辑
  • 基于手写的输入
    • 优点:
      • 对于会乐理的人容易上手
      • 适合编辑现有乐谱
    • 缺点
      • 会有识别错误
      • 录入速度偏慢

现有的乐谱录入/编辑软件

市面上不少乐谱编辑软件,其中有一部分在某种程度上支持手写,但它们大多在近年发展停滞,可能是因为它们仍然在使用古老的算法,导致在准确性和支持范围上遇到瓶颈。

支持手写的乐谱软件
产品 文档 手写技术供应商 价格
StaffPad 文档 ? $49.99
NotateMe 文档 ? 免费
Notion 文档 MyScript $14.99
Symphony Pro 文档 MyScript $24.98
MusicJOT 文档 MyScript $49.99
其它流行的乐谱软件
产品 价格
Dorico 免费/¥823.00/¥4,765.00
Finale 已停售
Sibelius $899
Flat 免费/$299
Lilypond 免费且开源
MuseScore 免费且开源

手写五线谱识别的前景

在引入更现代化的识别技术后,手写五线谱识别的用户体验有望大幅提升,乐谱编辑软件的交互设计上也将迎来更多的可能性。

潜在的产品定位

手写五线谱识别可能被整合进多种产品中。

  • 主要的目标设备:
    • 带笔和触摸屏的设备(如平板/电子书/笔记本),手指头、鼠标和触摸版等似乎并不合适
  • 基本的功能:
    • 容许用户通过手写录入和编辑五线谱
      • 用户可以写完整个小节再转换为印刷体
      • 用户可以利用手势在印刷体内容中插入、移动、替换和删除等音乐记号,或者调整速度和移调等
    • 容许用户通过手写录入和编辑歌词
  • 可能的产品形态:
    • 识别SDK:容许高级软件开发者调用识别能力而自行控制交互
    • 乐谱编辑器控件:让软件开发者/站长较容易地把乐谱编辑功能集成到他们的APP/网站中
      • Android/WinUI/WPF/WinForms/UWP/MFC/GTK/QT/wxWidgets/Swing/JavaFX/Compose multiplatform/SwiftUI/Flutter的控件
      • HTML控件
      • 富文本编辑器如TinyMCE/CKEditor的扩展
      • 内容管理系统如WordPress的扩展
    • 音乐类APP:让最终用户可直接使用
      • 乐谱编辑APP:利用手写笔进行作曲、填词和编曲,也可能带播放、打印、分析、搜索和分享等功能
      • 乐器/歌唱教学APP: 手写输入乐谱后建议弹奏(如指法)或歌唱(如吸气/呼气位置)方法
      • KTV APP: 让用户录入或编辑乐谱后生成伴奏和提词,甚至再生成MV
潜在的客户

无论是厂商还是消费者都有可能为手写五线谱识别买单。

  • B端
    • 现有的手写乐谱编辑软件厂商:可以利用差异化功能争取他们切换供应商
    • 现有的其它乐谱编辑软件厂商:可以争取他们加入手写相关功能
    • 现有的手写笔记软件厂商:可以提倡他们添加对乐谱的专门支持
    • 教育软件/电子白板/学习机厂商:可以建议他们参与构建多媒体音乐课堂
  • C端
    • 正在学习乐理/乐器的人:利用容易上手的音乐录入方式协助他们交互式地建立音乐直觉。这个人群基数较大,不需要很专业的功能,有一定的付费能力(毕竟他们往往会为乐器、乐谱、课程和演出机会买单),但未必会长期使用。
    • 音乐创作者:利用高效且自然的手势操作协助他们提高编辑效率。这个人群基数很小,对专业性和可定制性要求较高,但付费意愿强,有机会成为忠实用户。

五线谱的构成

为了了解五线谱中不同记号的实际使用情况以确定优先支持的范围,我们解析PDMX数据集中的高质量子集(MuseScore网站上13181个已去重及有评分的乐谱)的MusicXML文件,并统计不同标签、属性和内容出现频次。

五线谱类型

传统上,五线谱识别按五线谱的复杂程度从低到高被分成四个级别:

  1. 单音(Monophonic):每行五线谱在任何时刻最多只有一个音在弹奏
  2. 复音(Homophonic):每行五线谱只有一个声部,但同一时刻可以有多个音在弹奏以形成和弦
  3. 复调(Polyphonic):单行五线谱上可以有多个声部,但不同五线谱间没有交互
  4. 钢琴式(Pianoform):多行五线谱,且不同五线谱间有交互
类别 乐谱数(占比) 小节数(占比)
存在和弦 9377(71.14%) 794769(14.44%)
某个五线谱有多于一个声部 7562(57.37%) 414114(7.5%)
多于一个非空五线谱 7094(53.82%) 801286(14.56%)
某个声部横跨多于一个五线谱 4039(30.64%) 127974(2.33%)
Monophonic 2928(22.21%) 4250537(77.25%)
Homophonic 4134(31.36%) 4534719(82.41%)
Polyphonic 9142(69.36%) 5374595(97.67%)
Pianoform 13181(100.00%) 5502569(100.00%)

五线谱结构

以下是部分MusicXML标签的出现频次信息(忽略了一些仅与精细格式、播放、调和分析和指法有关的标签):

  • score-partwise: 13181
    • part-list: 13181
      • score-part: 50116
    • part: 50116
      • measure: 5502569
        • attributes: 205532
          • divisions: 56612
          • key: 93644
            • cancel: 0
            • fifths: 93631
            • mode: 5272
            • key-alter: 56
            • key-step: 56
            • key-accidental: 56
          • time: 130042
            • beat-type: 130042
            • beats: 130042
          • staves: 10065
          • clef: 103464
            • sign: 103464
            • line: 103464
            • clef-octave-change: 4455
        • barline: 253709
          • bar-style: 221522
          • fermata: 634
          • ending: 47596
          • repeat: 60120
        • direction: 1315347
          • direction-type: 1353110
            • dynamics: 471719
              • f: 116036
              • ff: 54191
              • fff: 11130
              • ffff: 299
              • fffff: 64
              • ffffff: 91
              • fp: 4956
              • fz: 5669
              • mf: 68667
              • mp: 45195
              • n: 1
              • other-dynamics: 6666
              • p: 97395
              • pf: 0
              • pp: 35394
              • ppp: 5196
              • pppp: 158
              • ppppp: 137
              • pppppp: 93
              • rf: 176
              • rfz: 579
              • sf: 19544
              • sffz: 1409
              • sfp: 764
              • sfpp: 675
              • sfz: 1615
              • sfzp: 0
              • z(bad): 29
            • bracket: 7940
            • coda: 452
            • dashes: 51523
            • metronome: 60391
              • beat-unit: 60490
              • beat-unit-dot: 4453
              • per-minute: 60292
            • octave-shift: 27371
            • pedal: 230697
            • rehearsal: 9461
            • segno: 620
            • wedge: 306192
            • words: 199523
          • staff: 555983
        • note: 27972373
          • grace: 79151
          • cue: 8538
          • chord: 4211929
          • pitch: 21708073
            • step: 21708073
            • alter: 6594619
            • octave: 21708073
          • unpitched: 1266207
            • display-step: 1266207
            • display-octave: 1266207
          • rest: 4998093
            • display-step: 106425
            • display-octave: 106425
          • duration: 27893222
          • tie: 2155490
          • voice: 27972373
          • type: 25901632
          • dot: 1623818
          • accidental: 1765477
          • time-modification: 1224977
            • normal-notes: 1224977
            • normal-type: 145190
            • actual-notes: 1224977
            • normal-dot: 10
          • stem: 22492692
          • notehead: 576194
          • staff: 10877922
          • beam: 15789930
          • notations: 5909810
            • arpeggiate: 89255
            • articulations: 1934135
              • accent: 362672
              • breath-mark: 4742
              • caesura: 2480
              • detached-legato: 18267
              • doit: 514
              • falloff: 2646
              • plop: 74
              • scoop: 1705
              • soft-accent: 297
              • staccatissimo: 31757
              • staccato: 1354229
              • stress: 4
              • strong-accent: 79019
              • tenuto: 95167
              • unstress: 14
            • fermata: 42882
            • glissando: 5503
            • non-arpeggiate: 791
            • ornaments: 119816
              • accidental-mark: 205
              • inverted-mordent: 5374
              • inverted-turn: 88
              • mordent: 1545
              • schleifer: 49
              • tremolo: 92674
              • trill-mark: 18022
              • turn: 541
              • wavy-line: 7608
            • slide: 6887
            • slur: 1291923
            • technical: 286832
              • down-bow: 4317
              • fingering: 82367
              • fret: 197869
              • harmonic: 514
              • harmonic/natural: 514
              • open-string: 2252
              • pluck: 1641
              • snap-pizzicato: 6
              • stopped: 1730
              • string: 199553
              • thumb-position: 6
              • up-bow: 3374
            • tied: 2155491
            • tuplet: 644082
              • tuplet-actual: 1652
                • tuplet-number: 1652
                • tuplet-type: 1652
              • tuplet-normal: 1652
                • tuplet-number: 1652
                • tuplet-type: 1652
          • lyric: 1264164
            • syllabic: 1264164
            • text: 1267630
            • extend: 55728

记号

谱号
谱号 次数 占比 累积占比
G (𝄞) 56748 54.85% 54.85%
F (𝄢) 39929 38.59% 93.44%
percussion 3272 3.16% 96.60%
C (𝄡) 3147 3.04% 99.64%
总计 103464 100.00% 100.00%
调号
调号 次数 占比 累积占比
  20757 22.17% 22.17%
12028 12.85% 35.02%
11680 12.47% 47.49%
♯♯ 9532 10.18% 57.67%
♭♭ 9372 10.01% 67.68%
♭♭♭ 8312 8.88% 76.56%
♯♯♯ 5636 6.02% 82.58%
♭♭♭♭ 4505 4.81% 87.39%
♯♯♯♯ 4193 4.48% 91.87%
♭♭♭♭♭ 2592 2.77% 94.63%
♯♯♯♯♯ 2461 2.63% 97.26%
♭♭♭♭♭♭ 1062 1.13% 98.40%
♯♯♯♯♯♯ 961 1.03% 99.42%
♯♯♯♯♯♯♯ 379 0.40% 99.83%
♭♭♭♭♭♭♭ 161 0.17% 100.00%
总计 93631 100.00% 100.00%
音符类型

以下是不同音符类型的使用情况,可见从32分音符到全音符可以覆盖约99.41%的音符,其中八分音符最常见,其次是四分音符。

音符类型 次数 占比 累积占比
eighth 11425412 44.11% 44.11%
quarter 6414609 24.77% 68.88%
16th 4899745 18.92% 87.79%
half 1902255 7.34% 95.14%
32nd 579715 2.24% 97.38%
whole 528355 2.04% 99.41%
64th 128665 0.50% 99.91%
128th 17278 0.07% 99.98%
breve 5266 0.02% 100.00%
long 249 0.00% 100.00%
256th 55 0.00% 100.00%
1024th 22 0.00% 100.00%
512th 6 0.00% 100.00%
总计 25901632 100.00% 100.00%

手写五线谱识别

可用的资源

关于五线谱识别,存在不少论文、公开数据集和软件:

早期的五线谱识别系统依赖于许多人工设计的启发式规则,然后由于维护困难而转向更系统的模式识别技巧,例如把识别建模为某种二维语法的解析问题。近年,随着深度学习的崛起,端到端可训练的图片到序列模型逐渐流行起来。由于可以从网络上爬取大量MusicXML/MIDI之类格式的音乐并把它们渲染为图片形式的五线谱,不太需要昂贵的数据标注,使用适当的数据增强策略模拟背景、光照、相机位置等条件后也能泛化到真实拍摄的印刷体五线谱图片,这个低技术门槛路线正受到追捧。现在,不仅有不少专用的五线谱识别系统,一些通用的视觉-语言模型也已经具备一定的光学五线谱识别能力。

不过,上述方法和数据集大多针对图片形式的印刷体五线谱,关于轨迹形式手写五线谱可用的资源非常有限。由于手写的多样性,基于规则的系统往往没有足够的泛化能力。端到端可训练的编码器-解码器则一般需要较大量的训练数据,但收集和标注联机手写五线谱的成本较高,而且似乎没有已知的公开数据集,只有孤立音乐记号的HOMUS数据集包括100位音乐家写的15200个音乐符号(只覆盖32个类别,缺少很多常用的类别)。

基于图神经网络的手写五线谱识别

图神经网络容许有效地结合全局和局部的信息。初始时每个顶点和边的对应的特征可以是按特定算法计算出的人工特征,也可能是自动学习出来和特征,或者两者的结合。每一层图神经网络分别更新所有顶点和边的特征,更新一个顶点的特征时会利用所有与之相邻的顶点和边的特征,更新一条边的特征时会利用它两个端点的特征。这样,$n$层图神经网络容许一个顶点的信息被传播到与之距离至多$2^{n-1}$条边的顶点处,指数增长之快让我们用几层图神经网络就能容许对每个顶点和边做分类时可以利用相当全局的信息。最后,分类头根据各个顶点和边最终的特征进行分类。

近年来,图神经网络被用于手写轨迹相关的各种任务,包括但不限于文本行分割文本/非文本分类表格检测表格分析图表分析数学公式检测数学公式识别等等。图神经网络在这些任务上的优势在于样本效率高,可以用有限数量的样本训练出泛化能力较强的模型,而且计算量不大。我们发现,把图神经网络用于五线谱识别任务也是非常合适的。

把图神经网络用于手写轨迹的基本套路是把每条笔画分别看作顶点,再把时间或空间上相邻的笔画对应顶点间加上边从而形成图,再用图神经网络对每个顶点和边分别进行分类。通过设计适当的分类问题和使用适当的数据训练就能得到适用于不同任务的模型。首先,我们可以用图神经网络把笔画分成若干组并判断每组的类型(使用一个顶点分类头预测各顶点对应笔画所属的组的类型,而用一个边分类头预测两个顶点对应笔画是否属于同一组,则据预测结果做连通分支分析即可)。特别地,假设不同音乐记号间没有连笔,每条笔画就只属于一个音乐符号,而反过来一个音乐符号可能由一条或多条笔画组成。也就是说,我们可以把轨迹分割为若干个音乐符号并决定每个符号分别是什么。同时,我们还可以判断两个音乐符号间有没有特定的关系(加一个边分类头预测两个顶点对应笔画所属符号间有没有关系)。比如说,我们可以让图神经网络帮我们分析一个符干与哪些符头和符尾关联、一个升/降号作用于哪个音符、一条连音线连了哪些音符、一个渐强/弱记号的起止音符是什么、一个音符对应于哪条音高线等等。MUSCIMA++就提供了其中一种五线谱的图表示,但未必是最优的。

在不能收集/标注真实五线谱的情况下,可以通过对MUSCIMA++数据集进行轨迹提取来得到初始的合成数据集。适当地配置不同的数据增强策略可以进一步提高泛化能力或者增大识别范围:

  • 随机地轻微移动、扰动、缩放或形变笔画可以提高模型的抗干扰能力。
  • 随机地把部分音符符号的轨迹替换为数据集中同一符号的其它轨迹可以提高模型对不同书写风格的鲁棒性。
  • 部分或完全随机地移除部分音乐符号可以提高用户输入较短或不完整五线谱时的鲁棒性。
  • 随机插入若干音乐符号可以提高模型对较罕见符号的识别能力,缓解类别样本数高度不均衡的问题。

五线谱的图表示

为了更准确地理解如何把五线谱表示为图,这里给出一种仅支持部分常见记号的精简图表示。

顶点的类型包括:

  • G谱号(𝄞)
  • F谱号(𝄢)
  • C谱号(𝄡)
  • 4/4拍号(𝄴)
  • 2/2拍号(𝄵)
  • 降(♭)
  • 还原(♮)
  • 升(♯)
  • 重升(𝄪)
  • 全音符头(𝅝)
  • 空心符头(𝅗)
  • 实心符头(𝅘)
  • 符干
  • 符尾
  • 加线
  • 附点
  • 全休止符(𝄻)
  • 半休止符(𝄼)
  • 四分休止符(𝄽)
  • 八分休止符(𝄾)
  • 十六分休止符(𝄿)
  • 连音线
  • 渐强(𝆒)
  • 渐弱(𝆓)
  • 小节线(𝄀)

在以下情况下两个音符对应顶点间应该有边关联:

  • 符头与依附的符干
  • 符尾与依附的各符干
  • ♭/♮/♯/𝄪与它影响的符头
  • 附点与它影响的符头/休止符
  • 加线与相关的符干/全音符
  • 连音线/渐强/渐弱与它影响的各符干/全音符

进一步发展这套表示的话,图神经网络就可以帮我们提取更多信息。如果把五条谱线当作额外的顶点,并让符头与相应音高的谱线关联起来,再让谱线(包括手绘的加线)与它相邻的谱线关联起来,音高就可以被表示出来了。又如让相同时间下不同声部的音符/休止符关联起来,或者把同一声部相邻的音符/休止符关联起来,就可以更好地表示多声部的乐谱。

在相同的精神下,完全可以把它扩展至可表示绝大多数常见的五线谱。

音乐记号

识别结果的导出

虽然用图数据结构表示的五线谱方便分析,但识别后通常需要转换为常用的格式以便其它应用程序使用:

  • 设计合适的图表示应该不难被转换为MusicXML等标准的乐谱交换格式。
  • MusicXML文件可以被转换为MEI等其它乐谱格式。
  • MusicXML文件可以被导出为MIDI格式。
  • 播放器可以把MIDI文件转换为FLAC、MP3、OGG、WAV等格式的音频文件。
  • 显示库如OSMD可以把MusicXML转换为SVG格式的向量图,进而不难转换为PDF等其它向量图格式。
  • 通过渲染库可以把向量图转换为PNG、webp、GIF、JPEG、TIFF等位图格式。

下一步的工作

基于图神经网络的联机手写五线谱识别可以在可用数据相当有限的情况下支持相当广泛的乐谱类型,原则上也可以被应用于吉他六线谱、鼓谱和简谱等等。不过,对于一个强调手写的乐谱编辑器,不仅要容许用户沿用纸质乐谱书写的习惯从零开始录入乐谱,还应该容许用户利用手势高效地编辑现有的乐谱,后者也许更为重要,但比较技术性,需要与乐谱渲染库更紧密地结合。

关键词 文档分析