语音识别中强制对齐_【涨姿势】口语评分——英语学习中的机器学习算法

人工智能81

芥末堆注:本篇是#

中国有数以亿计的英语学习者,移动互联网已经成为这个产业新的爆发点。口语学习app为学习者提供了一个更加轻松环境和低成本的投入。一方面鼓励用户"大声说出来",一方面为他们提供有效的评分反馈,指出发音中的具体错误,帮助他们进行有针对性的训练。

有道口语大师就是这样一款产品。这个号称最有趣的英语学习APP ,由曾出品过有道词典、有道翻译官的团队倾力打造。上线一个多月,便吸引了超过100万的用户。除了进阶式口语训练体系,游戏化设计萌宠元素受到好评之外,产品如何实现用机器学习的方法来进行口语自动评分,也是用户很关心的问题。

下面有道口语大师技术团队将对口语评分原理进行简单的介绍,以解大家困惑。

评价标准是什么?

所谓口语评分,具体来说就是给定某个句子,让用户进行发音,然后按照一定的标准进行评分。通常来说有两大类评分方法:第一,和某个特定的发音进行比较,和给定发音越相近得分越高;第二,用普适的标准来评价用户发音,即只要用户读的是正确的、地道的,就可以得到高分。我们认为第二种方法是更为准确合理,因为同样的一句话不可能只有单一的正确的读法,而给定的"标准"发音更无法保证是最标准的。发音存在夸张或连读/省略,这就使基于相似度的评分,在很多场景下都存在偏差。所以我们的介绍会围绕第二种评分方法展开,解释其中运用的技术。

从音标到单词

图1 有道口语大师跟读题示例

目前比较流行的口语学习类软件,都会给用户提供单词级别的评分反馈,但事实上,口语评分的内部实现是在比单词更小的单位——音标上进行的。我们在前面提到过,口语评分是将用户的发音和普适的标准比较来进行评价,这个"普适"的标准,是通过对成千上万的标准发音数据进行训练得到的,而音标就是我们训练和比较的单元。为什么选择音标而不是单词呢?首先,对于任何机器学习的算法来说,有足够多的训练样本都是至关重要的;其次,英语中有数十万计的单词,如果选择单词作为评分的单元,我们就需要对每个单词都收集到足够多的样本,这是非常困难的。而音标就不同了,标准的英语国际音标只有48个符号,因而我们只要对每个音标符号收集数据,就可以进行模型的训练了。

强制对齐

接下来的问题就变成了:我们要如何将一个完整的句子划分成音标级别的数据呢?这里我们通常使用的是强制对齐的技术。强制对齐(Forced Alignment),是指给定音频和文本,确定每个单词(音素)的起止位置的过程。如下图所示:我们给定一段波形,并给定该音频对应的文本She had a dark suit in greasy washwater all year. 通过强制对齐,能够得到每个音素(即我们通常所说的音标,使用的符号和标准国际音标略有差别)在原音频中所处的位置。

图2 强制对齐(Forced Alignment)

音频强制对齐的实现中最常用的方法是Viterbi解码,这是一个动态规划的算法。简单来说就是我们将音频切分成一个个长度很短的帧(我们称之为一个采样),帧的长度通常取到5~10ms之间,因为我们认为在这样短的时间内音频的各种特征基本不会发生改变。我们对一个音频的每个采样进行特征抽取,再和标准音标的特征进行相似度计算,用bi(Ot)来表示第t个采样和第i个音标模型的相似度。我们用δt(i)代表在采样t的时刻当前音频到达音标i的最大概率δt(i),则我们可以利用公式,由第t个采样推算出第t+1个时刻的结果δt+1(i)。解码过程中,t从0开始不断递增,直到音频结束,最终得到各个音标i对应的δN(i)。

强制对齐是语音识别的一种特殊的、简化了的情况,由于它的简单性,强制对齐通常具有较高的准确率(音素级别准确率可达90%,单词级别可达95%以上)。使用强制对齐,我们就可以对我们收集到的标准发音的数据进行处理:根据音频和它对应的文本进行强制对齐,得到每个音标对应的片段;对各个音标收集到的样本抽取特征并进行训练。通过对大量数据进行强制对齐,我们对每个音标得到一个模型,该模型将用于后续的打分流程。

语音识别

有了音标的模型,打分的过程就不难想到了。我们将用户的发音也切分成一个一个的音标,再将这每个片段分别和对应的音标模型进行比较,如果该片段表现的特征和我们在标准发音数据上训练得到的特征很相像,那么用户的发音就是地道的、准确的;反之,用户就很可能读错了这个音标。我们将一个单词的各个音标的得分综合起来得到一个单词的得分,再将各个单词的得分总和起来,就得到了整个句子的得分。同时我们通过各个音标的得分,也可以很容易地知道用户的哪些单词可能读错了,进一步将这些信息反馈给用户(如图1所示)。

强制对齐可以达到很高的准确率,但这必须要满足一个前提:我们给定的文本和音频必须是匹配的。具体来说,如果一个用户把I am a student读成了I was a student,我们在处理was所对应的音频片段时,会错误地将它和am对应的音标模型进行比对,那么很可能造成后续的a和student也无法对齐到正确的位置,从而影响打分的准确性。为了避免这样的情况,通常我们在进行强制对齐之前,还会增加一个语音识别的步骤,即先判断用户真正读的句子是什么,再用该结果去进行强制对齐。对上面的例子而言,我们用was对应的音标模型去和was的音频片段进行对比,那么后面的两个单词还是可以得到正确的切分结果。同时我们根据语音识别的结果,又可以发现部分用户读错的单词数据(am->was)并反馈给用户。

1、本文是

芥末堆网原创文章,转载可点击

芥末堆内容合作 了解详情,未经授权拒绝一切形式转载,违者必究;

2、芥末堆不接受通过公关费、车马费等任何形式发布失实文章,只呈现有价值的内容给读者;

3、如果你也从事教育,并希望被芥末堆报道,请您

填写信息告诉我们。

来源: 芥末堆

推广:

芥末堆商务合作:010-5726 9867

Original: https://blog.csdn.net/weixin_36335279/article/details/112927001
Author: 靖然是你
Title: 语音识别中强制对齐_【涨姿势】口语评分——英语学习中的机器学习算法



相关阅读1

Title: tensorflow基于cnn的实战mnist手写识别(浅层网络搭建)

手写数字识别mnist这个实例相当于c中的helloworld,对于刚入门cnn的同学来说可以借鉴一下,本人也是刚入门的小白,不对之处欢迎大家指正。

关于mnist数据集这里不多做介绍了,大家自己百度吧~~

使用tensorflow框架,导入相关包

import os  # 执行文件与文件夹
import numpy as np  # 导入numpy,同时给numpy一个别名np
import tensorflow as tf  # 导入tensorflow,同时给其一个别名tf
from tqdm import trange  # 进度条模块
from tensorflow.core.framework import summary_pb2  # 结果提取模块
from tensorflow.python.framework.graph_util import convert_variables_to_constants  # 将模型参数保存进graph

GPU使用设置

tf.logging.set_verbosity(tf.logging.ERROR)  # 让tensorflow记录错误信息
gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction=0.3)  # 指定每个GPU进程中使用显存的上限

下载mnist数据,打印训练集与数据集个数

这一步需要下载mnist数据集到本地文件夹mnist_data目录下,下载需要等待一段时间;或者自己去官网下载。

tutorials文件夹如果需要下载的同学自行百度下,不难的~~

关于one-hot编码,简单理解就是属于该类置1,不属于置0.

例如10分类中:

1,[0,1,0,0,0,0,0,0,0,0]

9,[0,0,0,0,0,0,0,0,0,1]

from tensorflow.examples.tutorials.mnist import input_data  # 导入数据
mnist = input_data.read_data_sets("MNIST_data", one_hot=True)  # 输入数据,one-hot编码
print(mnist.train.num_examples, mnist.test.num_examples)  # 打印训练集与测试集个数

输出:

Extracting MNIST_data\train-images-idx3-ubyte.gz
Extracting MNIST_data\train-labels-idx1-ubyte.gz
Extracting MNIST_data\t10k-images-idx3-ubyte.gz
Extracting MNIST_data\t10k-labels-idx1-ubyte.gz
55000 10000

定义一个FLAGS类,记录训练参数;计算训练批次

class FLAGS:
    num_classes = 10  # 十分类
    batch_size = 10  # 单次训练数
    global_epoch = 30  # epoch数 更新权重
    model_dir = "best_model" #模型地址

n_batch = mnist.train.num_examples // FLAGS.batch_size  # 计算批次

声明张量 占位符操作

语法结构为:tf.placeholder( dtype, shape=None, name )
函数的作用:减少产生的op,进而减少graph的开销。
具体原理是:因为每一个tensor值在graph上都是一个op,当我们将train数据分成一个个minibatch然后传入网络进行训练时,每一个minibatch都将是一个op,这样的话,一副graph上的op未免太多,也会产生巨大的开销;于是就有了tf.placeholder,我们每次可以将一个minibatch传入到x = tf.placeholder(tf.float32,[None,32])上,下一次传入的x都替换掉上一次传入的x,这样就对于所有传入的minibatch x就只会产生一个op,不会产生其他多余的op,进而减少了graph的开销。op其实可以理解成为是一个x数据经过网络时长生的张量值。

inputs = tf.placeholder(tf.float32, [None, 784],name='inputs')  # tf.placeholder(dtype(参数类型), [None,784]的形状,其中784是单个扁平28乘28像素MNIST图像的维度,而None表示对应于批量大小的第一个维度可以是任何大小., name=None name是数据名称,可不写)
y_true = tf.placeholder(tf.float32, [None, 10], name='ground_truth')  # 标签
global_step=tf.get_variable('global_step'[],initializer=tf.constant_initializer(0),trainable=False)  # 常量初始化函数tf.constant_initializer
is_training = tf.placeholder(tf.bool, name="phase_train")  # 阶段训练数据

定义卷积操作(输入、卷积核个数、步长striders)

加入BN层(批归一化,百度(手动狗头)),激活函数选择ReLU

def conv2d(x, filters, kernel_size=3, strides=1, is_training=True):  # 定义卷积
    x = tf.layers.conv2d(inputs=x, filters=filters, kernel_size=kernel_size, strides=strides, padding='same')
    x = tf.layers.batch_normalization(inputs=x, training=is_training)  # BN层
    return tf.nn.relu(x)  # 激活函数为ReLU

定义最大池化(输入、步长striders)

def maxpool2d(x, strides=2):  # 池化
    return tf.layers.max_pooling2d(inputs=x, pool_size=2, strides=strides, padding='same')

cnn(卷积神经网络)

[-1,28,28,1] -1表示自动计算这一维的大小,2828是图像heightweight,1是通道数channels,由于mnist原图为黑白,所以为1,RGB彩色图片为3

网络结构为浅层网络:2层卷积、两层池化、两层全连接层

def conv_net(inputs, num_classes=10, is_training=True):  # cnn
    inputs = tf.reshape(inputs, shape=[-1, 28, 28, 1])  # 重塑输入图片
    conv1 = conv2d(inputs, 32, kernel_size=5, strides=1, is_training=is_training)  # 卷积1
    conv1 = maxpool2d(conv1, strides=2)  # 池化1

    conv2 = conv2d(conv1, 64, kernel_size=5, strides=1, is_training=is_training)  # 卷积2
    conv2 = maxpool2d(conv2, strides=2)  # 池化2

平坦化,变成[-1,7,7,64] (n,3136)

两层全连接(输入、神经元个数、激活函数),dropout是防止过拟合,过拟合是什么?自己百度~~简单来说就是防止模型过于拟合数据,泛化能力减弱。全连接最后一层神经元个数为10,(0-9十分类)。

fc1 = tf.reshape(conv2, [-1, 7 * 7 * 64])  # 重塑conv2
    fc1 = tf.layers.dense(fc1, 1024, activation=tf.nn.relu)  # 全连接层(输入数据,输出维度,激活函数)
    fc1 = tf.layers.dropout(fc1, rate=0.3, training=is_training)  # 防止过拟合(拿掉0.3的神经元)
 end_point = tf.layers.dense(fc1, num_classes)  # 全连接层(输入数据,输出维度=10)
    return end_point

调用网络结构进行训练

end_point = conv_net(inputs, num_classes=FLAGS.num_classes, is_training=is_training)  # 调用
result_cls = tf.argmax(end_point, axis=-1)  # 返回最大的那个数值所在的下标
result_cls = tf.identity(result_cls,name="result_cls") # 检查位置

计算accurary

accurary = tf.metrics.accuracy(labels=tf.argmax(y_true, axis=-1), predictions=result_cls)[1]

计算交叉熵损失

loss = tf.losses.softmax_cross_entropy(onehot_labels=y_true, logits=end_point)  # loss

通过loss计算误差,批归一化处理,并使用Adam优化

update_opts = tf.get_collection(tf.GraphKeys.UPDATE_OPS)  # 取出ops列表
with tf.control_dependencies([tf.group(*update_opts)]):  # 当括号里面的参数执行完毕再执行with里面的语句,一般都会与with共用
    var_list = tf.trainable_variables()  # 返回使用trainable=ture创建的所有变量
    g_list = tf.global_variables()  # 返回全局变量
    bn_moving_vars = [g for g in g_list if 'moving_mean' in g.name]  # 批归一化均值
    bn_moving_vars += [g for g in g_list if 'moving_variance' in g.name]  # 批归一化方差
    var_list += bn_moving_vars  # 左=左+右
    loss = loss  # 交叉熵
    train_op = tf.train.AdamOptimizer(learning_rate=0.001).minimize(loss, var_list=var_list,
                                                                    global_step=global_step)  # Adam优化算法:一个寻找全局最优点的优化算法,引入了二次方梯度校正。
    pass

创建会话(session),初始化变量,数据输出以显示整个训练的过程

init = tf.group(tf.global_variables_initializer(), tf.local_variables_initializer())  # 组合操作初始化

# with tf.Session() as sess:
with tf.Session(
        config=tf.ConfigProto(gpu_options=gpu_options)) as sess:  # tf.ConfigProto用在创建session的时候,用来对session进行参数配置
    sess.run(init)
    bast_score = 0.995
    for epoch in range(FLAGS.global_epoch):
        for batch in trange(n_batch):
            batch_xs, batch_ys = mnist.train.next_batch(FLAGS.batch_size)
            [__train_op, __total_loss, __accurary, __global_step] = sess.run([train_op, loss, accurary, global_step],
                                                                             feed_dict={inputs: batch_xs,
                                                                                        y_true: batch_ys,
                                                                                        is_training: True})
            pass
        acc_train = sess.run(accurary,
                             feed_dict={inputs: mnist.train.images, y_true: mnist.train.labels, is_training: False})
        acc_test = sess.run(accurary,
                            feed_dict={inputs: mnist.test.images, y_true: mnist.test.labels, is_training: False})
        print("Iter:{:3d}, loss: {}, TrainAcc: {}, TestAcc: {}".format(epoch, '%.4f' % __total_loss, '%.4f' % acc_train,
                                                                       '%.4f' % acc_test))

输出如下:

100%|&#x2588;&#x2588;&#x2588;&#x2588;&#x2588;&#x2588;&#x2588;&#x2588;&#x2588;&#x2588;| 5500/5500 [01:52<00:00, 0 5500 48.85it s] 0%| | [00:00<?, ?it s]iter: 0, loss: 0.0610, trainacc: 0.9682, testacc: 0.9695 100%|██████████| [01:51<00:00, 49.32it 2022-04-24 09:25:45.217825: w tensorflow core framework allocator.cc:107] allocation of 5519360000 exceeds 10% system memory. 1, 0.0121, 0.9778, 0.9783 [01:53<00:00, 48.46it 2, 0.0564, 0.9820, 0.9823 [01:52<00:00, 48.94it 3, 0.0001, 0.9847, 0.9848 49.36it 4, 0.0008, 0.9862, 0.9862 49.30it iter: 5, 0.0000, 0.9875, 0.9876 48.97it 6, 0.0002, 0.9887, 0.9887 [01:54<00:00, 48.07it 7, 0.9896, 0.9897 [02:01<00:00, 45.44it 8, 0.8875, 0.9902, 0.9902 [01:57<00:00, 46.70it 9, 0.9909, 0.9909 46.75it 10, 0.9915, 0.9915 11, 0.9920, 0.9920 46.65it 12, 0.9924, 0.9924 46.87it 13, 0.9928, 0.9927 [01:58<00:00, 46.40it 14, 0.9931, 0.9931 46.69it 15, 0.9934, 0.9934 [01:56<00:00, 47.10it 16, 0.9937, 0.9937 48.45it 17, 0.9939, 0.9939 48.29it 18, 0.9941, 0.9941 48.22it 19, 0.9943, 0.9943 47.09it 20, 0.9945, 0.9945 [01:55<00:00, 47.52it 21, 0.9947, 0.9947 47.80it 22, 0.9948, 0.9948 46.95it 23, 0.9950, 0.9950 24, 0.9951, 0.9951 47.31it 25, 0.9952, 0.9952 46.85it 26, 0.9953, 0.9953 46.71it 27, 0.9954, 0.9954 28, 0.9955, 0.9955 47.12it 29, 0.9956, 0.9956 process finished with exit code <></00:00,>

转载请联系作者

Original: https://blog.csdn.net/panghuzhenbang/article/details/124375710
Author: 胖虎记录学习
Title: tensorflow基于cnn的实战mnist手写识别(浅层网络搭建)

相关阅读2

Title: 利用anaconda创建tensorflow环境并在jupyter和pycharm中使用

利用anaconda创建tensorflow环境并在jupyter和pycharm中使用

Anaconda官网下载即可

https://www.anaconda.com/products/individual

清华镜像网站下载更快https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/
安装完成后 conda --version 查看安装版本
语音识别中强制对齐_【涨姿势】口语评分——英语学习中的机器学习算法
注意:装anaconda,就不需要单独装python了。

anaconda 是一个python的发行版,包括了python和很多常见的软件库, 和一个包管理器conda
百度搜索任意安装教程即可,例: https://zhuanlan.zhihu.com/p/75717350
TensorFlow for Windows只支持Python3.5和Python 3.6,所以尽量下载高版本Anaconda

; cudnn和cuda下载安装(GPU版本的Tensorflow需要此步骤)

tensorflow-gpu和cudnn、cuda对应关系:
https://tensorflow.google.cn/install/source_windows

安装教程: https://blog.csdn.net/sinat_23619409/article/details/84202651

tensorflow环境创建

  1. 采用命令行的方法 ,管理员身份运行Anaconda Prompt(Anaconda3)
    语音识别中强制对齐_【涨姿势】口语评分——英语学习中的机器学习算法
  2. 添加清华镜像的方法
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/
conda config --set show_channel_urls yes
  1. 新建Tensorflow环境
conda create -n tensorflow python=3.6.2

查看python版本 python --version
检测目前安装了哪些环境变量: conda info --envs
语音识别中强制对齐_【涨姿势】口语评分——英语学习中的机器学习算法
4. 启动tensorflow环境

activate tensorflow

正式安装tensorflow

1.进入tensorflow环境,输入命令: pip install tensorflow_gpu==2.6.0
2.测试tensorflow是否安装成功:
输入命令: python

>>>import tendorflow as tf
>>>from tensorflow.python.client import device_lib
>>>print(device_lib.list_local_devices())
>>>tf.config.list_physical_devices('GPU')

在tensorflow环境中安装jupyter

  1. 进入tensorflow环境
    conda install ipython
    conda install jupyter
    conda install -n tensorflow ipykernel
    最后将此kernel链接到jupyter notebook中 python -m ipykernel install --user --name tensorflow --display-name "Python (tensorflow)" 此时发现多了一个jupyter notebook(tensorflow)

语音识别中强制对齐_【涨姿势】口语评分——英语学习中的机器学习算法

  1. 在jupyter中使用tensorflow
    语音识别中强制对齐_【涨姿势】口语评分——英语学习中的机器学习算法将kernel改为刚建立的tensorflow环境

; 在pycharm中使用tensorflow环境

在新建的项目中,点击file->settings...->Python Interpreter.

将这里的路径改为tensorflow环境下的python路径

语音识别中强制对齐_【涨姿势】口语评分——英语学习中的机器学习算法
语音识别中强制对齐_【涨姿势】口语评分——英语学习中的机器学习算法

参考

https://zhuanlan.zhihu.com/p/75717350
https://blog.csdn.net/sinat_23619409/article/details/84202651

Original: https://blog.csdn.net/weixin_44457451/article/details/122859084
Author: xianhjj
Title: 利用anaconda创建tensorflow环境并在jupyter和pycharm中使用

相关阅读3

Title: Realsense-D455的IMU在ubuntu18.04使用

一。配置realsense-ros:

已经新建了ROS工作空间,可以直接在工作空间的src目录下克隆相关功能包,然后进行编译,具体命令参考下方:

1、已建好工作空间Realsense_D435i:

cd Realsense_D435i/src
git clone -b 2.2.11 https://github.com/IntelRealSense/realsense-ros.git
git clone https://github.com/pal-robotics/ddynamic_reconfigure.git

原文链接:https://blog.csdn.net/hltt3838/article/details/120691764
2.完成上述步骤后,使用以下命令进行测试:

cd Realsense_D435i
catkin_make
source devel/setup.bash
roslaunch realsense2_camera rs_camera.launch
3.打开新的终端查看节点:
rostopic list语音识别中强制对齐_【涨姿势】口语评分——英语学习中的机器学习算法

可以看到,只有图片信息的话题,!!!!!!!!!!!!!!!!没有IMU信息的话题,因为这是原launch文件中默认的!!!!!!,想要打开IMU 信息话题,需要在相应的launch文件作修改,因此不建议使用一键安装realsense-ros方法

https://blog.csdn.net/weixin_50508111/article/details/121087220

二。打开IMU话题

  1. 针对相机的各种配置参数,通过 /realsense-ros/realsense2_camera/launch/rs_camera.launch 文件传给ROS系统。
    将rs_camera.launch 复制了一份命令成lee_test.launch,在其中更改打开IMU话题的相关命令。
    设备默认打开深度图,深度自信度,RGB图像,关闭IMU数据,
    语音识别中强制对齐_【涨姿势】口语评分——英语学习中的机器学习算法
    在这里将最后两个标识符设置为true,即可打开陀螺仪和加速计的数据流。
  2. 删除build和devel文件重新catkin_make编译一下,使用命令: roslaunch realsense2_camera lee_test.launch打开,报错语音识别中强制对齐_【涨姿势】口语评分——英语学习中的机器学习算法
    原因是没有添加环境变量,有俩个方法
    (1.)添加:
echo "source ~/Realsense_D435i/devel/setup.bash" >> ~/.bashrc
source ~/.bashrc

(2.)终端输入: cd Realsense_D435i
source devel/setup.bash
成功打开语音识别中强制对齐_【涨姿势】口语评分——英语学习中的机器学习算法
realsense d455在ROS中发布的IMU数据分红了两个:

"/camera/gyro/sample" 发布角速度
"/camera/accel/sample" 发布线加速度app

同时这两个的时间戳也不太同样,在launch文件中的频率也不同:

<arg name="gyro_fps" default="400"/>
  <arg name="accel_fps" default="250"/>

设置同步选项,以下部分参考自https://blog.csdn.net/weixin_46363611/article/details/114643088
IMU数据是不同步的,即accel和gyro互相独立。

可修改的配置介绍:https://github.com/IntelRealSense/realsense-ros#launch-parameters

其中影响IMU数据同步的为:语音识别中强制对齐_【涨姿势】口语评分——英语学习中的机器学习算法
r其中realsense2_camera\srcbase_realsense_node.cpp就是写了如何发布全部topic,代码很长,一开始绕了很多弯路。
其中void BaseRealSenseNode::setupStreams():

if (gyro_profile != _enabled_profiles.end() &&
            accel_profile != _enabled_profiles.end())
        {
            ROS_INFO("starting imu...");
            std::vector<rs2::stream_profile> profiles;
            profiles.insert(profiles.begin(), gyro_profile->second.begin(), gyro_profile->second.end());
            profiles.insert(profiles.begin(), accel_profile->second.begin(), accel_profile->second.end());
            auto& sens = _sensors[GYRO];
            sens.open(profiles);
            auto imu_callback_inner = [this](rs2::frame frame){
                imu_callback(frame);
            };
            auto imu_callback_sync_inner = [this](rs2::frame frame){
                imu_callback_sync(frame, _imu_sync_method);
            };
            if (_imu_sync_method > imu_sync_method::NONE)
            {
                std::string unite_method_str;
                int expected_fps(_fps[GYRO] + _fps[ACCEL]);
                unite_method_str = "COPY";
                if (_imu_sync_method == imu_sync_method::LINEAR_INTERPOLATION)
                {
                    unite_method_str = "LINEAR_INTERPOLATION";
                    expected_fps = 2 * std::min(_fps[GYRO], _fps[ACCEL]);
                }
                ROS_INFO_STREAM("Gyro and accelometer are enabled and combined to IMU message at "
                                 << expected_fps << " fps by method:" << unite_method_str);
                sens.start(imu_callback_sync_inner);
            }
            else
            {
                sens.start(imu_callback_inner);
                if (_enable[GYRO])
                {
                    ROS_INFO_STREAM(_stream_name[GYRO] << " stream is enabled - " << "fps: " << _fps[GYRO]);
                    auto gyroInfo = getImuInfo(GYRO);
                    _info_publisher[GYRO].publish(gyroInfo);
                }
                if (_enable[ACCEL])
                {
                    ROS_INFO_STREAM(_stream_name[ACCEL] << " stream is enabled - " << "fps: " << _fps[ACCEL]);
                    auto accelInfo = getImuInfo(ACCEL);
                    _info_publisher[ACCEL].publish(accelInfo);
                }
            }
        }

能够看到这里的条件判断:
if (_imu_sync_method > imu_sync_method::NONE)&#xFF0C;&#x6700;&#x540E;&#x8BB2;&#x6267;&#x884C;&#x56DE;&#x8C03;&#x51FD;&#x6570;sens.start(imu_callback_sync_inner)&#xFF1B;
否则就执行
_info_publisher[GYRO].publish(gyroInfo)&#x548C;_info_publisher[ACCEL].publish(accelInfo)

而咱们一开始的launch文件就是采用了后面一种,最后直接发布了GYRO和ACCEL。
unite_imu_method_str 是 "copy"或者"linear_interpolation"就好了!
而这又是读取了launch文件中的unite_imu_method,因此在rs_camera.launch中直接修改:
若使用linear_interpolation选项,可以将加速计的数据以插值的方式对齐到陀螺仪数据时间轴上;

若使用copy选项,则是在每一个陀螺仪数据上,附加上时间最近邻的加速计数据。

默认选项为:None。语音识别中强制对齐_【涨姿势】口语评分——英语学习中的机器学习算法
在.launch文件中,将unite_imu_method对应设置为"linear_interpolation",两路数据即可以同步为同一个topic: /camera/imu:语音识别中强制对齐_【涨姿势】口语评分——英语学习中的机器学习算法
测试一下语音识别中强制对齐_【涨姿势】口语评分——英语学习中的机器学习算法
测试成功!
使用命令行
rostopic echo /camera/imu
查看IMU数据,同一个数据中同时包含两个传感器数据:语音识别中强制对齐_【涨姿势】口语评分——英语学习中的机器学习算法

IMU与图像的同步

修改了enable_sync参数,是对相机和IMU进行同步的。

<arg name="enable_sync" default="true"/>

三。IMU数据集录制

数据记录与播放
说明:运行上面的 roslaunch realsense2_camera demo_pointcloud.launch 指令时,便可以进行下面bag的录制

rosbag record -a
   #录制所有topic到bag文件,注意-终端的地址就是bag包存放的地址,
bag的名字是时间;

比如记录IMU的数据bag
rosbag record /camera/accel/imu_info -O imu.bag

 变成了 rosbag record /camera/imu -O imu.bag

rosbag record /camera/imu /camera/color/image_raw -o Cam-imu.bag

  • rosbag play xxx.bag #播放bag文件
  • rosbag info xxx.bag #查看bag文件
  • 注意:rosbag play bag 的同时,也可以提取bag包发布的特定topic,保存成txt或者csv文件,如下所示:
    rostopic echo /camera/imu > imu.txt
  • rostopic hz /camera/color/image_raw
    用来查看话题的发布频率

原文链接:https://blog.csdn.net/hltt3838/article/details/120691764

Original: https://blog.csdn.net/weixin_50508111/article/details/123915215
Author: 王不偏
Title: Realsense-D455的IMU在ubuntu18.04使用