openSMILE安装、批量提取特征与生成文件的处理
下载安装openSMILE
更新:以前的opensmile没有提供Windows64位的版本,现在都有啦!
https://github.com/audeering/opensmile/releases/tag/v3.0.0
点击上述链接,找到下图,选择对应的文件下载。
下载之后解压即可,一般都没啥问题。
如果在这个过程中遇到什么问题,可以在底下评论或者私信我,我会尽快回复!
提取过程
在这里先介绍下opensmile自带的配置文件:
emobase2010.conf 情感特征:1582维特征向量
emobase_live4_batch_single.conf 现场情感识别:988维特征向量
IS09_emotion.conf 情感挑战:384维特征向量
emo_large.conf :大集合6552维向量
IS12_speaker_trait.conf 数字兼容特性
liveProsodyAcf.conf 语音韵律特征的音调和响度
(不同版本的opensmile特征数量稍微有些不同)
所以只需要根据自身的需求,更换下面命令中的conf文件名即可,注意音频文件必须是无损的wav格式。
SMILExtract -C config/IS09_emotion.conf -I wav_samples/opensmile.wav -O speech01.energy.csv
那在正式提取特征之前,我们还需要将我们需要提取的音频切割成多个短音频(如果后续有特征融合的需求的话),短音频的时长具体多少可根据自身需求进行更改,我这里是切割成了多个100ms(0.1s)的短音频。(很多情况下是按完整句子来切割的!)
具体代码如下:
import os
import wave
from pydub import AudioSegment
import contextlib
def get_wav_time(wav_path):
'''
获取音频文件时长
:param wav_path: 音频路径
:return: 音频时长 (单位秒)
'''
with contextlib.closing(wave.open(wav_path, 'r')) as f:
frames = f.getnframes()
rate = f.getframerate()
duration = frames / float(rate)
return duration
def get_ms_part_wav(main_wav_path, start_time, end_time, part_wav_path):
'''
音频切片,获取部分音频 单位是毫秒级别
:param main_wav_path: 原音频文件路径
:param start_time: 截取的开始时间
:param end_time: 截取的结束时间
:param part_wav_path: 截取后的音频路径
:return:
'''
start_time = int(start_time)
end_time = int(end_time)
sound = AudioSegment.from_mp3(main_wav_path)
word = sound[start_time:end_time]
word.export(part_wav_path, format="wav")
if __name__ == '__main__':
path = r'E:/123/' # 原音频目录
path_segment = r'E:/234/' # 切割后的音频目录
print('开始切割音频!')
time_segment = 100 # 切割后短音频的时长
for root, dir, files in os.walk(path):
for i in range(len(files)):
audio = root + files[i]
time_all = int(get_wav_time(audio) * 1000) # 转换成毫秒
start_time = 0 # 从第0ms开始切割
index = 1 # 切割后的序号名,从序号1开始命令
while start_time <= time_all - time_segment:
# print(str(i)+ ': ' + str(index))
end_time = start_time + time_segment
aduio_segment = path_segment + files[i][:-4] + '_' + str(index) + '.wav'
get_ms_part_wav(audio, start_time, end_time, aduio_segment)
start_time += time_segment
index += 1
# 接下来这两行是为了将最终能够不足time_segment时长的音频剪下来
aduio_segment = path_segment + files[i][:-4] + '_' + str(index) + '.wav'
get_ms_part_wav(audio, start_time, time_all, aduio_segment)
print('音频切割完成!')
注释是不是超级详细哈哈!
切割完音频之后,接下来就是对切割好的多个短音频进行处理了。
试想一下,如果一个一个进行提取,如果原音频是时长30s,那么切割后的音频就有300个了,更何况我们往往需要处理大量得到音频。
所以这个时候就需要我们进行批处理啦!(其实也就是用了一下os这个大家都很熟悉的模块而已哈哈)
话不多说,上代码:
"""
这个代码文件要与SMILExtract文件在同一目录下。
然后conf路径、生成特征文件的路径,都要改成你自己对应的路径。
"""
import os
path = './audio27_segment/' # 待处理的音频路径
for root,dir,files in os.walk(path):
for i in files:
os.system('SMILExtract -C config/IS09_emotion.conf -I ' + 'audio27_segment/' + i + ' -O ' + 'audio27_segment_fea/' + i[:-4] + '.csv')
生成文件的处理
当执行完以上操作之后,你也就基本完成了你的工作。
剩下最后一步,也就是将你真正需要用到的音频特征从csv文件中拿出来。
先介绍下这个生成的csv文件,这里以配置文件IS09_emotion.conf为例。
生成的csv文件中,第4~387行为特征名称,第392行一共386个元素,第一个元素为‘unknow’;最后一个元素为?;中间384个元素对应上面384个特征。
那如何将我们需要的这384个特征提取出来呢。
(PS:以下文档是针对多个长音频切割后的所有短音频进行的处理)
代码如下:
import os
import re
frome natsort import natsorted
# 先对文本进行操作
path2 = r'E:/audio27_segment_fea/' # 待处理的短音频的路径
arr = [[] for i in range(45)] # 45你可以随便改,只要大于你原长音频的数量就可以了!
index_num2 = []
for root, dir, files in os.walk(path2):
num = len(files)
files = natsorted(files)
for i in range(len(files)):
with open(root + files[i], 'r') as f:
content = f.readlines()
fea = content[-1]
fea1 = re.findall(r'-?\d+\.?\d*e?[-+]?\d+', fea)
fea1 = list(map(float, fea1))
index = int(re.findall(r'^(.*?)_', files[i])[0])
if index not in index_num2:
index_num2.append(index)
arr[index].append(fea1)
f_A1 = []
for i in arr:
if i != []:
f_A1.append(i)
# 除去有问题的音频特征(特征数为0)(一般都是原本长音频截取的最后一个短音频)
for index1, value1 in enumerate(f_A1):
for index2, value2 in enumerate(value1):
if len(value2) != 384:
print('holly shit!')
print(index1,end=': ')
print(index2,end=' ')
print(len(value2))
value1.pop(index2)
break
# 这里的f_A1 就是我们要的啦
这里给的代码很详细哈哈。
注:如果对上述代码或其他部分有问题的,可以评论或私信告诉我,我会尽快回复!
最后,点下赞不过分吧(qqnl)
更多推荐
所有评论(0)