java - 检测一维 Java 数组中局部最大值的一般模式

标签 java android arrays graph-algorithm

我正在尝试为 Android 手机制作一个简单的音高检测应用程序。我已经让手机显示我计算出的自相关值的图表,这些值存储在一维 double 组中。现在我需要弄清楚如何检测数组中的重复模式。这是自相关图的屏幕截图,其中我以稳定的音调哼唱:

screenshot of my autocorrelation graph when humming a steady pitch

我尝试实现此幻灯片中给出的一维数组的递归峰值查找算法:http://courses.csail.mit.edu/6.006/spring11/lectures/lec02.pdf但我在 Android 上遇到内存不足错误。

接下来我尝试实现类似这样的算法来查找二阶导数:https://stackoverflow.com/a/3869172但是来自手机的自相关值非常不稳定,以至于它发现了太多的最小值和最大值。

我需要弄清楚如何做是将某种过滤器应用于自相关数据以使其平滑,但我的数学很烂,不知道该怎么做。我尝试将自相关值四舍五入到小数点后几位,但没有得到我想要的结果。

基本上,我需要帮助来弄清楚如何找到重复模式的整体最大值(实际上只有第一个可能就可以了)。在上面的屏幕截图中,该模式是一个高峰,后面跟着两个较短的峰。我需要知道第二个高峰何时发生,以便计算音高。

最佳答案

您正在尝试估计样本数据中振幅峰值的频率。您可以执行此操作,而无需手动查找估计峰值,然后计算出频率。相反,您可以使用快速傅里叶变换,它将幅度与时间的关系图转换为频率与时间的关系图。这里对这个概念有很好的描述 http://en.wikipedia.org/wiki/Fast_Fourier_transform

...并且有几个实现转换的 Java 库,包括 Apache Commons 数学 - http://commons.apache.org/proper/commons-math/apidocs/org/apache/commons/math3/transform/FastFourierTransformer.html 和 JTransform - https://sites.google.com/site/piotrwendykier/software/jtransforms

关于java - 检测一维 Java 数组中局部最大值的一般模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17628181/

相关文章:

java - 将多个类映射与给定的上下文映射 ID 关联

android - 如何使用数据绑定(bind)将数据绑定(bind)到 RecyclerView 中的一行?

java - 为什么在改造中需要 addConverterFactory

php - 使用 PDO 在 MySQL "IN"查询中多次使用相同的数组

c - 在 C : square brackets vs. 指针中传递数组

c - 在C语言中,我如何c写一个函数来打开一个csv文件并将值读入数组?

java - Android 许可证状态未知且出现奇怪的问题

java - JAVA中的JSON数组错误,并在URL中添加了反斜杠

java - 将 jars 添加到 java webapp

java - Android:找不到我的包文件夹来放置数据库文件?