基于MATLAB的简谱识别算法研究

2015-01-20 11:45束美其
电脑知识与技术 2014年36期
关键词:分割算法

束美其

摘要:该文介绍了运用MATLAB软件实现简谱识别的算法。该算法主要实现图像的预处理、分割以及匹配识别等功能,关键是对音符进行准确的分割,因为这直接影响到识别效果的好坏。

关键词:简谱识别;算法;MATLAB;分割

中图分类号:TP37 文献标识码:A 文章编号:1009-3044(2014)36-8757-03

随着数字化信息时代的到来,全球经济以前所未有的速度向前发展,同时,人们的生活水平和文化要求也越来越高,人们在各个领域的工作也更加的细化和深化,软件行业异军突起, 各种应用软件不断的得以开发并应用于工业、农业、行政、文化娱乐等行业,不仅为信息时代的人类提供了更加简洁、方便的工作和生活方式,更加使我们的生活丰富多彩。在音乐方面,各种乐谱编辑软件、音乐合成软件和音乐制作软件已经广泛地应用于音乐爱好者和专业人士的音乐工作中,在这些众多的软件中,绝大部分的音乐处理软件都是对唱谱的后期制作与处理软件,而对于乐谱的识别软件相关的却不多,乐谱识别,是相应于现代化人们对快节奏工作方式的要求而产生的,但现有的识别软件大多都存在种种的误差,实际应用性不高,能够较准确地识别出乐谱地软件更是少之又少,这就给乐谱识别的软件开发人员带来了动力与挑战,同时,乐谱识别软件的开发也具有较好的市场发展前景。

简谱,相对于五线谱而言,它书写较为简便,学习起来也比较容易,越来越多的人倾向于用简谱来创作音乐,演奏音乐,目前市场上的简谱识别软件非常少,这与简谱本身的特点有关,使得识别处理存在一些难点。因此,该文主要研究和设计了简谱识别算法。

1 算法设计与实现

1.1 设计思路

对于一张扫描到电脑中的简谱,进行识别前需要首先进行预处理,使之能够转化为易于进行数字化处理的形式。依次为中值滤波、二值化、细化处理,如前所述,中值滤波可以较好的去除图片中的椒盐噪声,二值化将待处理音符提取出来,细化处理很好的保留了音符的形状、边界特征,这对于后续的识别是大有好处的。本识别系统中最重要的一步就是准确地分割出简谱中的每个音符,分割的准确与否直接影响到识别效果的好坏,我们采用水平投影、垂直投影并以零为阈值分割出每行和每列,再次利用水平和垂直投影分割出单个音符,之后即可进行单个音符及其它符号的识别,这里需要注意的是需要用到多重循环,其嵌套关系是逐步递进的。总而言之,即先分割,每分割出一个音符就进行一次识别,然后对该字符附近几个区域进行搜索其它符号的算法,每识别出一个音符赋一次值。其流程图如图1。

图1 简谱识别的基本流程

1.2 简谱的分割算法

在本系统中,我们对简谱用了四次分割:1) 水平投影(针对整篇简谱)——行分割;2) 垂直投影(针对每行)——列分割;3) 水平投影(针对每列)——音符高度的分割;4) 垂直投影(针对2和3截出的区域)——音符宽度的分割。

第一次对整篇细化后的简谱进行水平投影,可以划分出每行的高度,这里的高度一般就是小节线的高度(记为higth(u),u为行数),当然,若该行中存在高低音点或减时线的话,水平投影后还会分割出距离较小的行高度,一般其值不超过5,这样的行是没有意义的,因为它不包含音符,所以在进行第二次每行的垂直分割之前,须进行一次判断,即若该行的高度是大于5的,才对该行进行后面的垂直投影分割,小于等于5的情况不作处理;

第二次对每行进行垂直投影,可以划分出每列的最大宽度(width(h),h为列数),这里的最大宽度可能是单个音符的宽度,也可能是带有减时线的组合音符的宽度;

经过两次分割,截出的图象区域的高度不是准确的字符高度,宽度也可能不是单个音符的宽度(不带减时线的情况下可以分割出单个音符的宽度),因此,有必要再次确定音符的准确高度和宽度;

第三次水平投影,是对第二次分割出的每列进行的,这样得到的高度值中可能也包含距离较小的高度(可能包含减时线),又因为音符的准确高度只能为一个值,所以我们可对分割出的高度higth1取最大值即:maxhigth1=max(higth1),即是单个字符的确切高度;

第四次分割是以第二次分割出的每个宽度width(h)为宽度,以第三次分割出的maxhigth1为高度,进行垂直投影,这样就可以把组合音符也分割开来。

至此,每个音符都可以被依次分割出来,依次识别。具体的分割算法如下(以第一次分割为例):

y2=sum(bowa')';%每行象素值求和

T1=0; %分割阈值

i=1,j=1;

for k=1:m-1

if y2(k)<=T1&y2(k+1)>T1

h1(i)=k; %灰度上升点

i=i+1;

end

if y2(k)>T1&y2(k+1)<=T1

h2(j)=k+1+1; %灰度下降点

j=j+1;

end

end

higth=h2-h1; %分割出每行的高度

其中,bowa是做过细化后的二值图像,y2是每行像素值之和,m是该简谱图像的行数。经过该算法处理后,就可以得到准确的行高度和位置。其它三次分割算法与此类似。

1.3 音符及各种符号的识别算法

基图的识别算法及流程:分割出单个音符后,首先要对其归一化,即经过放缩、线形插值算法处理,使其成为与模版相同的大小,这样与模版进行匹配识别才能达到较准确的匹配比较结果。归一化之后是图像的匹配识别处理,这里模版的选取也是要值得注意的,因为平常扫描的简谱字符属于印刷体,印刷体虽然比手写体规范许多,但是也会因印刷体的版本、大小不同有所区别。大小不同可以经过归一化处理转化为规定大小;版本不同,但是音符的书写的特点并未改变,所以采用模糊模版匹配的识别方法,即让分割出的音符矩阵与模版矩阵做差并求和,认为与模版误差最小的音符就是该模版所代表的音符。定义模版之前,需要查阅大量的简谱,统计其音符的特点,之后选取与大部分音符特征最为相近的数字作为模版数字。这里模版的定义是:对模版数字1、2、3、4、5、6、7、0同样放缩到规定大小,它们依次存放在一个矩阵中。进行模版匹配时,要让分割出的每个音符分别与每个数字模版进行一次差值比较,对各差值取绝对值,这样得到8个差值,再对这8个差值求最小值,那么该最小值对应的模版数字就是该音符的识别结果。

混合图的识别算法及流程: 在简谱中,存在着大量的组合音符,如图2(a)图中前四个音符就属于一个组合音符,(b)图中前三个是一个组合音符,后两个也是一个组合音符。

(a) (b)

图2 混合图的识别举例

由图2可以看出,组合音符一般都包含减时线,使多个音符组成一个整体。如何识别这些复杂的组合音符呢?我们采用了先分割,再识别的方法,即在第一次水平分割,垂直分割的基础上再次进行一次水平分割和一次垂直分割,有前所述,对于单个音符,第一次的分割可以得到准确的音符宽度和上下带有空余的音符高度,在此基础上进行第二次水平分割就可得到准确的音符高度。但对于组合音符,在第二次水平投影分割后得到的是准确的已去除减时线的组合音符的高度和宽度,并未分割出单个音符,因此必须再次进行垂直投影分割。这样,整个简谱经过两次水平投影分割,两次垂直投影分割就可以准确地分割出单个音符了。

在最后一次列分割完成后,得到一个存放音符的数组,该数组中可能只有一个音符(对应于单个音符的情况),也可能包含若干个音符(对应于组合音符的情况),接下来对该数组中的每个音符要进行识别判断,若该列的宽度是小于或等于5的,则不满足音符条件,属于附点,进行下一列的处理,否则满足音符条件就进行音符的匹配识别。

各种符号的识别算法: 对简谱中的小节线、延时线、高、低音点和附点的识别,我们都采用了阈值判别法,因为细化处理给我们带来的很大的好处就是小节线、延时线在理想情况下都被细化成宽度或高度为1个像素值,经过统计,即使不太理想的情况下其投影宽度也不会超过5,而附点的有无是通过计算特定区域内的像素不为零的点的个数(pointcnt),经过统计,可定其阈值范围为0

对小节线的判别是判断它的宽度是否是<=5,是则不处理,否则进行延时线的判别;

对延时线是判断它的高度是否是<=5的,是则对其前一个音符作延时线标记,否则可判定它满足音符的条件,进行音符识别处理;

对高低音点和附点有无的判断是在识别完该音符后,再在该音符的上方、下方、右方的某一特定区域内搜索不为零的像素个数,如果个数是大于0且小于或等于4的话就说明存在,并对该音符进行高低音点、附点标记;

高音点的搜索区域(point1) 是这样定义的:高度的行起点为从该音符的行起点值减去该音符的高度,行终点为该音符的行起点;宽度就是该音符的宽度,并与之列的起点和终点对齐。低音点的搜索区域与高音点的搜索区域(point2) 相对应,如下代码实现的便是高、低音点的识别:

p1=h11-maxhigth1;

p2=h22+maxhigth1;

if p1<=0

p1=1;

end %越界处理

if p2>=m

p2=m;

end

point1=(bowa(p1:h11,w11(t):w22(t)));

point2=(bowa(h22:p2,w11(t):w22(t)));

point1cnt=find(point1);[point1cnt,d]=size(point1cnt);

point2cnt=find(point2);[point2cnt,d]=size(point2cnt);

if point1cnt>0 & point1cnt<=4

flag=1;

point(count)=3; %高低音点的识别

else

flag=0;

end

if flag==0

if point2cnt>0 & point2cnt<=4

point(count)=1;

flag=1;

else

flag=0;

end

end

if flag==0

point(count)=2;

end

上述代码中用到了越界处理,这在处理点的运算时经常要用到,在搜索区域中寻找像素值不为零的个数,判断是否在0~5之间,若是,则表示有高或低音点,否则没有,注意这里高低音点的表示用的是数组point(count),由高音点,point(count)=3;有低音点,point(count)=1;两者都不存在,point(count)=2;这些将作为识别结果的四位代码的首位。同时,在代码中,高低音点的识别采用相并行的处理方法,即若首先判断出该音符有高音点,则不用再去执行低音点的识别程序,这样既可简化识别过程,又符合逻辑。

附点的识别区域的高度定义为pointhigth=round(3/4*maxhigth1),宽度为该音符宽度的列终点加上pointhigth。识别过程与高低音点的识别相似,这里不再赘述。

对减时线的识别采用的是穿线法判别,即通过计算音符正下方一定区域内竖直方向上灰度突变的次数总和并求均值,四舍五入取整后,若统计结果是2,则表明该音符下方有一条减时线;若统计结果是4,则表明该音符下方有两条减时线,若统计结果为0则表明该音符下方没有减时线

2 运行结果

识别结果由一个四位的代码来表示,有前所述,第一位代表音符是否含有高低音点,有高音点用3表示,有低音点用1表示,两者都没有用2表示;第二位代表的是具体的识别音符,用“x6”表示,其中“x”就是识别的音符(0~7) ,6这一位是与声音库中的代码相对应的;最后一位代表的是音符的节拍,用阿拉伯数字0~9表示,识别结果的赋值语句如下:

result(count)=

point(count)*1000+Reconga(count)*10+resultpai(count)

在上式中,point(count)标记了高低音点的数值,Reconga(count)标记了识别出的具体音符,resultpai(count)标记了音符的节拍数值,这就是说,每个音符的识别结果包含了:音的高低、具体的音节、以及音符的节拍。并且每识出一个音符就记一个结果到数组result,并将其数组元素的个数加1。

该算法实现了对于一般简谱的识别功能,经统计,识别率达87%左右。易发生识别错误的情况,多是对于高低音点、附点的识别,由于本算法最终没有用到中值滤波,因而对于简谱图像上的较小的噪声点没有去除,使得噪声点易于同简谱中的圆点混淆。这是因为用到本算法用到了细化处理,如果先对整篇简谱进行中值滤波,由于中值滤波是对该像素点相邻的8个像素点取中间的像素点的值,而很多时候两条减时线之间仅相隔一个像素点的间隔,则许多情况下两条减时线就会被合成一条粗线,再经细化处理就成为一条细线了 ,那么经过穿线法统计的话,就会判断成一条减时线,从而导致识别节拍的错误,如果进行中值滤波,那么简谱上的噪声能够被较好的去除,高低音点和附点的识别率也会上升。在个别情况下,某几个数字的识别也容易发生识别错误,比如有时5会被识别成3,2有时会被识别成7,当然,这也和具体的扫描上的简谱的清晰度有关,也和模版选取的合适与否有一定的关系。

3 算法改进

1) 找到合适的去噪方法

本算法在一开始确定用中值滤波去噪,是有一定的理论根据的,但是对于简谱这种具体情况,中值滤波的处理会影响到减时线的识别。因此,找到一种合适的去噪算法,使之既可以较好的去除图像上的椒盐噪声点,又不会影响减实线的个数。

2) 附点搜索的改进算法

本算法对于附点的搜索是在音符的右边,以该音符宽度的列终点为搜索区域的列起点,宽度为该音符高度的3/4左右,搜索区域的高度也为该音符高度的3/4左右,对于一般的情况是可以正确识别出附点的。但是,有时候两个音符间的间隔会很短,甚至不到音符高度的3/4,这样的话附点的搜索区域中会包含许多的非零像素点,导致识别结果为没有附点,产生错误。因此,可以改进算法为,将在音符右边的固定大小区域内搜索附点改为在该音符与下一个音符之间的区域中搜索附点,该区域的宽度的起点不变,宽度的计算变为2/3*(两音符的间距),这样搜索区域的大小是可变的,是随着音符的间距的变化而变化,这样就避免了区域划分可能不准确的问题。

3) 对于易混淆音符的区分识别

由于各种各样的因素干扰,使得识别结果总存在一定的误差,比如3与5可能会发生混淆,这样可以考虑一种补偿识别算法,即当识别结果为3或5,就对该音符以另一种方法进行识别,比如穿线法,得到穿线的统计值以区别是否识别正确。

4) 用小节线来验证识别节拍的正确与否

本算法对于小节线没有进行任何处理,然而可以考虑一种验证节拍算法,通过小节线的出现,来验证上一小节的拍子是否正确,如果不正确就说明上一小节的节拍识别有错,不过在识别一开始就要对该简谱的节拍标记进行识别,以确定每一小节应该有几拍。

4 结束语

本文基于MATLAB软件给出了简谱识别的算法,包括对图像的预处理、图像分割和图像的匹配识别等算法。经过去噪、二值化、细化等一系列预处理步骤,再利用投影法进行准确的字符分割,最后对满足数字条件的单个音符进行模糊匹配识别。这里,对于每个数字识别完成后,要进行高低音点,附点和减时线的识别。对于高低音点和符点的识别,我们采用的是一种区域搜索算法,对于减时线我们采用的是穿线法识别算法。实验结果表明,对于一般的简谱,能够达到较准确的识别结果。

参考文献:

[1] 张宏林.Visual C++数字图像模式识别技术及工程实践[M].人民邮电出版社,2003:1-8.

[2] 朱虹.数字图像处理基础[M].科学出版社,2005:1-6.

[3] 徐飞,施晓红. MATALB应用图像处理[M].西安电子科技大学出版社,2002:29-45.endprint

result(count)=

point(count)*1000+Reconga(count)*10+resultpai(count)

在上式中,point(count)标记了高低音点的数值,Reconga(count)标记了识别出的具体音符,resultpai(count)标记了音符的节拍数值,这就是说,每个音符的识别结果包含了:音的高低、具体的音节、以及音符的节拍。并且每识出一个音符就记一个结果到数组result,并将其数组元素的个数加1。

该算法实现了对于一般简谱的识别功能,经统计,识别率达87%左右。易发生识别错误的情况,多是对于高低音点、附点的识别,由于本算法最终没有用到中值滤波,因而对于简谱图像上的较小的噪声点没有去除,使得噪声点易于同简谱中的圆点混淆。这是因为用到本算法用到了细化处理,如果先对整篇简谱进行中值滤波,由于中值滤波是对该像素点相邻的8个像素点取中间的像素点的值,而很多时候两条减时线之间仅相隔一个像素点的间隔,则许多情况下两条减时线就会被合成一条粗线,再经细化处理就成为一条细线了 ,那么经过穿线法统计的话,就会判断成一条减时线,从而导致识别节拍的错误,如果进行中值滤波,那么简谱上的噪声能够被较好的去除,高低音点和附点的识别率也会上升。在个别情况下,某几个数字的识别也容易发生识别错误,比如有时5会被识别成3,2有时会被识别成7,当然,这也和具体的扫描上的简谱的清晰度有关,也和模版选取的合适与否有一定的关系。

3 算法改进

1) 找到合适的去噪方法

本算法在一开始确定用中值滤波去噪,是有一定的理论根据的,但是对于简谱这种具体情况,中值滤波的处理会影响到减时线的识别。因此,找到一种合适的去噪算法,使之既可以较好的去除图像上的椒盐噪声点,又不会影响减实线的个数。

2) 附点搜索的改进算法

本算法对于附点的搜索是在音符的右边,以该音符宽度的列终点为搜索区域的列起点,宽度为该音符高度的3/4左右,搜索区域的高度也为该音符高度的3/4左右,对于一般的情况是可以正确识别出附点的。但是,有时候两个音符间的间隔会很短,甚至不到音符高度的3/4,这样的话附点的搜索区域中会包含许多的非零像素点,导致识别结果为没有附点,产生错误。因此,可以改进算法为,将在音符右边的固定大小区域内搜索附点改为在该音符与下一个音符之间的区域中搜索附点,该区域的宽度的起点不变,宽度的计算变为2/3*(两音符的间距),这样搜索区域的大小是可变的,是随着音符的间距的变化而变化,这样就避免了区域划分可能不准确的问题。

3) 对于易混淆音符的区分识别

由于各种各样的因素干扰,使得识别结果总存在一定的误差,比如3与5可能会发生混淆,这样可以考虑一种补偿识别算法,即当识别结果为3或5,就对该音符以另一种方法进行识别,比如穿线法,得到穿线的统计值以区别是否识别正确。

4) 用小节线来验证识别节拍的正确与否

本算法对于小节线没有进行任何处理,然而可以考虑一种验证节拍算法,通过小节线的出现,来验证上一小节的拍子是否正确,如果不正确就说明上一小节的节拍识别有错,不过在识别一开始就要对该简谱的节拍标记进行识别,以确定每一小节应该有几拍。

4 结束语

本文基于MATLAB软件给出了简谱识别的算法,包括对图像的预处理、图像分割和图像的匹配识别等算法。经过去噪、二值化、细化等一系列预处理步骤,再利用投影法进行准确的字符分割,最后对满足数字条件的单个音符进行模糊匹配识别。这里,对于每个数字识别完成后,要进行高低音点,附点和减时线的识别。对于高低音点和符点的识别,我们采用的是一种区域搜索算法,对于减时线我们采用的是穿线法识别算法。实验结果表明,对于一般的简谱,能够达到较准确的识别结果。

参考文献:

[1] 张宏林.Visual C++数字图像模式识别技术及工程实践[M].人民邮电出版社,2003:1-8.

[2] 朱虹.数字图像处理基础[M].科学出版社,2005:1-6.

[3] 徐飞,施晓红. MATALB应用图像处理[M].西安电子科技大学出版社,2002:29-45.endprint

result(count)=

point(count)*1000+Reconga(count)*10+resultpai(count)

在上式中,point(count)标记了高低音点的数值,Reconga(count)标记了识别出的具体音符,resultpai(count)标记了音符的节拍数值,这就是说,每个音符的识别结果包含了:音的高低、具体的音节、以及音符的节拍。并且每识出一个音符就记一个结果到数组result,并将其数组元素的个数加1。

该算法实现了对于一般简谱的识别功能,经统计,识别率达87%左右。易发生识别错误的情况,多是对于高低音点、附点的识别,由于本算法最终没有用到中值滤波,因而对于简谱图像上的较小的噪声点没有去除,使得噪声点易于同简谱中的圆点混淆。这是因为用到本算法用到了细化处理,如果先对整篇简谱进行中值滤波,由于中值滤波是对该像素点相邻的8个像素点取中间的像素点的值,而很多时候两条减时线之间仅相隔一个像素点的间隔,则许多情况下两条减时线就会被合成一条粗线,再经细化处理就成为一条细线了 ,那么经过穿线法统计的话,就会判断成一条减时线,从而导致识别节拍的错误,如果进行中值滤波,那么简谱上的噪声能够被较好的去除,高低音点和附点的识别率也会上升。在个别情况下,某几个数字的识别也容易发生识别错误,比如有时5会被识别成3,2有时会被识别成7,当然,这也和具体的扫描上的简谱的清晰度有关,也和模版选取的合适与否有一定的关系。

3 算法改进

1) 找到合适的去噪方法

本算法在一开始确定用中值滤波去噪,是有一定的理论根据的,但是对于简谱这种具体情况,中值滤波的处理会影响到减时线的识别。因此,找到一种合适的去噪算法,使之既可以较好的去除图像上的椒盐噪声点,又不会影响减实线的个数。

2) 附点搜索的改进算法

本算法对于附点的搜索是在音符的右边,以该音符宽度的列终点为搜索区域的列起点,宽度为该音符高度的3/4左右,搜索区域的高度也为该音符高度的3/4左右,对于一般的情况是可以正确识别出附点的。但是,有时候两个音符间的间隔会很短,甚至不到音符高度的3/4,这样的话附点的搜索区域中会包含许多的非零像素点,导致识别结果为没有附点,产生错误。因此,可以改进算法为,将在音符右边的固定大小区域内搜索附点改为在该音符与下一个音符之间的区域中搜索附点,该区域的宽度的起点不变,宽度的计算变为2/3*(两音符的间距),这样搜索区域的大小是可变的,是随着音符的间距的变化而变化,这样就避免了区域划分可能不准确的问题。

3) 对于易混淆音符的区分识别

由于各种各样的因素干扰,使得识别结果总存在一定的误差,比如3与5可能会发生混淆,这样可以考虑一种补偿识别算法,即当识别结果为3或5,就对该音符以另一种方法进行识别,比如穿线法,得到穿线的统计值以区别是否识别正确。

4) 用小节线来验证识别节拍的正确与否

本算法对于小节线没有进行任何处理,然而可以考虑一种验证节拍算法,通过小节线的出现,来验证上一小节的拍子是否正确,如果不正确就说明上一小节的节拍识别有错,不过在识别一开始就要对该简谱的节拍标记进行识别,以确定每一小节应该有几拍。

4 结束语

本文基于MATLAB软件给出了简谱识别的算法,包括对图像的预处理、图像分割和图像的匹配识别等算法。经过去噪、二值化、细化等一系列预处理步骤,再利用投影法进行准确的字符分割,最后对满足数字条件的单个音符进行模糊匹配识别。这里,对于每个数字识别完成后,要进行高低音点,附点和减时线的识别。对于高低音点和符点的识别,我们采用的是一种区域搜索算法,对于减时线我们采用的是穿线法识别算法。实验结果表明,对于一般的简谱,能够达到较准确的识别结果。

参考文献:

[1] 张宏林.Visual C++数字图像模式识别技术及工程实践[M].人民邮电出版社,2003:1-8.

[2] 朱虹.数字图像处理基础[M].科学出版社,2005:1-6.

[3] 徐飞,施晓红. MATALB应用图像处理[M].西安电子科技大学出版社,2002:29-45.endprint

猜你喜欢
分割算法
基于MapReduce的改进Eclat算法
Travellng thg World Full—time for Rree
进位加法的两种算法
基于增强随机搜索的OECI-ELM算法
一种改进的整周模糊度去相关算法