一篇文章入门梅尔频率倒谱系数

文章目录

  • 梅尔频率倒谱系数MFCC
    • 预处理
      • 预加重
      • 分帧
      • 加窗
    • FFT(Fourier-Transform)
    • 功率谱
    • 滤波器组
    • 梅尔频率倒谱系数(MFCC)
    • 均值归一化
    • 总结
  • 参考文献

梅尔频率倒谱系数MFCC

梅尔倒谱系数(Mel-scale FrequencyCepstral Coefficients,简称MFCC):依据人的听觉实验结果来分析语音的频谱
MFCC分析依据的听觉机理:

  1. 第一梅尔刻度(Mel scale):人耳感知的声音频率和声音的实际频率并不是线性的 ⇒ \Rightarrow 从频率转换为梅尔刻度的公式为: f m e l = 2595 ∗ log ⁡ 10 ( 1 + f 700 ) f_{mel}=2595*\log _{10}(1+\frac{f}{700}) fmel=2595log10(1+700f);从梅尔回到频率: f = 700 ( 1 0 f m e l / 2595 − 1 ) f = 700 (10^{f_{mel}/2595} - 1) f=700(10fmel/25951)
    f m e l f_{mel} fmel是以梅尔(Mel)为单位的感知频域(梅尔频域), f f f是以Hz为单位的实际语音频率
    在这里插入图片描述
  2. 第二临界带(Critical Band):把进入人耳的声音频率用临界带进行划分,将语音在频域上划分成一系列的频率群,组成了滤波器组,即Mel滤波器组

人耳对不同频率的声波有不同的听觉敏感度 ⇒ \Rightarrow 两个不同响度的声音作用于人耳时,响度较高的声音会影响到对响度较低的声音的感受
耳蜗的工作机制:耳蜗的基底膜对不同频率的声音振动有不同的响应

  • 低频(低音)声音在基底膜上的行波传递距离较长,能在基底膜较远端引发振动
  • 高频(高音)声音在基底膜上的传递距离较短,通常会在基底膜的靠近基部处引发振动

当低音和高音同时存在时,低频声波的传播会在更广泛的区域内产生振动,从而覆盖住高频部分,使得高频的声音被掩蔽 ⇒ \Rightarrow 低频声音(如低音)具有较强的掩蔽能力,能掩盖掉频率相近的其他声音
临界带宽是指人耳在某个频率范围内能够区分的最小频率差,超过这个带宽外的声音可以被人耳区分,但在带宽内的声音容易被掩蔽掉

预处理

预处理包括预加重、分帧、加窗函数

import numpy
import scipy.io.wavfile
from scipy.fftpack import dctsample_rate, signal = scipy.io.wavfile.read('OSR_us_000_0010_8k.wav') 
signal = signal[0:int(3.5 * sample_rate)]  # 我们只取前3.5s

在这里插入图片描述

时域中的语音信号

预加重

预加重处理其实是将语音信号通过一个高通滤波器: y ( t ) = x ( t ) − α x ( t − 1 ) y(t)=x(t)-\alpha x(t-1) y(t)=x(t)αx(t1),其中滤波器系数 α \alpha α通常取值在 0.9 到 1 之间

emphasized_signal = numpy.append(signal[0], signal[1:] - pre_emphasis * signal[:-1])

在这里插入图片描述

预加重的作用:

  1. 增强高频成分:语音信号的频谱特性通常是低频成分的能量较高,高频成分的能量较低。预加重通过增加高频成分的能量,使整个频谱更加平坦
  2. 提高信噪比:高频成分往往更容易受到噪声的影响。预加重增强了这些高频分量,从而相对提高了它们的信噪比
  3. 减少信号失真:低频成分可能会引起过度的信号能量集中,导致失真。预加重可以平衡频谱,减少这种失真

分帧

在大多数情况下,语音信号是非平稳的,对整个信号进行傅里叶变换是没有意义的
将信号帧化为20-40 ms帧,标准是25毫秒 frame_size = 0.025 \text{frame\_size}=0.025 frame_size=0.025,这意味着8kHz信号的帧长度为 0.025 ∗ 8000 = 200 0.025*8000=200 0.0258000=200个采样点。帧移通常为10毫秒 frame_stride = 0.01 \text{frame\_stride}=0.01 frame_stride=0.01(80个采样点)第一个语音帧从0开始,下一个语音帧从80开始,直到到达语音文件的末尾

  • 帧长(frame length):一帧的持续时间,如果帧长为 25 ms,采样率为 16,000 Hz,那么每一帧的采样点数为 400 个
  • 帧移(frame step):两帧之间的时间间隔,如果帧移为 10 ms,表示每一帧开始后过 10 ms 就会开始下一帧
  • 重叠部分:帧长 25 ms,帧移 10 ms,那么每两帧之间有 15 ms 的重叠部分
frame_length, frame_step = frame_size * sample_rate, frame_stride * sample_rate  # 从秒转换为采样点
signal_length = len(emphasized_signal)
frame_length = int(round(frame_length))
frame_step = int(round(frame_step))
# 确保至少有1帧
num_frames = int(numpy.ceil(float(numpy.abs(signal_length - frame_length)) / frame_step))  pad_signal_length = num_frames * frame_step + frame_length
z = numpy.zeros((pad_signal_length - signal_length))
# 填充信号,确保所有帧的采样数相等,而不从原始信号中截断任何采样
pad_signal = numpy.append(emphasized_signal, z) indices = numpy.tile(numpy.arange(0, frame_length), (num_frames, 1)) + numpy.tile(numpy.arange(0, num_frames * frame_step, frame_step), (frame_length, 1)).T
frames = pad_signal[indices.astype(numpy.int32, copy=False)]

加窗

在信号处理(尤其是音频处理)过程中,将信号分割成帧后,每帧的开头和结尾容易产生不连续性或边界效应,在频域中会产生不必要的伪影或噪声(称为“频谱泄漏”)
通过对每个帧乘以窗函数,尤其是渐变的窗函数,可以减少这种不连续性,保证帧的两端更“平滑”,从而减小频谱泄漏的影响
Hamming 窗口是常用的一种窗函数: w ( n ) = ( 1 − α ) − α ⋅ cos ⁡ ( 2 π n N − 1 ) w(n)=(1-\alpha)-\alpha\cdot\cos\left(\frac{2\pi n}{N-1}\right) w(n)=(1α)αcos(N12πn),其中 n n n是采样点的索引、 N N N是窗口/帧的长度、 α = 0.46 \alpha=0.46 α=0.46
Hamming 窗口的特点:它的两端值接近 0,中间值接近 1,因此乘以 Hamming 窗口会使帧的两端平滑下降,而中间部分的信号保留得较完整

  • 减小边界效应:将每一帧乘以 Hamming 窗口后,信号在帧的左右两端逐渐减小到接近 0,这使得每帧在拼接时不再产生突然的跳跃,信号的开头和结尾更加“平滑”,从而减少了不连续的边界问题 ⇒ \Rightarrow 将信号划分成多个帧时,每一帧都被认为是一个独立的信号片段。如果帧的开始和结束处信号值存在较大的突变,就会产生不连续性
  • 降低频谱泄漏:当对分帧后的信号进行傅里叶变换时,如果帧的边界不连续,会导致在频域中泄漏到不相关的频率分量。Hamming 窗口通过将帧的两端平滑过渡,减少了不连续性,进而降低了频谱泄漏的影响 ⇒ \Rightarrow 傅里叶变换假设信号是周期性的,因此它会自动认为每一帧的结束点与下一帧的起始点是连续的。如果实际情况中,帧的两端不连续,傅里叶变换会试图将这个突变表示为多种不同频率的叠加,从而在频域中引入了不相关的频率分量。这些不相关的频率分量扩散到整个频谱中,形成所谓的“频谱泄漏”

帧的拼接:将处理后的每帧按帧移的间隔进行逐一加和。因为相邻的帧之间有重叠部分,需要将这些重叠的部分叠加起来,而不是简单地直接连接

  • 第一帧 frame_1(400 点)直接放在结果信号的起始位置(即 0 到 399 采样点)
  • 第二帧 frame_2 从 160 采样点处开始,它的前 240 个点和 frame_1 的后 240 个点会发生重叠,因此它们重叠部分的值需要相加,而不是替换
  • 依次类推,直到所有帧都拼接完成
frames *= numpy.hamming(frame_length)
# frames *= 0.54 - 0.46 * numpy.cos((2 * numpy.pi * n) / (frame_length - 1))  # 内部实现

在这里插入图片描述

FFT(Fourier-Transform)

由于信号在时域上的变换通常很难看出信号的特性,通常对它做FFT变换转换为频域上的能量分布来观察,不同的能量分布,代表不同语音的特性
短时傅里叶变换(STFT):对每一帧信号执行一个长度为 N N N的傅里叶变换,最终得到一个包含 N N N个频率分量的频谱,其中 N N N通常为256或512: S i ( k ) = ∑ n = 1 N s i ( n ) e − j 2 π k n N , 1 ≤ k ≤ K S_i(k)=\sum_{n=1}^Ns_i(n)e^{-j\frac{2\pi kn}{N}},\quad1\leq k\leq K Si(k)=n=1Nsi(n)ejN2πkn,1kK

  • S i ( k ) S_i(k) Si(k):第 i i i帧第 k k k个频率分量
  • s i ( n ) s_i(n) si(n):第 i i i帧的第 n n n个时域采样点的信号值,表示原始信号在时域的值
  • N N N::表示经过傅里叶变换后的频率分量的个数
  • k k k:表示频率索引,取值范围为 1 ≤ k ≤ K 1\leq k\leq K 1kK,其中 K K K通常是 N / 2 N/2 N/2,因为傅里叶变换的结果通常是对称的,前 K K K项就包含所有独立的频率信息
  • e − j 2 π k n N e^{-j\frac{2\pi kn}{N}} ejN2πkn:傅里叶变换中的复数旋转因子
    n N \frac{n}{N} Nn表示信号在一个周期内的相位变化,当 n n n增加时,信号的相位也会变化,这种变化与频率 k k k相关

功率谱

功率谱:对语音信号中的频谱取模平方((取对数或者取平方)得到语音信号的谱线能量 P = ∣ F F T ( x i ) ∣ 2 N P=\frac{|FFT(x_i)|^2}N P=NFFT(xi)2,其中 x i x_i xi是信号 X X X的第 i i i
在信号处理中,噪声往往集中在特定的频率范围内。通过查看信号的功率谱,可以识别出噪声频率并设计合适的滤波器去除这些噪声
信号在某一频率上的功率反映了该频率的强弱

滤波器组

计算Mel滤波器组:将功率谱通过一组Mel刻度(通常取40个滤波器, n f i l t = 40 nfilt=40 nfilt=40)的三角滤波器来提取频带(frequency bands)

  • Mel刻度:人类对频率感知的非线性刻度 ⇒ \Rightarrow 将实际的频率值转换为与人耳感知一致的数值,使得低频段的变化在Mel刻度上比高频段的变化更敏感 ⇒ \Rightarrow 人耳对低频更敏感,能更好地区分相邻的频率,而对高频的分辨能力较差 ⇒ \Rightarrow Mel ⁡ ( f ) = 2595 log ⁡ 10 ( 1 + f 700 ) \operatorname{Mel}(f)=2595\log_{10}\left(1+\frac{f}{700}\right) Mel(f)=2595log10(1+700f),其中 f f f是频率,转换后的Mel值反映了人耳对不同频率的感知
  • 临界带宽:在听觉系统中,能够分辨出的最小频率差 ⇒ \Rightarrow 如果两个声音的频率差小于这个带宽,人耳就难以区分它们,它们会被感知为同一个声音
    依赖频率:临界带宽的大小与频率相关。在低频段,临界带宽较小,人耳可以分辨出较小的频率差异;而在高频段,临界带宽较大,意味着人耳难以分辨高频信号中的细微差异
    掩蔽效应:当低频声音和高频声音同时出现时,低频声音会“占据”较小的频率带宽,而高频声音的临界带宽较大,更容易被低频声音覆盖或掩蔽 ⇒ \Rightarrow 在耳蜗中,低频声音的行波传播距离比高频声音更长,能够覆盖更广的区域,这意味着低频声音能更有效地激活耳蜗中较大的一部分,干扰甚至覆盖高频声音的感知;在声音的频谱中,低频声音的能量往往更大,且由于临界带宽较小,低频声音的能量集中,这种强度较高的低频声音更容易掩蔽掉能量相对较弱、临界带宽较大的高频声音 ⇔ \Leftrightarrow 当低频和高频声音同时出现时,低频声音的强度和较小的临界带宽使得它更容易“占据”听觉频率空间,而高频声音由于较大的临界带宽和相对较弱的能量分布,更容易受到低频声音的干扰或掩蔽
  • Mel滤波器组:就像人类的听觉感知系统(耳朵),人耳只关注某些特定的频率分量(人的听觉对频率是有选择性的)。它对不同频率信号的灵敏度是不同的,换言之,它只让某些频率的信号通过,而压根就直接无视它不想感知的某些频率信号。但是这些滤波器在频率坐标轴上却不是统一分布的,在低频区域有很多的滤波器,他们分布比较密集,但在高频区域,滤波器的数目就变得比较少,分布很稀疏。因此Mel刻度的目的是模拟人耳对声音的非线性感知,在较低的频率具有更强的辨别力
    滤波器:用于分离或增强某些频率的声音信号,常见的滤波器包括低通滤波器(只允许低频通过)、高通滤波器(只允许高频通过)以及带通滤波器(只允许一定范围的频率通过)
    Mel刻度:Mel刻度是基于人耳对频率感知的非线性频率刻度。它对低频敏感度更高,高频则较不敏感 ⇒ \Rightarrow Mel滤波器组(通常是三角滤波器)用于分割信号的频谱,每个滤波器的中心频率依据Mel刻度分布,低频滤波器更密集,高频滤波器较稀疏
    临界带宽:在滤波器设计中,临界带宽用来确定每个滤波器的带宽

语音频率和Mel频率之间转换:

  • 从频率转换为梅尔刻度的公式为: Mel ⁡ ( f ) = 2595 log ⁡ 10 ( 1 + f 700 ) \operatorname{Mel}(f)=2595\log_{10}\left(1+\frac{f}{700}\right) Mel(f)=2595log10(1+700f)
  • 从梅尔回到频率: f = 700 ( 1 0 f m e l / 2595 − 1 ) f = 700 (10^{f_{mel}/2595} - 1) f=700(10fmel/25951)

定义一个有M个三角滤波器的滤波器组(滤波器的个数和临界带的个数相近), M M M通常取22-40,26是标准。滤波器组中的每个滤波器都是三角形的,中心频率为 f ( m ) f(m) f(m),中心频率处的响应为1,并向0线性减小,直到达到两个相邻滤波器的中心频率,其中响应为0,各 f ( m ) f(m) f(m)之间的间隔随着m值的增大而增宽 ⇒ \Rightarrow 每个滤波器的响应形状是三角形,这意味着在中心频率 f ( m ) f(m) f(m)处,滤波器的响应最强(即响应值为1),而随着频率远离中心,滤波器的响应会线性下降,直到在相邻滤波器的中心频率处降为0。这样的设计使得相邻滤波器在频谱上有所重叠,确保信号中的频率信息平滑过渡,不会突然丢失

  • 中心频率 f ( m ) f(m) f(m):每个滤波器都有一个中心频率,它是该滤波器对输入信号最敏感的频率
  • 线性减小:滤波器对中心频率的两侧频率的响应逐渐减弱。这种线性下降的设计让每个滤波器只对特定的频率区间有效
  • 三角滤波器的频率响应定义为: H m ( k ) = { 0 k < f ( m − 1 ) k − f ( m − 1 ) f ( m ) − f ( m − 1 ) f ( m − 1 ) ≤ k < f ( m ) 1 k = f ( m ) f ( m + 1 ) − k f ( m + 1 ) − f ( m ) f ( m ) < k ≤ f ( m + 1 ) 0 k > f ( m + 1 ) \left.H_m(k)=\left\{\begin{array}{cc}0&k<f(m-1)\\\\\frac{k-f(m-1)}{f(m)-f(m-1)}&f(m-1)\leq k<f(m)\\\\1&k=f(m)\\\\\frac{f(m+1)-k}{f(m+1)-f(m)}&f(m)<k\leq f(m+1)\\\\0&k>f(m+1)\end{array}\right.\right. Hm(k)= 0f(m)f(m1)kf(m1)1f(m+1)f(m)f(m+1)k0k<f(m1)f(m1)k<f(m)k=f(m)f(m)<kf(m+1)k>f(m+1)

在这里插入图片描述
奈奎斯特频率是离散信号系统采样频率的一半

# --*-- coding:utf-8 --*--
# @Author : 一只楚楚猫
# @File : 01滤波器组.py
# @Software : PyCharmimport numpy as np# 示例参数
sample_rate = 16000  # 采样率 16kHz
NFFT = 512  # FFT点数
nfilt = 40  # 滤波器组的滤波器数量
low_freq_mel = 0  # 最低的Mel频率
high_freq_mel = (2595 * np.log10(1 + (sample_rate / 2) / 700))  # 最高Mel频率,对应Nyquist频率# 1. 生成Mel刻度上的点
mel_points = np.linspace(low_freq_mel, high_freq_mel, nfilt + 2)  # 在Mel刻度上均匀生成42个点
# hz_points = [[   0.           44.37407701   91.56109503  141.73937073  195.09852453,  251.84019719  312.17881177  376.34238398  444.57338374  517.12965156,  594.28537283  676.33211398  763.57992429  856.35850754  955.01846792, 1059.93263499 1171.49747253 1290.13457677]
# hz_points.shape: (nfilt + 2, )
hz_points = 700 * (10 ** (mel_points / 2595) - 1)  # 将Mel刻度转换回Hz刻度# 2. 计算每个频率点在FFT频率bin中的索引
# bins = [  0   1   2   4   6   8  10  12  14  16  19  21  24  27  30  33  37  41,  45  49  54  59  64  69  75  81  88  95 103 110 119 128 137 148 158 170, 182 195 209 224 239 256]
# bins.shape: (nfilt + 2, )
bins = np.floor((NFFT + 1) * hz_points / sample_rate).astype(int)  # 每个Hz点对应的频率bin# 3. 创建滤波器组的矩阵
fbank = np.zeros((nfilt, int(np.floor(NFFT / 2 + 1))))for m in range(1, nfilt + 1):f_m_minus = bins[m - 1]  # 左边界f_m = bins[m]  # 中间频率f_m_plus = bins[m + 1]  # 右边界# 左侧线性上升for k in range(f_m_minus, f_m):fbank[m - 1, k] = (k - f_m_minus) / (f_m - f_m_minus)# 右侧线性下降for k in range(f_m, f_m_plus):fbank[m - 1, k] = (f_m_plus - k) / (f_m_plus - f_m)# 4. 假设我们有信号的功率谱 pow_frames (形状: num_frames x NFFT/2+1)
# 假设 pow_frames 是任意生成的矩阵
num_frames = 100  # 假设有100帧信号
# pow_frames.shape: (num_frames, NFFT/2+1)
pow_frames = np.random.rand(num_frames, int(NFFT / 2 + 1))  # 随机生成的功率谱矩阵# 5. 将滤波器组应用到功率谱上
# fbank.shape: (nfilt, int(np.floor(NFFT / 2 + 1)))
filter_banks = np.dot(pow_frames, fbank.T)# 6. 防止数值稳定性问题,将0替换为非常小的数值
# filter_banks.shape: (num_frames, nfilt)
filter_banks = np.where(filter_banks == 0, np.finfo(float).eps, filter_banks)# 7. 转换为分贝(dB)
filter_banks = 20 * np.log10(filter_banks)# 打印滤波器组的响应
print(f"Mel滤波器组的响应形状: {filter_banks.shape}")

requency bins:频域中样本之间的间隔

  • 例如,如果采样率为100 Hz,FFT大小为100,则在[0 100)Hz之间有100个点。因此,将整个100 Hz范围划分为100个间隔,如0-1 Hz、1-2 Hz等。每个这样的小间隔,例如0-1 Hz,都是一个frequency bin

在这里插入图片描述

梅尔频率倒谱系数(MFCC)

可以把 MFCC 想象成将声音“简化成一张声音的名片”,这张名片包含了声音的主要特征,比如音调、音色等,而忽略掉了一些不太重要的细节
C ( n ) = ∑ m = 0 N − 1 log ( x m e l ) cos ⁡ ( π n ( m − 0.5 ) M ) , n = 1 , 2 , … , L C(n)=\sum_{m=0}^{N-1}\text{log}(x_{mel})\cos(\frac{\pi n(m-0.5)}M),n=1,2,\ldots,L C(n)=m=0N1log(xmel)cos(Mπn(m0.5)),n=1,2,,L,其中 C n C_n Cn表示第 n n n个梅尔频率倒谱系数、 N N N是窗口/帧的长度、 M M M是三角滤波器个数、 L L L阶指MFCC系数阶数 ⇒ \Rightarrow MFCC 特征向量由不同阶的倒谱系数组成。每个系数捕捉了语音信号在频率空间中的不同信息,通常只保留低阶的 MFCC 系数(如前 12 或 13 阶),因为这些系数包含了主要的音频特征,高阶系数则多是噪声或细节,不利于识别任务
在这里插入图片描述
在这里插入图片描述
时间分辨率:时域图横坐标上最小的时间间隔,即模拟信号采样后得到的离散信号中的密集程度,提高采样率可以提高时域内的时间分辨率

均值归一化

为了平衡频谱并改善信噪比(SNR),可以简单地从所有帧中减去每个系数的平均值

filter_banks -= (numpy.mean(filter_banks, axis=0) + 1e-8)

在这里插入图片描述对于MFCC:

mfcc -= (numpy.mean(mfcc, axis=0) + 1e-8)

在这里插入图片描述
在处理音频信号时,背景噪声常常表现为某些频率成分上的恒定噪声,这些噪声在整个音频中几乎保持一致。通过从所有帧中减去每个频率上的平均值,可以消除或减弱这种静态噪声,使得音频信号中的有用成分更加突出

总结

计算Mel刻度滤波器组Filter Banks由语音信号的性质和人类对这些信号的感知所驱动的;计算MFCC由一些机器学习算法的限制所驱动的
Filter Banks和MFCC对比:

  • 计算量:MFCC是在FBank的基础上进行的
  • 特征区分度:FBank特征相关性较高(相邻滤波器组有重叠),MFCC具有更好的判别度
  • 信息量:Filter Banks包含比MFCC更多的信息

如果机器学习算法不易受高度相关输入的影响,则使用Mel刻度滤波器组。如果机器学习算法易受相关输入的影响,则使用MFCC

参考文献

1、梅尔频率倒谱系数(MFCC)的原理讲解及python实现
2、时间分辨率、频率分辨率

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

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

相关文章

Qt的信号槽机制学习一

一、Qt理论知识简记 &#xff08;一&#xff09;信号与槽[1] 信号与槽是Qt编程的基础&#xff0c;其使得处理界面上各个组件的交互操作变得比较直观和简单&#xff0c;GUI&#xff08;Graphical User Interface&#xff09;程序设计的主要工作就是对界面上各组件的信号进行相应…

程序员的相亲囧途:三万相亲费,能否换回真爱?

在快节奏的都市生活中&#xff0c;相亲已成为不少单身男女寻找另一半的重要途径。然而&#xff0c;宁波的唐先生却在这条路上遭遇了不小的挫折。28岁的他&#xff0c;身高1米78&#xff0c;本应是相亲市场上的“香饽饽”&#xff0c;却在“我主良缘”交了三万块钱相亲费后&…

【Android】使用TextView实现按钮开关代替Switch开关

介绍 Android 本身自己带的有开关控件&#xff0c;但是很多时候我们是不愿意使用这种开关的&#xff0c;感觉使用起来比较麻烦&#xff0c;特别是遇到需要延迟操作的情况。 比如有一个需求是这样的&#xff1a;我们需要打开一个设置&#xff0c;但是这个设置是否打开需要经过…

AI自媒体变现路径大盘点!建议收藏!

当下的我做为一人公司或者超级个体为目标的创业模式&#xff0c;无论是在写作、图文和短视频输出方面&#xff0c;我都是运用了N个AI工具来提升我的生产力。 这种创业模式就是一个人N个AI的模式&#xff0c;我们可以通过AI工具做提效来赚取差价&#xff0c;以时间复利来累计财…

Python的协程与传统的线程相比,是否能更有效地利用计算资源?在多大程度上,这种效率是可测量的?如何量化Python协程的优势|协程|线程|性能优化

目录 1. 协程与线程的基本概念 1.1 线程 1.2 协程 2. 协程的实现原理 2.1 基本示例 3. 协程与线程的效率对比 3.1 资源利用率 3.2 性能测试 4. 使用场景分析 4.1 适用场景 4.2 不适用场景 5. 性能监测与测量 5.1 使用时间记录 5.2 使用第三方库 6. 总结与展望 P…

服务器文件访问协议

服务器文件访问协议 摘要NFS、CIFS、SMB概述SMBWindows SMBLinux SambaPython SMB NFS 摘要 本篇博客参考网上文档和博客&#xff0c;对基于网络的服务器/主机的文件访问、共享协议进行简要总结&#xff0c;完整内容将会不断更新&#xff0c;以便加深理解和记忆 NFS、CIFS、S…

docker占用磁盘过多问题

我在windows系统上用docker&#xff0c;安装在C盘环境下&#xff0c;我发现C盘占用了大量的空间&#xff0c;查找后发现是docker的映像文件占用的&#xff0c;于是开始清理&#xff0c;中间还踩个坑&#xff0c;记录一下&#xff0c;下次需要的时候方便找。 踩坑 我本想移动映…

HarmonyOS:@Watch装饰器:状态变量更改通知

Watch应用于对状态变量的监听。如果开发者需要关注某个状态变量的值是否改变&#xff0c;可以使用Watch为状态变量设置回调函数。 说明 从API version 9开始&#xff0c;该装饰器支持在ArkTS卡片中使用。 从API version 11开始&#xff0c;该装饰器支持在元服务中使用。 一、概…

【Qt】控件——布局管理器、常见的布局管理器、布局管理器的使用、垂直布局、水平布局、网格布局、表单布局、Spacer

文章目录 Qt布局管理器垂直布局水平布局网格布局表单布局Spacer Qt 布局管理器 之前在使用 Qt 创建界面上的控件时&#xff0c;大多是通过 “绝对定位” 的方式来设定的。即每个控件所在的位置都需要计算坐标&#xff0c;最终通过 setGeometry 或者 move 方式进行摆放。 然而&a…

配置和排查 Lombok 在 IDEA 中使用的详细步骤

在日常开发中&#xff0c;Java 代码常常需要大量的样板代码&#xff0c;比如 getter、setter、toString 等方法。Lombok 是一个 Java 库&#xff0c;可以通过注解的方式&#xff0c;自动生成这些常见的代码&#xff0c;从而让代码更加简洁、清晰。比如&#xff0c;我们可以通过…

快速在win11上利用hyper-v安装虚拟系统:遭遇Start PXE over ipv4

以前习惯使用VMware&#xff0c;但在win11上折腾了很久都遇到各种麻烦&#xff0c;索性就上微软自家的Hyper-V&#xff0c;。作为微软自家的产品&#xff0c;Hyper-V 与 Windows 11 操作系统紧密结合&#xff0c;具有良好的兼容性和稳定性。在安装和使用过程中&#xff0c;与系…

Python中的数据可视化:Matplotlib基础与高级技巧

Python中的数据可视化&#xff1a;Matplotlib基础与高级技巧 数据可视化是数据分析和数据科学中不可或缺的一部分。通过图表&#xff0c;我们可以更直观地观察数据的分布和趋势。Matplotlib作为Python最基础、也是最广泛使用的绘图库之一&#xff0c;不仅支持多种常用图表&…

沈阳乐晟睿浩科技有限公司抖音小店新篇章

在当今数字化时代&#xff0c;电商行业如雨后春笋般迅速崛起&#xff0c;其中抖音小店凭借其庞大的用户基础、精准的推荐算法和便捷的购物体验&#xff0c;成为了电商领域的新宠。在这场电商变革中&#xff0c;沈阳乐晟睿浩科技有限公司&#xff08;以下简称“乐晟睿浩”&#…

1,国产FPGA(紫光同创)-IP核-PLL

本文默认在0&#xff0c;国产FPGA&#xff08;紫光同创&#xff09;-新建PDS工程基础上完成。 1&#xff0c;添加IP核 右击&#xff08;1&#xff09;空白处进行添加&#xff0c;点击New IP&#xff08;2&#xff09;进行新建IP核。 选择本次实验要配置的IP核-PLL&#xff08;…

“智能二维码”实现光伏行业数字信息化管理

近日&#xff0c;为了提升管理效率&#xff0c;国电投建业光伏电站将二维码引入设备巡视和班组建设中。 首先&#xff0c;使用传统纸质巡视作业卡&#xff0c;巡视工作强度大&#xff0c;容易出现错误&#xff1b;此外&#xff0c;“三会一活动”和培训记录等班组建设过程材料大…

电脑录屏不用愁!四款免费录屏软件深度体验分享

虽然我不是专业的&#xff0c;但是我有一颗想要变得专业的心。作为一名经常需要录制教学视频和游戏直播的博主&#xff0c;我深知一款好用的录屏软件对于工作效率的重要性。今天&#xff0c;我就来和大家分享一下我最近亲测的四款免费录屏软件&#xff0c;来看看哪一款更适合你…

shodan5,参数使用,批量查找Mongodb未授权登录,jenkins批量挖掘

查找美国安全局漏洞 nww.nsa.gov&#xff08;美国安全局官方网站) net参数使用 搜索指定的ip网段 shodan search --limit 10 --fields ip_str,port net:208.88.84.0/24 (老美国家安全局的一个网段)可能直接访问不太行&#xff0c;可以使用host参数&#xff0c;得到域名再去…

部署MiniCPM-V

GitHub - OpenBMB/MiniCPM-V: MiniCPM-V 2.6: A GPT-4V Level MLLM for Single Image, Multi Image and Video on Your Phone 安装和执行 "Local WebUI Demo" 的步骤如下&#xff1a; 克隆仓库并导航到源文件夹&#xff1a; git clone https://github.com/OpenBMB/M…

Vue 权限管理

vue 中&#xff0c;比较常见的需要进行权限管控的权限控制实现思路有四条&#xff1a;、 菜单的控制 在登录请求中&#xff0c;会得到权限数据&#xff0c;当然&#xff0c;这个需要后端返回数据的支持&#xff0c;前端根据权限数据&#xff0c;展示对应的菜单&#xff0c;单…

MongoDB 8.0.3版本安装教程

MongoDB 8.0.3版本安装教程 一、下载安装 1.进入官网 2.选择社区版 3.点击下载 4.下载完成后点击安装 5.同意协议&#xff0c;下一步 6.选择第二个Custon&#xff0c;自定义安装 7.选择安装路径 &#xff01;记住安装路径 8.默认&#xff0c;下一步 9.取…