[Arduino]用arduino做声音分类
本文最后更新于 667 天前,其中的信息可能已经有所发展或是发生改变。

Arduino,一个MCU设备,处理能力是非常差的,但是其实它是有办法实现声音识别的。

翻github发现了一个大佬就做了这个项目。

github博客链接:https://eloquentarduino.github.io/2019/12/word-classification-using-arduino/

不过,由于是一个歪果仁写的,有点难看得懂,这里简单跟大家讲讲,同时对代码的大部分注释也改成了中文,方便理解。

正式开始

采集声音

将一个模拟口的麦克风接到arduino上面,这个谁都会吧。。。刷入代码(请自行修改mic端口以及声音阈值)

//Arduino做声音分类 by eloquentarduino 部分注释及代码由小草修改

#include <arduinoFFT.h> //傅里叶变换头文件,需要先在IDE库管理器中安装

//#include "model.h"  //以数据训练出来的模型头文件,未生成模型数据前注释掉

#define MIC A0  //麦克风接到模拟口0
#define NUM_SAMPLES 32    //因傅里叶变换的所限,采样数必须是2的倍数
#define SAMPLING_FREQUENCY 1024 //采样频率
#define INTERVAL 5       //间隙 
#define SOUND_THRESHOLD 3 //声音阈值,采集到的声音大小减去背景噪音大小超过这个值才记录,根据mic的灵敏度设定

unsigned int samplingPeriod;    //采样时间
unsigned long microSeconds;   //微秒

int32_t backgroundSound;      //背景声
double features[NUM_SAMPLES]; //特征向量大小,就是每次声音采样多少个值
arduinoFFT fft;   //创建一个快速傅里叶变换实例

String Q;

//Eloquent::ML::Port::RandomForest classifier;  //创建一个分类器实例(类定义在“model.h”文件中)。训练后才需要用,获取数据时注释掉

void setup() {    //硬件参数设定
    Serial.begin(115200);
    Q = "d";

    samplingPeriod = round(100000*(1.0/SAMPLING_FREQUENCY));   // 1000000/1024,采样时间约1秒
    calibrate();      //校正背景噪音

}

void loop() {
    //digitalWrite(8,HIGH);
    if (!soundDetected()) {
        delay(10);
        return;
    }
    
    captureWord();

    printFeatures();    //打印声音特征向量,采集数据时去掉注释

// uncomment when doing classification
    //Serial.print("You said ");
    //Serial.println(Q);
    //delay(1000);

}

/**

    Get analog readings 读取mic的声音值,原来范围0-1023不适合用作快速傅里叶变换(FFT),于是减512
    @return
    */
int16_t readMic() {   
    return analogRead(MIC);
    return (analogRead(MIC) - 512) >> 2;
}

/**

    Get "ambient" volume 循环200次获取背景噪音均值
    */
void calibrate() {
    for (int i = 0; i < 200; i++)
        backgroundSound += readMic();

    backgroundSound /= 200;

    Serial.print("Threshold set at ");
    Serial.println(backgroundSound);
}

bool soundDetected() {    //判断是否有在说话,若Mic检测到的声音减去底噪后大于设定阈值,则说明有人说话
    return abs(readMic() - backgroundSound) >= SOUND_THRESHOLD;
}

void captureWord() {    //采集字词语音,每个词的特征采集次数取决于设定的变量NUM_SAMPLES
    for (uint16_t i = 0; i < NUM_SAMPLES; i++) {
        microSeconds = micros();
        features[i] = readMic();

        while(micros() < (microSeconds + samplingPeriod));
    }

    fft.Windowing(features, NUM_SAMPLES, FFT_WIN_TYP_HAMMING, FFT_FORWARD);   //采集到的声音信息进行FFT特征提取

}

void printFeatures() {      //打印声音采样特征到串口,把这些特征值保存为CSV文件,一种声音一个文件
    const uint16_t numFeatures = sizeof(features) / sizeof(double);

    for (int i = 0; i < numFeatures; i++) {
        Serial.print(features[i]);
        Serial.print(i == numFeatures - 1 ? '\n' : ',');
    }

}

然后新建一个csv文件,将数据保存进去,这里放一个示例。

2.48,2.50,3.40,4.55,5.80,8.31,10.65,13.64,16.34,19.66,24.51,27.11,28.45,31.09,33.28,31.92,29.93,30.35,28.27,25.78,23.83,21.53,19.00,16.34,13.64,11.79,9.20,6.92,5.04,3.75,2.86,2.40
2.56,2.86,3.75,4.87,6.47,8.31,10.65,13.64,17.46,20.97,25.25,27.11,27.56,27.32,28.39,28.93,29.93,30.35,29.21,27.56,25.47,23.02,20.31,17.46,14.11,11.03,8.60,6.47,4.87,3.64,2.86,2.56
2.16,2.50,3.40,4.87,7.14,10.09,12.93,16.93,20.28,22.94,24.51,25.47,26.67,27.32,27.41,27.93,26.94,26.43,26.38,26.67,25.47,24.51,22.28,19.72,16.46,13.31,9.79,6.92,4.87,3.40,2.50,2.24
2.80,3.04,3.87,5.20,6.92,9.20,11.03,13.17,15.77,18.35,21.53,24.65,26.67,29.21,31.32,32.92,32.92,32.30,31.09,28.45,25.47,22.28,19.00,15.77,13.17,10.65,8.31,6.47,4.71,3.52,2.77,2.56
2.64,2.77,3.52,4.71,6.25,8.31,10.65,13.64,16.90,20.31,23.02,26.29,28.45,31.09,32.30,30.93,30.93,29.37,27.32,25.78,23.00,20.79,19.00,16.90,14.11,11.41,9.49,7.36,5.36,3.99,2.86,2.48
2.56,2.86,3.64,4.71,6.69,8.90,11.41,14.11,16.34,19.00,22.28,24.65,25.78,28.27,29.37,30.93,31.92,33.28,32.98,28.45,24.65,20.05,19.00,15.21,13.17,11.79,9.49,7.81,5.52,3.99,2.86,2.40
2.56,2.77,3.17,4.55,6.02,8.60,12.17,15.52,19.15,21.62,24.51,24.65,27.56,27.32,28.39,28.93,28.93,29.37,29.21,28.45,27.93,24.51,20.31,16.34,13.17,10.65,8.31,6.69,4.87,3.64,2.77,2.48
2.48,2.77,3.64,4.87,6.47,8.60,10.65,12.70,15.77,18.35,22.28,25.47,25.78,28.27,29.37,31.92,32.92,32.30,31.09,29.34,28.75,23.76,20.31,16.90,13.17,10.65,8.31,6.69,4.71,3.52,2.77,2.48
2.80,3.04,3.75,5.04,6.69,8.90,11.03,13.17,15.21,17.69,20.79,23.83,27.56,27.32,29.37,28.93,30.93,32.30,32.03,30.23,27.11,25.99,22.28,18.59,14.58,11.03,8.31,6.02,4.71,3.40,2.59,2.40
2.88,3.22,4.10,5.36,6.92,8.60,10.65,12.70,15.21,18.35,20.79,22.18,24.89,27.32,30.35,31.92,33.92,33.28,33.92,32.01,29.58,25.25,21.62,17.46,14.11,10.65,8.31,6.02,4.39,3.28,2.50,2.32
2.72,2.86,3.64,4.87,6.47,8.60,11.03,13.64,15.77,19.00,23.02,26.29,29.34,32.03,32.30,31.92,30.93,30.35,28.27,25.78,23.00,20.79,18.35,16.90,14.58,11.79,9.20,6.92,5.04,3.75,2.77,2.48
2.56,2.86,3.75,5.04,6.92,9.20,11.41,14.11,16.90,19.66,22.28,24.65,26.67,28.27,29.37,29.93,29.93,29.37,28.27,26.67,24.65,23.02,20.31,18.03,14.58,11.41,8.60,6.47,4.71,3.40,2.59,2.32
2.72,2.95,3.75,5.04,6.92,8.90,11.41,13.17,15.77,18.35,21.53,23.83,26.67,28.27,29.37,30.93,31.92,31.32,30.15,27.56,24.65,21.53,19.66,16.34,14.11,12.17,9.49,6.92,5.04,3.64,2.86,2.56
2.48,2.50,3.28,4.55,6.69,8.90,11.03,13.17,16.34,19.66,23.76,27.93,29.34,30.15,29.37,30.93,31.92,30.35,27.32,25.78,23.83,21.53,19.66,16.90,14.11,12.17,9.79,7.81,5.52,3.75,2.59,2.24
2.56,2.77,3.40,4.55,6.25,8.60,11.03,14.11,17.46,21.62,25.99,27.93,30.23,30.15,29.37,28.93,28.93,27.41,26.38,25.78,24.65,23.76,21.62,18.59,15.52,12.17,9.20,6.47,4.71,3.40,2.59,2.32
2.72,2.86,3.75,5.04,6.47,8.60,10.65,13.17,15.77,19.00,21.53,24.65,27.56,30.15,32.30,32.92,32.92,31.32,30.15,27.56,25.47,22.28,19.00,15.77,13.17,10.65,8.31,6.47,4.87,3.75,2.95,2.72
2.64,2.77,3.64,4.87,6.69,8.90,11.79,13.64,16.34,19.00,22.28,24.65,26.67,29.21,31.32,31.92,31.92,31.32,30.15,26.67,25.47,22.28,19.66,16.90,13.17,10.65,8.60,6.92,4.87,3.64,2.77,2.56
2.48,2.68,3.40,4.55,6.47,8.60,11.41,13.64,17.46,20.31,23.02,25.47,24.89,27.32,27.41,29.93,31.92,32.30,32.98,27.56,25.47,23.02,19.00,16.34,13.17,10.65,8.60,6.92,5.36,3.87,3.13,2.56
2.56,2.68,3.52,4.71,6.25,8.31,10.65,13.17,15.77,19.00,22.28,25.47,28.45,30.15,32.30,32.92,31.92,31.32,30.15,28.45,24.65,22.28,19.66,16.34,14.11,11.41,8.90,6.69,5.04,3.64,2.77,2.40
2.64,3.13,3.99,5.36,7.14,9.20,11.03,13.17,15.77,18.35,21.53,24.65,26.67,28.27,30.35,29.93,29.93,29.37,26.38,24.89,23.83,21.53,20.31,18.03,15.99,12.93,10.09,7.58,5.04,3.75,2.68,2.32
2.24,2.41,3.28,4.71,6.92,9.49,12.17,16.93,19.72,23.59,26.73,27.11,27.56,28.27,28.39,26.94,26.94,25.45,24.50,25.78,23.83,23.02,20.97,17.46,14.11,11.79,9.20,6.92,5.52,3.87,3.04,2.64
2.72,3.13,3.52,4.87,6.02,8.01,9.89,12.23,15.21,17.69,23.76,24.65,27.56,30.15,29.37,30.93,31.92,33.28,31.09,32.89,27.93,23.02,21.62,15.21,13.17,10.27,7.71,6.25,4.39,3.52,2.68,2.88
2.56,2.68,3.52,4.55,6.25,8.60,11.41,14.11,17.46,19.66,22.28,24.65,26.67,28.27,30.35,30.93,31.92,31.32,30.15,27.56,25.47,22.28,19.00,16.34,13.17,11.03,8.90,6.92,5.20,3.87,2.95,2.56
2.64,2.95,3.75,5.04,6.69,8.60,10.27,12.70,15.21,19.00,23.76,27.93,31.12,32.98,32.30,30.93,29.93,28.39,26.38,24.89,23.83,20.79,19.00,15.77,13.17,11.41,9.20,7.14,5.52,4.10,3.04,2.64
2.08,2.41,3.40,4.87,7.36,10.09,13.31,16.46,19.15,21.62,22.28,23.00,24.00,25.44,27.41,28.93,30.93,31.32,32.03,31.12,28.75,25.25,21.62,18.03,15.05,11.03,8.31,6.02,4.22,3.17,2.50,2.32
2.64,2.95,3.87,5.04,6.47,8.60,10.65,12.70,15.21,18.35,20.79,24.65,27.56,31.09,34.26,34.92,34.92,34.26,31.09,28.45,24.65,20.79,17.69,15.21,13.17,10.65,8.90,6.69,5.20,3.99,3.04,2.72
2.48,2.68,3.52,4.55,6.25,8.31,11.03,13.64,17.46,19.66,23.76,27.11,28.45,30.15,30.35,29.93,29.93,28.39,26.38,24.89,23.00,21.53,18.35,16.34,14.11,11.79,9.49,7.58,5.52,4.10,3.13,2.64
2.72,2.95,3.64,4.71,6.47,8.31,10.27,12.70,15.21,18.35,20.79,24.65,27.56,30.15,32.30,32.92,32.92,33.28,30.15,26.67,24.65,20.79,18.35,15.77,13.17,11.03,8.90,7.14,5.36,4.22,3.13,2.80
2.72,2.95,4.22,5.85,6.92,8.60,11.41,13.64,15.21,17.04,20.05,23.00,26.67,29.21,30.35,32.92,34.92,34.26,33.92,30.23,26.29,23.76,19.00,15.77,12.70,9.89,7.71,6.02,4.55,3.52,2.86,2.64
2.16,2.50,3.28,4.55,6.47,9.20,12.55,16.93,20.84,24.25,25.25,27.11,27.56,26.38,26.43,25.94,24.94,24.47,24.50,25.78,25.47,23.76,22.28,19.72,16.93,14.07,11.27,8.03,5.36,3.87,2.68,2.32
2.64,3.04,3.99,5.36,7.14,8.90,11.03,13.64,16.90,20.31,22.28,24.65,25.78,28.27,30.35,30.93,29.93,29.37,30.15,30.23,27.11,23.02,19.66,16.90,13.64,11.03,8.60,6.25,4.87,3.64,2.86,2.56
2.80,2.77,3.64,4.87,6.25,8.60,10.65,13.17,16.90,20.31,22.28,24.65,29.34,31.09,31.32,32.92,32.92,33.28,31.09,28.45,25.47,21.53,18.35,14.65,12.23,10.27,8.01,6.02,4.71,4.10,3.40,2.72
2.16,2.59,3.40,5.52,9.15,10.98,13.31,15.05,16.90,19.00,20.79,21.36,23.11,29.21,30.35,30.93,29.93,28.39,27.32,26.67,24.65,22.28,20.97,16.90,17.40,15.21,9.20,6.69,4.55,3.17,2.41,2.40
2.72,2.77,3.40,4.39,6.02,8.01,11.03,14.58,19.15,20.97,23.02,24.65,24.00,27.32,28.39,31.92,32.92,34.26,36.75,28.45,27.93,22.28,17.04,14.08,12.23,11.03,9.49,8.48,5.69,4.57,3.13,2.56
2.56,2.77,3.64,5.04,6.69,9.20,11.41,14.11,17.46,19.00,22.28,25.47,26.67,27.32,29.37,29.93,29.93,29.37,28.27,27.56,25.47,22.28,19.00,17.46,14.11,11.03,8.90,6.69,4.87,3.52,2.68,2.48
1.84,2.06,2.81,4.06,5.80,8.01,10.65,13.64,17.46,20.97,24.51,27.11,29.34,31.09,31.32,29.93,28.93,28.39,25.44,24.00,21.36,20.05,17.69,15.21,13.17,11.03,8.60,6.69,4.87,3.64,2.77,2.56
2.08,2.32,2.81,4.22,6.02,8.60,11.41,14.58,17.46,21.62,24.51,26.29,28.45,31.09,35.24,33.92,31.92,34.26,32.98,31.12,27.11,24.51,20.97,16.34,13.64,10.65,7.71,5.80,4.39,3.52,2.59,2.48
2.64,3.13,3.75,5.52,7.36,10.09,13.31,15.99,19.15,22.28,24.51,25.47,28.45,29.21,29.37,29.93,28.93,28.39,27.32,26.67,25.47,23.76,21.62,18.59,16.46,13.69,10.68,8.25,6.17,4.22,3.13,2.80
2.64,2.86,3.64,5.20,7.58,9.79,12.17,14.58,16.90,19.00,21.53,24.65,26.67,27.32,28.39,29.93,30.93,31.32,29.21,27.56,23.83,21.53,18.35,15.21,13.64,11.79,8.60,6.47,4.71,3.52,2.86,2.64
2.80,2.41,2.93,4.06,5.58,9.49,12.93,15.52,19.15,20.97,26.73,32.04,38.23,31.09,28.39,25.94,24.94,27.41,27.32,24.89,21.36,19.31,17.69,15.77,15.99,16.35,10.09,8.03,4.87,3.52,2.95,2.72
2.48,2.77,3.40,4.71,6.92,9.20,11.41,14.11,16.34,19.00,23.02,25.47,26.67,28.27,28.39,27.93,27.93,27.41,31.09,28.45,26.29,24.51,19.00,18.59,14.58,12.55,8.31,6.47,4.55,3.28,2.86,2.48
2.56,2.95,3.17,4.39,5.80,7.42,11.41,14.11,18.03,20.97,24.51,27.11,31.12,32.03,30.35,29.93,26.94,27.41,28.27,27.56,24.65,22.28,20.31,17.46,15.52,12.55,9.49,6.69,4.87,3.40,2.59,2.24
2.24,2.50,3.75,5.69,7.81,10.38,12.17,15.05,18.03,20.97,22.28,23.83,24.00,24.50,25.45,25.94,26.94,29.37,29.21,27.56,27.93,23.76,23.59,20.84,17.40,12.55,9.20,6.25,4.55,3.52,2.50,2.32
2.48,2.86,3.52,4.87,6.47,7.71,11.41,13.64,17.46,20.31,22.28,25.47,29.34,32.98,34.26,33.92,30.93,29.37,28.27,26.67,24.65,21.53,18.35,16.34,13.64,11.03,8.90,6.47,4.55,3.28,3.04,2.48
2.64,2.68,3.75,5.04,7.58,8.90,11.79,12.70,15.77,20.31,22.28,25.47,26.67,28.27,29.37,32.92,31.92,32.30,30.15,25.78,23.83,23.02,19.66,16.90,14.11,11.03,8.60,6.69,5.04,3.52,2.59,2.24
2.80,2.86,3.52,4.71,6.02,8.31,11.03,13.64,16.34,19.00,23.02,25.47,30.23,32.03,31.32,31.92,29.93,30.35,29.21,26.67,23.00,20.79,18.35,15.77,14.11,12.17,9.20,6.92,5.20,3.75,2.77,2.40
2.40,2.68,3.28,4.55,6.47,8.60,11.41,13.64,16.90,19.66,23.76,27.11,28.45,30.15,30.35,30.93,30.93,30.35,28.27,25.78,23.83,21.53,19.66,17.46,14.58,11.79,9.20,6.92,5.04,3.75,2.77,2.40
2.56,2.95,3.64,4.87,6.47,8.90,11.03,14.11,16.90,19.00,21.53,23.83,26.67,28.27,29.37,27.93,27.93,28.39,27.32,25.78,25.47,21.53,19.66,16.90,15.05,12.55,10.09,7.58,5.20,3.87,2.86,2.56
2.64,2.68,3.40,4.55,6.47,8.60,11.79,14.58,16.90,19.66,22.28,25.47,28.45,29.21,28.39,28.93,26.94,28.39,28.27,26.67,25.47,20.79,19.66,17.46,16.46,13.69,10.38,7.36,5.04,3.87,2.86,2.72
2.40,2.68,3.87,5.36,7.36,10.38,13.69,16.46,19.15,20.97,21.53,23.83,24.89,24.50,25.45,24.94,24.94,27.41,27.32,26.67,28.75,25.25,23.59,20.84,18.34,13.69,10.68,7.14,4.71,3.40,2.50,2.24
2.64,3.04,3.75,5.20,6.69,8.90,11.03,13.64,16.34,19.00,21.53,23.83,25.78,27.32,29.37,29.93,28.93,28.39,29.21,26.67,26.29,23.02,20.31,17.46,15.05,12.55,9.20,7.36,4.87,3.52,2.68,2.40
2.64,3.04,3.87,5.69,7.36,10.09,12.55,15.52,18.03,20.97,23.76,25.47,26.67,29.21,29.37,28.93,28.93,27.41,27.32,24.00,21.36,19.31,17.69,15.21,13.64,11.41,9.20,7.36,5.52,4.10,3.22,2.80
2.80,3.13,3.75,4.71,7.14,8.90,11.41,14.11,16.34,18.35,21.53,24.65,28.45,28.27,27.41,29.93,30.93,30.35,30.15,27.56,25.47,23.76,20.31,17.46,15.05,12.17,9.49,6.69,4.55,3.52,2.59,2.24
2.24,2.59,3.52,4.87,6.69,9.49,12.17,15.05,16.90,19.66,22.28,24.65,25.78,26.38,27.41,28.93,28.93,29.37,28.27,27.56,26.29,23.02,19.66,17.46,15.05,12.17,9.20,6.92,5.20,3.64,2.68,2.24
2.72,2.95,3.87,5.20,6.92,8.90,11.41,14.58,16.90,19.66,22.28,23.83,26.67,29.21,31.32,31.92,32.92,32.30,30.15,28.45,25.47,23.02,20.31,16.90,13.64,11.03,8.60,6.47,4.71,3.52,2.68,2.40
1.60,1.79,2.23,3.09,4.46,5.93,7.60,9.41,11.83,13.76,15.59,18.07,19.56,21.67,22.51,23.94,23.94,24.47,23.55,21.34,19.72,17.82,15.73,13.52,11.76,9.51,7.71,5.80,4.39,3.17,2.41,2.08
2.56,2.86,3.75,5.04,6.92,9.20,11.79,14.11,16.90,20.31,23.02,25.47,27.56,29.21,30.35,30.93,30.93,30.35,28.27,26.67,24.65,22.28,19.66,16.90,14.11,11.41,8.90,6.69,4.87,3.52,2.68,2.32
2.64,2.77,3.64,4.87,6.69,9.20,11.79,14.58,16.90,19.66,20.79,23.00,25.78,28.27,31.32,34.92,34.92,34.26,32.03,28.45,25.47,22.28,19.66,16.90,14.11,11.41,8.60,6.47,4.55,3.17,2.41,2.08
2.16,2.41,3.40,5.04,7.14,9.79,12.55,15.52,17.46,20.31,22.28,24.65,26.67,29.21,30.35,30.93,30.93,30.35,28.27,26.67,24.65,22.28,20.97,18.59,15.99,12.93,10.09,7.36,5.20,3.52,2.68,2.32
2.24,2.68,3.75,5.69,8.25,11.57,14.07,15.99,18.03,19.66,23.02,24.65,26.67,29.21,30.35,29.93,28.93,27.41,26.38,25.78,26.29,26.73,25.56,22.53,17.40,12.93,9.49,6.69,4.87,3.52,2.77,2.40
2.56,2.77,3.28,4.55,6.25,8.31,11.41,14.11,16.34,19.00,20.79,22.18,24.89,28.27,31.32,35.92,36.91,35.24,30.15,27.56,23.83,20.79,18.35,15.77,13.17,11.03,8.01,6.02,4.22,2.93,2.24,2.00
2.16,2.68,3.87,5.85,8.03,10.68,12.93,15.05,16.90,18.35,20.79,23.00,25.78,29.21,30.35,31.92,30.93,30.35,28.27,26.67,24.65,23.02,20.97,19.15,16.46,13.69,10.09,7.36,5.04,3.40,2.50,2.16
2.56,2.86,3.75,5.04,6.92,9.20,11.41,14.11,16.90,19.66,22.28,24.65,26.67,28.27,29.37,29.93,29.93,29.37,28.27,26.67,24.65,22.28,19.66,16.90,14.11,11.41,8.90,6.69,4.87,3.40,2.68,2.40
2.16,2.50,3.40,4.87,7.14,9.49,12.17,14.58,17.46,20.97,23.02,27.11,29.34,31.09,31.32,30.93,29.93,28.39,27.32,26.67,24.65,23.02,20.31,18.03,14.58,12.17,9.49,7.14,5.20,3.87,2.86,2.56
2.56,2.86,3.64,4.87,6.47,8.01,10.65,13.17,16.90,21.62,25.99,29.58,32.01,32.03,32.30,31.92,31.92,31.32,30.15,26.67,24.65,20.79,17.04,14.65,12.23,9.89,7.42,5.80,4.55,3.40,2.77,2.80
2.00,2.24,2.93,4.06,6.02,8.60,11.79,16.93,21.97,25.56,28.96,28.75,28.45,28.27,30.35,30.93,29.93,31.32,28.27,27.56,23.83,20.79,19.00,16.90,15.99,13.69,11.57,8.70,5.69,3.87,2.86,2.48
3.12,3.67,4.34,5.69,7.14,8.90,11.41,14.11,16.90,19.66,22.28,23.83,24.00,25.44,24.47,25.94,25.94,27.41,29.21,28.45,32.04,29.70,25.56,20.84,15.05,11.79,8.31,6.47,4.55,3.52,2.77,2.32
2.56,2.50,3.40,4.87,6.69,9.20,11.79,14.58,16.34,19.00,20.79,23.83,28.45,32.03,37.20,37.91,36.91,34.26,29.21,26.67,23.83,21.53,19.00,16.34,14.11,10.65,8.31,6.02,4.22,3.05,2.24,2.08
2.88,3.13,3.87,5.20,6.92,9.20,11.79,14.58,18.59,20.97,23.76,24.65,24.89,26.38,26.43,27.93,29.93,30.35,32.03,32.01,30.40,26.73,21.62,18.59,14.58,11.79,9.20,6.92,5.04,3.64,2.77,2.40
2.96,3.67,4.34,5.85,7.36,9.20,11.41,14.11,16.90,19.00,21.53,22.18,24.00,24.50,25.45,25.94,24.94,25.45,25.44,26.67,26.29,26.73,24.25,21.41,16.93,13.69,9.79,6.69,5.04,3.52,2.77,2.48
3.12,3.04,3.99,4.87,6.69,8.90,11.41,15.05,17.46,20.97,22.28,23.83,26.67,28.27,32.30,34.92,36.91,38.18,34.86,31.12,26.29,23.02,19.66,16.90,14.11,11.03,8.90,6.25,4.39,3.17,2.32,2.08
2.08,2.32,3.17,4.71,6.92,10.09,13.31,17.40,20.28,21.62,23.76,23.83,26.67,27.32,30.35,31.92,31.92,32.30,28.27,26.67,23.83,21.53,20.31,18.03,16.46,13.69,10.68,7.81,5.20,3.64,2.68,2.40
2.56,2.77,3.64,5.04,6.69,8.60,11.41,14.58,17.46,20.97,23.76,24.65,27.56,29.21,31.32,30.93,31.92,32.30,29.21,29.34,26.29,23.02,19.66,16.34,13.64,10.65,8.60,6.69,5.04,3.75,2.86,2.56
2.56,2.95,3.75,5.20,6.69,8.90,11.79,14.58,16.90,19.66,22.28,25.47,26.67,28.27,28.39,29.93,29.93,29.37,27.32,25.78,24.65,23.02,19.66,16.34,13.64,11.03,8.31,6.47,4.71,3.52,2.68,2.48

文件要求编码格式为utf-8,否则后续过程可能会报错。

注意,这些csv都要放在同一个文件夹下面,同时所有数据总共最好不要超过230条,否则很有可能内存不够(如果你用arduino nano ble 33等mbed板子另议)。

声音训练

训练这里使用sklearn库,同时使用 eloquentarduino 大佬开发的micromlgen库转换为c语言。代码如下


#Arduino做声音分类 by eloquentarduino 部分注代码由小草修改
from sklearn.ensemble import RandomForestClassifier
from micromlgen import port
import numpy as np
from glob import glob
from os.path import basename

# put your samples in the dataset folder
# one class per file
# one feature vector per line, in CSV format
def load_features(folder):
    dataset = None
    classmap = {}
    for class_idx, filename in enumerate(glob('%s/*.csv' % folder)):
        class_name = basename(filename)[:-4]
        classmap[class_idx] = class_name
        samples = np.loadtxt(filename, dtype=float, delimiter=',')
        labels = np.ones((len(samples), 1)) * class_idx
        samples = np.hstack((samples, labels))
        dataset = samples if dataset is None else np.vstack((dataset, samples))

    return dataset, classmap
features, classmap = load_features('new-data-2/')
X, y = features[:, :-1], features[:, -1]
classifier = RandomForestClassifier(n_estimators=30, max_depth=10).fit(X, y)
c_code = port(classifier, classmap=classmap)
print(c_code)

请注意修改存放csv的文件夹的位置。运行完程序后,将代码复制并保存到model.h文件中。

同时修改代码,将第二行的

#include <cstdarg>

修改为

#include <stdarg.h>

将代码里的所有float改为double。

检测

接下来就可以进行检测了,代码如下:

//Arduino做声音分类 by eloquentarduino 部分注释及代码由小草修改
#include <arduinoFFT.h> //傅里叶变换头文件,需要先在IDE库管理器中安装

#include "model.h"  //以数据训练出来的模型头文件,未生成模型数据前注释掉

#define MIC A0  //麦克风接到模拟口0
#define NUM_SAMPLES 32    //因傅里叶变换的所限,采样数必须是2的倍数
#define SAMPLING_FREQUENCY 1024 //采样频率
#define INTERVAL 5       //间隙 
#define SOUND_THRESHOLD 15 //声音阈值,采集到的声音大小减去背景噪音大小超过这个值才记录,根据mic的灵敏度设定

unsigned int samplingPeriod;    //采样时间
unsigned long microSeconds;   //微秒

int32_t backgroundSound;      //背景声
double features[NUM_SAMPLES]; //特征向量大小,就是每次声音采样多少个值
arduinoFFT fft;   //创建一个快速傅里叶变换实例

String Q;

Eloquent::ML::Port::RandomForest classifier;  //创建一个分类器实例(类定义在“model.h”文件中)。训练后才需要用,获取数据时注释掉

void setup() {    //硬件参数设定
    Serial.begin(115200);
    pinMode(MIC, INPUT);
    Q = "d";

    samplingPeriod = round(100000*(1.0/SAMPLING_FREQUENCY));   // 1000000/1024,采样时间约1秒 
    calibrate();      //校正背景噪音

}

void loop() {
    if (!soundDetected()) {
        delay(10);
        return;
    }
    
    captureWord();
   
    Q = classifier.predictLabel(features);
    Serial.println(Q);
    
    //printFeatures();    //打印声音特征向量,采集数据时去掉注释

// uncomment when doing classification
    //Serial.print("Detecting :");
    //Serial.println(Q);
    //sdelay(200);

}

/**

    Get analog readings 读取mic的声音值,原来范围0-1023不适合用作快速傅里叶变换(FFT),于是减512
    @return
    */
int16_t readMic() {   
    return analogRead(MIC);
    return (analogRead(MIC) - 512) >> 2;
}

/**

    Get "ambient" volume 循环200次获取背景噪音均值
    */
void calibrate() {
    for (int i = 0; i < 200; i++)
        backgroundSound += readMic();

    backgroundSound /= 200;

    Serial.print("Threshold set at ");
    Serial.println(backgroundSound);
}

bool soundDetected() {    //判断是否有在说话,若Mic检测到的声音减去底噪后大于设定阈值,则说明有人说话
    return abs(readMic() - backgroundSound) >= SOUND_THRESHOLD;
}

void captureWord() {    //采集字词语音,每个词的特征采集次数取决于设定的变量NUM_SAMPLES
    for (uint16_t i = 0; i < NUM_SAMPLES; i++) {
        microSeconds = micros();
        features[i] = readMic();

        while(micros() < (microSeconds + samplingPeriod));
    }

    fft.Windowing(features, NUM_SAMPLES, FFT_WIN_TYP_HAMMING, FFT_FORWARD);   //采集到的声音信息进行FFT特征提取

}

void printFeatures() {      //打印声音采样特征到串口,把这些特征值保存为CSV文件,一种声音一个文件
    const uint16_t numFeatures = sizeof(features) / sizeof(double);

    for (int i = 0; i < numFeatures; i++) {
        Serial.print(features[i]);
        Serial.print(i == numFeatures - 1 ? '\n' : ',');
    }

}

效果演示

https://www.youtube.com/embed/aqXfYHW3t_E

注:两个视频是一样的,上传到不同地方方便观看。

贡献

感谢原作者答复我们的issue,给予我们帮助,以及感谢我的好友pigener陪我一起研究。

加入QQ群1014345230一起划水吧
转载请注明来源及链接
如需商业用途请联系作者

评论

  1. Windows Chrome 94.0.4606.81
    2年前
    2021-10-31 19:19:29
    1. 这个都是你写的吗,我感觉不像是
    2. 为什么不用效率更高的TensorFlow呢?
    3. 为什么不用余弦判断呢?
    • 博主
      AHdark
      Windows Edge 95.0.1020.40
      2年前
      2021-11-02 22:35:13

      不是我写的,你仔细看看文章。
      如果我没有记错,arduino uno的资源运行不了TensorFlow,TensorFlow lite都不行

    • 芋头焜
      AHdark
      Windows Edge 97.0.1072.62
      2年前
      2022-1-18 16:58:56
      1. 代码是一个意大利歪果仁写的,我们只调试了错误和修改了Arduino的控制部分
      2. TF模型在Arduino上部署不了,这里是用机器学习中的随机森林算法直接对声音频谱特征(FFT后)进行分类学习
      3. MFCC等预处理也需要一定内存,很可能也是不够的,并且我们也不会实现。不过相信应用后会对声音的识别率有不小的提升。详细可参考这里:https://www.jianshu.com/p/a588f7b0d281
      4. 安静环境下对某些声音辨识度比较好的动物,比如豹,要区分它和其他动物,还是不难的。本程序经过测试,是有效的。
      5. 程序原作者后来还提供了一种单分类SVM算法,应该能更好的识别出要检测的那种声音。文章如下:https://eloquentarduino.github.io/2020/05/anomaly-detection-on-your-arduino-microcontroller-via-one-class-svm/

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇