本文最后更新于 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' : ',');
}
}
效果演示
注:两个视频是一样的,上传到不同地方方便观看。
贡献
感谢原作者答复我们的issue,给予我们帮助,以及感谢我的好友pigener陪我一起研究。
不是我写的,你仔细看看文章。
如果我没有记错,arduino uno的资源运行不了TensorFlow,TensorFlow lite都不行