深度学习系列74:语音中的mel谱

news2024/11/28 2:47:19

1 mel谱介绍

一个人说一句话,其 waveform 可以很不一样,但是 spectrogram 基本上会相似,甚至有人可以通过 spectrogram 来判断说话的内容。语谱图的横坐标是时间,纵坐标是频率,坐标点值为语音数据能量。由于是采用二维平面表达三维信息,所以能量值的大小是通过颜色来表示的,颜色深,表示该点的语音能量越强。
DFT(Discrete Fourier Transform)是将连续音频信号转换为离散频域表示的一项重要操作。DFT是一种数学变换,用于将时域信号(如音频波形)转换为频域表示。它是连续傅立叶变换(Continuous Fourier Transform,CFT)的离散版本,适用于离散时间序列。
FFT(快速傅立叶变换)是一种算法,旨在更快、更高效地计算序列的离散傅立叶变换 (DFT),从而降低计算的复杂性并缩短处理时间。

mel谱是一种常用的声音的特征向量计算方法,主要步骤为:

  1. 预处理:对声音采样图做一个预加重处理,即数值 = 当前点-前一点,可以让频谱比较均衡

  2. 分帧:通常取20-40ms称为一帧,太长会使时间上的分辨率(time resolution)较小,太小会加重运算成本,在此之上加窗做FFT,然后拼接起来称为功率谱(spectrogram)。
    在这里插入图片描述

  3. 计算功率谱spectrogram:选择1024点FFT(FFT点数比原信号点数少会降低频率分辨率frequency resolution,但这里相差很小,所以可以忽略)。将得到的FFT变换取其magnitude,并进行平方再除以对应的FFT点数,即可得到功率谱。声谱图的横轴表示时间,纵轴表示频率,而颜色或亮度则表示在特定时间和频率上的信号强度或能量。

  4. 通过 filter bank(滤波器组)变为特征向量:滤波器组(filter bank)是由一组滤波器所组成的系统,用于对输入信号进行频率分析。在声学特征提取中,常用的滤波器组是梅尔滤波器组(Mel filter bank)。梅尔滤波器组是一种非线性的滤波器组,它的设计基于梅尔刻度(Mel scale),该刻度是一种根据人耳感知频率的特性而设计的心理声学刻度,可以提升低频区间的分辨率。

  5. 有时会再做一点处理,得到MFCC:spectrogram filter bank output取log,再进行DCT,最后生成MFCC(Mel Frequency Cepstral Coefficients)。在这里插入图片描述
    下图是大家使用的特征比例,用filter bank output和MFCC的比较多
    在这里插入图片描述

2 参考代码

2.1 使用librosa

首先是使用librosa获取声音波形,然后严格按照时间间隔进行重采样:

import librosa
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import rcParams
import matplotlib.ticker as ticker
y,sr = librosa.load('test.m4a',sr=None)
#这里只获取0-20秒的部分,这里也可以在上一步的load函数中令duration=20来实现
tmax,tmin = 20,0
t = np.linspace(tmin,tmax,(tmax-tmin)*sr)
plt.plot(t,y[tmin*sr:tmax*sr])

在这里插入图片描述

import librosa.display
mel_spect = librosa.feature.melspectrogram(y=y, sr=sr)
mel_spect = librosa.power_to_db(mel_spect, ref=np.max)
librosa.display.specshow(mel_spect, y_axis='mel', fmax=sr/2, x_axis='time')
plt.colorbar(format='%+2.0f dB')
plt.show()

在这里插入图片描述

函数说明如下:
spectrogram=librosa.feature.melspectrogram(y,sr,
S=None,n_fft=2048,
hop_length=512,win_length=2048,
window=“hann”,center=True,
pad_mode=“constant”,power=2,
n_mels=40,fmin=0,fmax=sr/2,
htk=0,norm=None
)
y:音频时间序列,numpy数组。支持多通道
sr :采样率,默认22050
S :语频谱,默认None
n_fft :FFT窗口的长度,默认2048
hop_length :帧移,默认512,n_fft/4
win_length :窗口的长度为win_length,默认win_length = n_fft
window :窗函数,默认hann
center:bool
如果为True,则填充信号y,以使帧 t以y [t * hop_length]为中心。
如果为False,则帧t从y [t * hop_length]开始

    pad_mode:补零模式,默认constant
    power:幅度谱的指数。例如1代表能量,2代表功率,等等
    n_mels:滤波器组的个数 ,默认40

    f_min(float) :音频的最小频率,默认为0.0(可以设为20,为了滤去噪声,在频域中表为左下角为一条线)
    f_max(float) :音频的最大频率,默认为sr/2

    norm(str):默认为None,{None、slaney或number}[标量],如果是“slaney”,则将三角形的mel权重除以的宽度,mel波段(区域归一化)。如果是数字,请使用“librosa.util.normalize”对每个筛选器进行标准化,按单位lp范数。请参阅“librosa.util.normalize”以获取完整的支持的范数值的描述(包括“+-np.inf”)。

    mel_scale(str) :采用的mel尺度: htk 或者 slaney,默认 htk

2.2 使用torchaudio

也可以用torchaudio进行加载:

import torchaudio
waveform,sr = torchaudio.load('test.wav')
y=waveform.t().numpy().reshape(waveform.shape)[0]
plt.plot(t,y[tmin*sr:tmax*sr])

torchaudio可以直接输出mel谱:

#梅尔谱
specgram = torchaudio.transforms.MelSpectrogram()(waveform)
print("梅尔谱大小:{}".format(specgram.shape))
plt.figure()
p = plt.imshow(specgram.log2()[0,:,:].detach().numpy(),cmap='gray')
plt.show()                             

在这里插入图片描述
1表示单通道;128表示梅尔滤波器的个数;1103表示时间(也就是帧数)

函数说明如下:
torchaudio.transforms.MelSpectrogram(sample_rate: int = 16000, n_fft: int = 400,
win_length[int]:None, hop_length[int] = None,
f_min: float = 0.0, f_max[float] = None,
pad: int = 0, n_mels: int = 128,
window_fn:(…) -> Tensor=torch.hann_window ,
power: float = 2, normalized: bool = False,
wkwargs[dict] = None, center: bool = True,
pad_mode: str = ‘reflect’, onesided: bool = None,
norm[str] = None, mel_scale: str = ‘htk’)

sample_rate(int) :输入波形的采样率
n_fft(int) :为FFT的长度,默认为400,会生成 n_fft /2 + 1 个 bins
win_length :窗口的长度,默认为 n_fft
hop_length :相邻两个滑动窗口帧之间的距离,即帧移,默认为 win_length / 2
f_min(float) :音频的最小频率,默认为0.0(可以设为20,为了滤去噪声,在频域中表为左下角为一条线)
f_max(float) :音频的最大频率,默认为None
pad :对输入信号两边的补零长度,默认为 0
n_mels(int) :mel滤波器的个数,默认为128
window_fn :窗函数,默认为 torch.hann_window
power(float) :语谱图的幂指数,值必须大于 0,默认为 2.0(代表功率),取 1( 代表能量)
normalized(bool) :对stft的输出进行归一化,默认为 False
wkwargs :窗函数的参数,默认为 None(附加参数,为字典类型,暂时不用。如果需要传参数,就要调用这个参数)
center(bool) :是否对输入tensor在两端进行padding,默认为 True
pad_mode(str) :补零方式,默认为 reflect
onesided(bool) :是否只计算一侧的谱图,默认为 True,即返回单侧的语谱图,如果为 False,则返回全部的谱图。
norm(str):默认为None, 为“slaney”时,则将三角形mel权重除以mel bin的宽度(即进行面积归一化),
mel_scale(str) :采用的mel尺度: htk 或者 slaney,默认 htk

3. 步骤详解

3.1 预加重(类似差分)

通常来讲语音或音频信号的高频分量强度较小,低频分量强度较大,信号预加重就是让信号通过一个高通滤波器,让信号的高低频分量的强度不至于相差太多。
在时域中,对信号x[n]作如下操作:
在这里插入图片描述
α通常取一个很接近1的值,为0.97或0.95.
下面对比一下预加重前后的频谱分布图

alpha = 0.97#预加重的系数
tmin=0
tmax=5
emphasized_y = np.append(waveform[tmin*sr],
                         waveform[tmin*sr+1:tmax*sr]-alpha*waveform[tmin*sr:tmax*sr-1])
n = int((tmax-tmin)*sr) #信号一共的sample数量
 
#未经过预加重的信号频谱(图5)
plt.figure()
freq = sr/n*np.linspace(0,n/2,int(n/2)+1)
plt.plot(freq,np.absolute(np.fft.rfft(waveform[tmin*sr:tmax*sr],n)**2)/n)
plt.xlim(0,5000)
plt.xlabel('Frequency/Hz',fontsize=14)
plt.show()
 
#预加重之后的信号频谱(图6)
plt.figure()
plt.plot(freq,np.absolute(np.fft.rfft(emphasized_y,n)**2)/n)
plt.xlim(0,5000)
plt.xlabel('Frequency/Hz',fontsize=14)
plt.show()

在这里插入图片描述
这两段代码里用了函数librosa.fft.rfft(y,n),rfft表示经过fft变换之后只取其中一半(因为另一半对应负频率,没有用处), y对应信号,n对应要做多少点的FFT。我们这里的信号有44.1k5=220500 个点,所以对应的FFT 也做220500点的FFT,每一个点所对应的实际频率是该点的索引值fs/n。

3.2 分帧

预处理完信号之后,要把原信号按时间分成若干个小块,一块就叫一帧(frame)。
为啥要做这一步?因为原信号覆盖的时间太长,用它整个来做FFT,我们只能得到信号频率和强度的关系,而失去了时间信息。因此我们对每一帧作FFT(又称为短时FFT,因为我们只取了一小段时间),然后对每一帧频谱进行映射。最后将得到的结果按照时间顺序拼接起来。

#分帧
alpha = 0.97#预加重的系数
tmin=0
tmax=5
emphasized_y = np.append(waveform[tmin*sr],
                         waveform[tmin*sr+1:tmax*sr]-alpha*waveform[tmin*sr:tmax*sr-1])
 
frame_size, frame_stride = 0.025,0.01#frame_size:每一帧的长度。frame_stride:相邻两帧的间隔
frame_length, frame_step = int(round(sr*frame_size)),int(round(sr*frame_stride))
signal_length = (tmax-tmin)*sr
frame_num = int(np.ceil((signal_length-frame_length)/frame_step))+1 #向上舍入
pad_frame = (frame_num-1)*frame_step+frame_length-signal_length #不足的部分补零
pad_y = np.append(emphasized_y,np.zeros(pad_frame))
signal_len = signal_length+pad_frame
 
print("frame_length:",frame_length)# 每一帧对应的sample数量
print("frame_step:",frame_step)#相邻两帧的sample数量
print("signal_length:",signal_length)#音频的总sample数量
print("frame_num:",frame_num)#整个信号所需要的帧数
print("pad_frame:",pad_frame)#需要补零的sample数量
print("pad_y:",pad_y)#预加重、补零之后的音频列表
print("signal_len:",signal_len)#预加重、分帧之后的音频总sample数量

3.3 加窗

分帧完毕之后,对每一帧加一个窗函数,以获得较好的旁瓣下降幅度。通常使用hamming window。原始的矩形窗的频谱有很大的旁瓣,时域中将窗函数和原函数相乘,相当于频域的卷积,矩形窗函数和原函数卷积之后,由于旁瓣很大,会造成原信号和加窗之后的对应部分的频谱相差很大,这就是频谱泄露 。hamming window有较小的旁瓣,造成的spectral leakage也就较小。

#加窗
indices = np.tile(np.arange(0, frame_length), (frame_num, 1)) + np.tile(
    np.arange(0, frame_num * frame_step, frame_step), (frame_length, 1)).T
frames = pad_y[indices] #frame的每一行代表每一帧的sample值
frames *= np.hamming(frame_length) #加hamming window 注意这里不是矩阵乘法
print(frames)#加窗完之后的数据

分帧的下标indices如下:
在这里插入图片描述
对每一行做FFT。由于每一行是551个点的信号,所以可以选择512点FFT(FFT点数比原信号点数少会降低频率分辨率frequency resolution,但这里相差很小,所以可以忽略)。

3.4 计算功率谱->语谱图->mel谱

在实际使用中, 根据需求不同, 频谱图有三种类型:线性振幅谱;对数振幅谱 (对数振幅谱中各谱线的振幅都作了对数计算,所以其纵坐标的单位是dB分贝));功率谱。而这里要介绍Mel_ spectrogram 语谱图, 其中的频谱类型使用的便是功率谱。

将上一步得到的FFT变换取其magnitude,并进行平方再除以对应的FFT点数,即可得到功率谱(power spectrum )。
将每一帧信号的功率谱做成一个合集(每一帧信号都有一个功率谱)。将多个帧的功率谱,翻转之后,按照时间顺序拼接,就构成信号的语谱图(spectrogram)。

#FFT--->功率谱(使用dB单位)-->语谱图(此处等价为功率谱)
NFFT = 512 #frame_length=551
mag_frames = np.absolute(np.fft.rfft(frames,NFFT))#由于rfft之后,返回的是复数,故要对其取进行模操作
pow_frames = mag_frames**2/NFFT#Pow_frames就是功率谱矩阵的变量名.
plt.figure()
plt.imshow(20*np.log10(pow_frames[40:].T),cmap=plt.cm.jet,aspect='auto')
plt.yticks([0,128,256],np.array([0,128,256])*sr/NFFT)
plt.show()

mel-spectrogram就是将梅尔滤波器组应用到语谱图中。此时,语谱图的纵坐标从Hz 刻度便转换成Mel刻度;Mel尺度和普通频率之间使用如下转换公式:
M e l ( f ) = 2595 ∗ l o g 10 ( 1 + f / 700 ) Mel(f) = 2595 * log10(1 + f/700) Mel(f)=2595log10(1+f/700),称为MFCC。

所谓梅尔滤波器组是一个等高的三角滤波器组,每个滤波器的起始点在上一个滤波器的中点处。其对应的频率在梅尔尺度上是线性的,因此称之为梅尔滤波器组。
在这里插入图片描述

#语谱图(spectrogram)-->梅尔谱(mel-spectrogram)
#下面定义mel filter
mel_N = 40 #滤波器数量,这个数字若要提高,则NFFT也要相应提高
mel_low, mel_high = 0, (2595*np.log10(1+(sr/2)/700))
mel_freq = np.linspace(mel_low,mel_high,mel_N+2)
hz_freq = (700 * (10**(mel_freq / 2595) - 1))
bins = np.floor((NFFT)*hz_freq/sr) #将频率转换成对应的sample位置
fbank = np.zeros((mel_N,int(NFFT/2+1))) #每一行储存一个梅尔滤波器的数据
for m in range(1, mel_N + 1):
    f_m_minus = int(bins[m - 1])   # left
    f_m = int(bins[m])             # center
    f_m_plus = int(bins[m + 1])    # right
 
    for k in range(f_m_minus, f_m):
        fbank[m - 1, k] = (k - bins[m - 1]) / (bins[m] - bins[m - 1])
    for k in range(f_m, f_m_plus):
        fbank[m - 1, k] = (bins[m + 1] - k) / (bins[m + 1] - bins[m])
filter_banks = np.matmul(pow_frames, fbank.T)#将梅尔滤波器作用到上一步得到的pow_frames上
filter_banks = np.where(filter_banks == 0, np.finfo(float).eps, filter_banks)  # np.finfo(float)是最小正值
filter_banks = 20 * np.log10(filter_banks)  # dB
plt.figure()
plt.imshow(filter_banks[40:].T, cmap=plt.cm.jet,aspect='auto')
plt.yticks([0,10,20,30,39],[0,1200,3800,9900,22000])
plt.show()

举个例子:
假如有10个Mel滤波器
(在实际应用中通常一组Mel滤波器组有26个滤波器。)

首先要选择一个最高频率和最低频率,通常最高频率为8000Hz,最低频率为300Hz。

使用从频率转换为Mel频率的公式将300Hz转换为401.25Mels,8000Hz转换为2834.99Mels,

由于有10个滤波器,每个滤波器针对两个频率的样点,样点之间会进行重叠处理,因此需要12个点,意味着需要在401.25和2834.99之间再线性间隔出10个附加点,如:

mel(i)=401.25,622.50,843.75,1065.00,1286.25,1507.50,1728.74,1949.99,2171.24,2392.49,2613.74,2834.99
现在使用从Mel频率转换为频率的公式将它们转换回赫兹:
h(i)=300,517.33,781.90,1103.97,1496.04,1973.32,2554.33,3261.62,4122.63,5170.76,6446.70,8000
将频率映射到最接近的DFT频率,此时得到的 f(i), 便是 Mel 滤波器组中 各个滤波器的中心频率。
在这里插入图片描述

4. 补充知识

4.1 短时FFT

短时FFT通过在信号上滑动这个窗口,我们可以逐渐查看整个信号,就像是通过一系列快照来观察它的变化。这个过程可以用一个日常的比喻来说明:想象你正在看一场烟花表演,你决定用相机拍摄整个表演。如果使用长时间曝光,你最终得到的照片将是所有烟花的叠加,这相当于传统的频谱分析;然而,如果你使用一连串短时间曝光的快照,每张照片将捕捉到表演的一个瞬间,这就类似于“加窗”的频谱分析。
参考这个图:https://pica.zhimg.com/50/v2-62e60fad089b4a82fc88f267cd1db0c3_720w.webp?source=1def8aca
STFT图就是频谱图在时间轴上的连续展开,这个图有三个轴:
时间轴:表示信号分析的持续时间。
频率轴:它表示了信号中存在的各种频率成分。
幅度轴:幅度轴垂直于时间-频率平面,通常通过颜色的深浅来表示。强度表示在特定时间和频率下信号的能量大小。
STFT图也有二维形式,这种形式中是使用颜色来代表幅度大小的,其生成过程如下:
https://pica.zhimg.com/50/v2-3aa719443f5982f4961068a822dde92d_720w.webp?source=1def8aca
对比第一个信号和第二个信的STFT图,可以看到在不同时间段内频率成分的变化。
在这里插入图片描述

4.2 小波变换

短时FFT的问题如下图:
在这里插入图片描述
大窗口提供较高的频率分辨率,您将能够看到信号中不同频率成分的细节,就像200Hz的频率可以被很好得识别出来。然而,时间分辨率较低,这意味着短暂事件的精确时间定位可能不太清晰,图中跳变的时间段都延展到0.4-0.6s了,而实际上它是0.5-0.6s。相反的,小窗口对分辨率辨别不是很清晰。

下面说一下卷积的重要特性:**频域相乘等于时域的卷积。**这个性质将频率分解转化为卷积计算。

频谱计算的一种理解视角——频谱可以被视为一系列不同频率的正弦波与原始信号进行卷积的结果:
https://picx.zhimg.com/50/v2-e7b9233f6b787f13a7b9b74b21a7d6ae_720w.webp?source=1def8aca

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
https://pic1.zhimg.com/50/v2-9b694c566d1bd5457c80cd195a0757b1_720w.webp?source=1def8aca
在这里插入图片描述

当频率较低时,小波的相对窗口会非常宽,而频率较高时窗口会越来越窄。CWT和人类的听觉系统非常一致:在低频处有更好的频率定位能力,在高频处有更好的时间定位能力。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2099838.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

计算机网络(一) —— 网络基础入门

目录 一,关于网络 二,协议 2.1 协议是什么,有什么用? 2.2 协议标准谁定的? 2.3 协议分层 2.4 OSI 七层模型 2.5 TCP/IP 四层模型 三,网络传输基本流程 3.1 局域网中两台主机通信* 3.2 报文的封装与…

智能化浪潮赋能工业制造与报废拆解,基于高精度YOLOv8全系列参数【n/s/m/l/x】模型开发构建工业生产场景下车辆不同部位智能化分割检测识别分系统

随着科技的飞速发展,数字化与智能化已成为推动社会进步的强大引擎。在工业生产制造与汽车报废处理这一传统领域中,这一变革尤为显著。曾经,流水线作业与人工拆解是这些行业的主要生产方式,它们不仅效率低下,且高度依赖…

如何从 AWS CodeCommit 迁移到极狐GitLab?

极狐GitLab 是 GitLab 在中国的发行版,可以私有化部署,对中文的支持非常友好,是专为中国程序员和企业推出的企业级一体化 DevOps 平台,一键就能安装成功。安装详情可以查看官网指南。 本文将分享如何从 AWS CodeCommit 服务无缝迁…

【无标题】XSS安全防护:responseBody (输入流可重复读) 配置

接上文:配置XSS过滤器 XXS 安全防护:拦截器+注解实现校验-CSDN博客XSS(跨站脚本)攻击是一种网络安全威胁,允许攻击者注入恶意脚本到看似安全的网站。当用户浏览这些被注入恶意代码的网页时,恶意脚本会在用户的浏览器环境中执行,这可能导致多种安全问题,如窃取敏感数据、…

链表算法题(上)

在之前单链表和双链表两个专题中我们学习了链表相关的概念和性质,同时了解了单链表和双链表各自的特征,那么接下来在本篇中我们就将使用这些链表的知识来解决链表相关的算法题,在本篇中这些算法题能强化我们的算法思想,会对我们之…

HTML5好看的花店商城源码2

文章目录 1.设计来源1.1 主界面1.2 界面效果11.3 界面效果21.4 界面效果31.5 界面效果41.6 界面效果51.7 界面效果61.8 界面效果71.9 界面效果8 2.效果和源码2.1 动态效果2.2 源代码 源码下载万套模板,程序开发,在线开发,在线沟通 作者&#…

postgresql数据库创建表分区和分区分区查询失效问题

postgresql数据库创建表分区和分区失效场景 一、前言二、分区表创建1、范围分区(Range Partitioning)2、列表分区(List Partitioning)3、hash分区(hash Partitioning) 三、表分区查询失效问题 一、前言 在…

AcWing算法基础课-785快速排序-Java题解

大家好,我是何未来,本篇文章给大家讲解《AcWing算法基础课》785 题——快速排序。这篇文章介绍了使用快速排序算法对整数数列进行排序的方法,包括选择基准元素、分区操作和递归排序子数组。通过详细的步骤和示例,解释了快速排序的…

Axure打造科技感数据可视化大屏原型

在数字化浪潮的推动下,数据已成为企业决策不可或缺的核心驱动力。面对海量且复杂的数据集,如何高效解读并转化为洞见,是企业面临的重大挑战。数据可视化,尤其是科技感十足的大屏展示,不仅为企业提供了直观的数据洞察&a…

9,sql 约束

创建表时添加非空约束 create table sys3(name int,age int not null) 建表后修改 alter table sys3 modify name int null 删除 创建表时添加默认值约束 关键字 default 默认值的意思 后面跟着默认的值create table sys_4(列名1 数据类型 default 默认值,列名2 数据类型 no…

网络安全售前入门09安全服务——安全加固服务

目录 1.服务概述 2.流程及工具 2.1服务流程 2.2服务工具 3.服务内容 ​​​​​​​4.服务方式 ​​​​​​​5.风险规避措施 ​​​​​​​6.服务输出 1.服务概述 安全加固服务是参照风险评估、等保测评、安全检查等工作的结果,基于科学的安全思维方式、长期的安全…

Apache CloudStack Official Document 翻译节选(十三)

快速部署一朵 Apache CloudStack 云 (二) 部署一朵pache CloudStack 云 安装Apache CloudStack的云内管理服务组件 本部分我们将安装Apache CloudStack的云内管理服务组件及周边工具。 关于数据库的安装与配置: 我们会安装和配置MySQL并配…

【机器学习入门】一文读懂非线性支持向量机SVM

前面已经分别介绍了基于硬间隔最大化的线性可分支持向量机、基于软间隔最大化的线性支持向量机,这次来总结下使用核函数来解决非线性可分问题的非线性支持向量机。 【机器学习入门】一文读懂线性可分支持向量机【机器学习入门】一文读懂线性支持向量机SVM 一 非线…

GCViT实战:使用GCViT实现图像分类任务(一)

摘要 GC ViT(全局上下文视觉转换器)是一种创新的深度学习架构,旨在提升计算机视觉任务中的参数和计算效率。它通过将全局上下文自注意力模块与标准的局部自注意力相结合,有效地建模长程和短程空间交互,同时避免了传统…

IJCAI-信也科技杯全球AI大赛-华东师范大学亚军队伍分享

作者:彭欣怡(找不到工作版) 华东师范大学; 马千里(搬砖版) 虾皮; 指导:闫怡搏(科研版) 华东师范大学 比赛链接:https://ai.ppdai.com/mirror/goToMirrorDetailSix?mirrorId34 前言 这是我们首次参加语音领域的比赛,最初只是抱着…

深度学习之 OpenCV 图像边缘检测算法解析及代码演示

引言 在计算机视觉领域,边缘检测是一种重要的图像预处理技术,用于识别图像中对象的边界。边缘检测有助于提取图像的关键特征,这对于后续的图像分析(如物体识别、运动检测等)至关重要。OpenCV 是一个强大的计算机视觉库…

Zabbix 企业级高级应用(Zabbix Enterprise Advanced Application)

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:Linux运维老纪的首页…

备忘录1【java环境变量手动更改】

B站视屏链接:https://www.bilibili.com/video/BV1cV8BeCESA?vd_source3e4562475feb55327a8adde111050d4e 1.电脑设置 2.系统-------系统信息 3.高级系统设置 4.环境变量 5.系统变量中,更改之前创建好的JAVA_HOME 版本可以将1.8改成本机安装的其他版本…

Java进阶13讲__第九讲

Stream流 1. 案例初体验 package cn.hdc.oop9.stream.using;import java.util.LinkedList; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream;public class t1 {public static void main(String[] args) {LinkedList<String&g…

认知杂谈30

今天分享 有人说的一段争议性的话 I I 《豁然开朗&#xff1a;男性成长的关键转折》 在男人的人生旅程当中啊&#xff0c;最金贵的可不是那些让人眼馋的钱财啥的&#xff0c;也不是啥惊天动地的事儿&#xff0c;更不是偶尔碰到的贵人帮忙。真正无价的宝贝呢&#xff0c;是在…