我正在进行一些生物声学分析并遇到了一个我认为可以用数学方法解决的问题。我将使用seewave
包中的声音样本:
library(seewave)
library(tuneR)
data(tico)
通过在R对象中存储频谱图(即声波tico
的图形表示),我们现在可以计算地处理波形文件。
s <- spectro(tico, plot=F)
class(s)
>[1] "list"
length(s)
>[1] 3
创建的对象s
包含分别代表X和Y轴的两个数值向量x = s$time
,y = s$freq
和具有相同幅度值的矩阵z = s$amp
x和y的尺寸。 Z实际上是一个3D矩阵,可以使用persp3D
(plot3D
),plot_ly
(plotly
)或plot3d
(rgl
)绘制。或者,如果希望将其视为交互式seewave
图,则可以使用rgl
在3D中绘制波形文件。
spectro3D(tico)
话虽这么说,我正在进行的分析旨在计算相对振幅的轮廓:
con <- contourLines(x=s$time, y=s$freq, z=t(s$amp), levels=seq(-25, -25, 1))
选择最长轮廓:
n.con <- numeric(length(con))
for(i in 1:length(con)) n.con[i] <- length(con[[i]]$x)
n.max <- which.max(n.con)
con.max <- con[[n.max]]
然后根据tico
:
spectro(tico, grid=F, osc=F, scale=F)
polygon(x=con.max$x, y=con.max$y, lwd=2)
现在它变得棘手了。我必须找到一种方法,使用最长轮廓s$amp
的坐标“子集”幅度值矩阵con.max
。我的目标是实现一个只包含多边形内部幅度值的新矩阵。然后光谱图的其余部分应显示为空白区域。
我可以使用的一种方法是创建一个循环,用于替换给定幅度值(例如-25 dB)的多边形外的每个值。我曾经采用类似的方法去除低于-30 dB的值,并且它完美地完成了:
for(i in 1:length(s$amp)){if(s$amp[i] == -Inf |s$amp[i] <= -30)
{s$amp[i] <- -30}}
另一种方法是使用轮廓坐标创建具有相同尺寸s$amp
,子集s$amp
的新矩阵,然后替换新矩阵上的子集。大致是:
mt <- matrix(-30, nrow=nrow(s$amp), ncol = ncol(s$amp))
sb <- s$amp[con.max$y, con.max$x]
new.mt <- c(mt, sb)
s$amp <- new.mt
我会感激任何帮助。