使用matlab/python进行双门限法的端点检测

这篇具有很好参考价值的文章主要介绍了使用matlab/python进行双门限法的端点检测。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

端点检测是指从包含语音的一段信号中确定出语音的起始点和结束点位置.
在进行基于音频信号的深度学习中,模型训练前进行端点检测,将每一个有效的激励信号提取出来,不仅可以增加样本数量,而且能够减少网络训练过程中不必要的计算,提升模型训练的准确率.

1.双门限法原理

双门限法最初是基于短时平均能量和短时平均过零率而提出的,其原理是汉语的韵母中有元音,能量较大,所以可以从短时平均能量中找到韵母,而声母是辅音,它们的频率较高,相应的短时平均过零率较大,所以用这两个特点找到声母和韵母,等于找出完整的汉语音节.双门限法是使用二级判决来实现的,如图所示.

使用matlab/python进行双门限法的端点检测

a是语音的波形,b是语音的短时平均能量,c是语音的短时平均过零率

进行判决的具体步骤如下:
1.第一级判决
①根据在语音短时能量包络线上选取的一个较高阈值(门限)T2进行一次粗判.
则高于该T2阈值肯定是语音(即在CD段之间肯定是语音),而语音起止点应位于该阈值与短时能量包络交点所对应的时间点之外(即在CD段之外).
②在平均能量上确定一个较低的阈值(门限)T1,并从C点往左,从D点往右搜索,分别找到短时能量包络与阈值T1相交的两个点B和E,于是BE段就是用双门限法根据短时能量所判定的语音段起止点位置.

2.第二级判决
以短时平均过零率为准,从B点往左和从E点往右搜索,找到短时平均过零率低于某个阈值T3的两点A和F,这便是语音段的起止点.

根据这两级判决,求出了语音的起始点位置A和结束点位置F.但考虑到语音发音时单词之间的静音区会有一个最小长度表示发音间的停顿,就是在小于阈值T3满足这样一个最小长度后才判断为该语音段结束,实际上相当于延长了语音尾音的长度,如图中在语音波形上标出语音的起止点分别为A和F+(从图中看出终止点位置为F,而实际处理中延长到
F+).

在端点检测的具体运行中,首先是对语音进行分帧,在分帧的基础上方能求出短时平均能量和短时平均过零率,然后逐帧地依阈值进行比较和判断.

2.双参数的双门限端点检测的实例

使用能量,自相关函数,用双门限判决来提取端点.

之前使用能量和过零率检测端点的双门限法,实际上就是一个双参数的双门限检测法,它涉及能量和过零率两个参数,同时给出三个或四个门限值T1,T2,T3(T4).其中,有一个参数是dst1,另一个参数是dst2.

以下进一步介绍二级判决说明
1.第一级判决
①根据在第一个参数dst1上选取的一个较高的阈值T2(或在第二个参数dst2上选取的一个较高阈值T4),进行一次粗判,就是高于该T2(或T4)阈值肯定是语音.
②在第一个参数dst1上确定一个较低的阈值T1,从①中的交汇点向两边扩展搜索,分别找到dst1与阈值T1相交的两个点,粗判定为语音段的起止点位置.
2.第二级判决
以dst2为准,从第一级判断得到的起止点位置向两端扩展搜索,找到dst2与某个阈值T3
相交的两点,这边是语音段的起止点.

按照这样的思路编制出相应的函数:
(1)vad_param2D
功能:按照dst1和dst2两个参数提取语音端点的位置
调用格式:[voiceseg,vsl,SF,NF]=vad_param2D(dst1,dst2,T1,T2,T3,T4);

实例:用双参数进行端点检测

①在输入参数中,x是语音信号序列,为了要分帧,设置帧长为wlen和帧移为inc,NIS是前导无话段的帧数.

在语音处理中为了能估算噪声的情况,往往在一段语音的前部有一段前导无话段,利用该段前导无话段来估算噪声的特性.

在实际中,有时可能不知道前导无话段的帧数,但从语音信号的波形图中可以估算出前导无话段的时长IS,有了IS就能计算出前导无话段的帧数NIS
NIS = fix(IS * fs - wlen) / inc + 1)

②在这里的讨论中都认为噪声是平稳的,所以估算出的噪声短时平均能量和自相关函数适用于整段语音.

③语音信号为x(n),加窗分帧后为xi(m),其中下标i表示为第i帧,帧长为N,总帧数为fn,而每帧的能量计算为:
A M P i   = ∑ m = 1 N x i 2 ( m ) AMP_i\ = \displaystyle \sum^{N} _{m=1} x_i^{2}(m) AMPi =m=1Nxi2(m)

语音信号为x(n),加窗分帧后为xi(m),其中下标i表示为第i帧(i=1,2,3,……,M),M为总帧数.
每帧数据的短时自相关函数定义为:
R i ( k ) = ∑ m = 1 L − k x i ( m ) x i ( m + k ) R_i(k) = \displaystyle \sum^{L-k} _{m=1} x_i(m)x_i(m+k) Ri(k)=m=1Lkxi(m)xi(m+k)
L为语音分帧后的长度,k为延迟量
如果在相邻两帧之间计算相关函数,便是互相关函数,其表达式为:
R i ( k ) = ∑ m = 1 L − k x i − 1 ( m ) x i ( m + k ) R_i(k) = \displaystyle \sum^{L-k} _{m=1} x_{i-1}(m)x_i(m+k) Ri(k)=m=1Lkxi1(m)xi(m+k)
因为语音信号是准稳态信号,它的变化较缓慢,根据噪声的情况设置两个阈值T3和T4,当相关函数最大值大于T4时,便判定为是语音;当相关函数最大值大于或小于T3时,则判定为语音信号的端点.

④先对前导无话段计算噪声短时平均能量和自相关函数:
etemp=mean(etemp(1:NIS));
thredth=max(Rum(2:NIS));

再在这两值的基础上设置能量的两个阈值(T1)和(T2),以及互相关函数的阈值(T3):
T2 = 4etemp; T1 = 2etemp;
T3=1.1*thredth;

在这里阈值不设为一个固定的值,将会随前导无话段计算噪声的情况动态地变动.有了阈值以后就能按双门限法进行检测了.

⑤在检测完成后的端点为x1和x2,还进一步设置了SF和NF这两个序列,它们都是1xfn的数组,
SF=1表示该帧为有话帧,SF=0表示该帧为无话帧;
NF与SF相反,NF=1表示该帧为无话帧,NF=0表示该帧为有话帧.

⑥同时又设置了一个voiceseg结构数据,它也给出了语音端点的信息.因为在分析的一组语音中可能中间有几次停顿,每一组有一个开始时间和结束时间,在voiceseg结构数据中就包含了每一组有话音段的开始时间,结束时间和这组有话段语音的长度,它们都是以帧为单位.

voiceseg的计算是通过以下两个语句完成的:
speechIndex=find(SF==1);
voiceseg=findSegment(speechIndex);

程序清单如下:


clear all; clc; close all;
IS=0.25;                                % 设置前导无话段长度
wlen=200;                               % 设置帧长为25ms
inc=80;                                 % 求帧移
SNR=10;                            		 % 设置信噪比
fle = 'D:\audio\test1\51_674_740001.wav';

[xx,fs]=wavread(fle);                   % 读入数据
xx=xx-mean(xx);                         % 消除直流分量
x=xx/max(abs(xx));                      % 幅值归一化
N=length(x);                            % 取信号长度
time=(0:N-1)/fs;                        % 设置时间
signal=Gnoisegen(x,SNR);                % 叠加噪声
wnd=hamming(wlen);                      % 设置窗函数
overlap=wlen-inc;                       % 求重叠区长度
NIS=fix((IS*fs-wlen)/inc +1);           % 求前导无话段帧数
y=enframe(signal,wnd,inc)';             % 分帧
fn=size(y,2);                           % 求帧数
frameTime=frame2time(fn, wlen, inc, fs);% 计算各帧对应的时间

for k=2 : fn                            % 计算互相关函数
    u1=y(:,k-1);
    u2=y(:,k);
    ru=xcorr(u1,u2);
    Ru(k)=max(ru);
end
Rum=multimidfilter(Ru,1);              % 平滑处理
Rum=Rum/max(Rum);                       % 归一化
%thredth=max(Rum(2:NIS));                % 计算阈值
%T3=1.1*thredth;
%T4=1.3*thredth;
T3 =  0.065;

etemp=sum(y.^2);                        % 求取短时平均能量
etemp=etemp/max(etemp);                 % 能量幅值归一化
fn=size(y,2);                           % 帧数
% etemp = mean(etemp(1:NIS));           %计算初始无话段区间的能量平均值
% T2 = 4*etemp; T1 = 2*etemp;					%设置能量的阈值
T1=0.2;                            	 	  % 设置阈值
T2=0.15;

[voiceseg,vsl,SF,NF]=vad_param2D(etemp,Rum,T1,T2,T3);   % 双参数双门限端点检测

% 作图
subplot 311; plot(time,x,'k');
title('纯语音波形');
ylabel('幅值'); axis([0 max(time) -1 1]);

subplot 312; plot(frameTime,etemp,'k')
title('语音短时能量图');
ylabel('幅值'); axis([0 max(time) 0 1]);
xlabel('时间/s');
line([0 max(time)],[T1 T1],'color','b','LineStyle','--');
line([0 max(time)],[T2 T2],'color','r','LineStyle','--');

subplot 313; plot(frameTime,Rum,'k');
title('短时自相关函数'); axis([0 max(time) 0 1.2]);
xlabel('时间/s'); ylabel('幅值'); 
line([0,frameTime(fn)], [T3 T3], 'color','b','LineStyle','--');

for k=1 : vsl                           % 标出语音端点
    nx1=voiceseg(k).begin; nx2=voiceseg(k).end;
    fprintf('%4d   %4d   %4d    %4d\n',k,nx1,nx2,nx2-nx1);
    subplot 311; 
    line([frameTime(nx1) frameTime(nx1)],[-1 1],'color','b','LineStyle','--');
    line([frameTime(nx2) frameTime(nx2)],[-1 1],'color','r','LineStyle','--');
end

端点检测结果图
使用matlab/python进行双门限法的端点检测
3.vad_param2D函数说明及其他说明

名称:vad_param2D
功能:用短时平均能量和自相关函数最大值提取语音端点位置
调用格式:function [voiceseg,vsl,SF,NF]=vad_param2D(dst1,dst2,T1,T2,T3,T4)
说明:
①dst1和dst2可以是上述的能量和过零率,也可以是其他参数,如自相关函数等,
②dst1的两个阈值T1和T2,dst2的一个或两个阈值T3(和T4)都是在调用该函数之前先计算出来,这些阈值可以取决于dst1和dst2原始数据上的数值,也可以是取经过平滑处理的数值.
③对dst2可只带一个阈值(在函数调用时只写T3,不写T4),也可带两个阈值,在函数中会自动地判断是否带有T4,只有带了T4以后才会用T4进行判断.

⑦在vad_param2D函数中设置了一些参数:maxsilence表示一段语音结束时静音区的最小长度,minlin表示有话段的最小长度,它们都是固定的.

而对T1,T2,T3等参数虽是动态变化的,但它们的比例系数也是固定的.

实际上,在端点检测中想要正确的检测会受到很多因素的影响:噪声环境是一个主要因素,不同的噪声,不同的信噪比都会影响到检测的正确性,所以这些参数可以改变,可以按实际情况进行调整.

函数流程图如下
使用matlab/python进行双门限法的端点检测

名称:findSegment
功能:根据SF中数值为1的地址组合出每一组有话音段的开始时间,结束时间和这组有话段语音的长度.
调用格式:function soundSegment=findSegment(express)
程序清单如下:

function soundSegment=findSegment(express)
if express(1)==0
    voicedIndex=find(express);                     % 寻找express中为1的位置
else
    voicedIndex=express;
end

soundSegment = [];
k = 1;
soundSegment(k).begin = voicedIndex(1);            % 设置第一组有话段的起始位置
for i=1:length(voicedIndex)-1,
	if voicedIndex(i+1)-voicedIndex(i)>1,          % 本组有话段结束
		soundSegment(k).end = voicedIndex(i);      % 设置本组有话段的结束位置
		soundSegment(k+1).begin = voicedIndex(i+1);% 设置下一组有话段的起始位置  
		k = k+1;
	end
end
soundSegment(k).end = voicedIndex(end);            % 最后一组有话段的结束位置
% 计算每组有话段的长度
for i=1 :k
    soundSegment(i).duration=soundSegment(i).end-soundSegment(i).begin+1;
end

注:其实单参数(只用短时平均能量)的双门限法就可以对音频数据集进行端点检测.效果不错.

3.python实现双门限法端点检测

"""
    本程序是进行端点检测
    双门限法进行端点检测
"""
import numpy as np
import wave
from scipy.io import wavfile
import soundfile as sf
import numpy as np
import matplotlib.pyplot as plt
import os
import re
from pydub import AudioSegment
plt.rcParams['font.family'] = ['sans-serif']
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

def STAc(x):
    """
    计算短时相关函数
    :param x:
    :return:
    """
    para = np.zeros(x.shape)
    fn = x.shape[1]
    for i in range(fn):
        R = np.correlate(x[:, i], x[:, i], 'valid')
        para[:, i] = R
    return para


def STEn(x, win, inc):
    """
    计算短时能量函数
    :param x:
    :param win:
    :param inc:
    :return:
    """
    X = enframe(x, win, inc)
    s = np.multiply(X, X)
    return np.sum(s, axis=1)


def STZcr(x, win, inc, delta=0):
    """
    计算短时过零率
    :param x:
    :param win:
    :param inc:
    :return:
    """
    absx = np.abs(x)
    x = np.where(absx < delta, 0, x)
    X = enframe(x, win, inc)
    X1 = X[:, :-1]
    X2 = X[:, 1:]
    s = np.multiply(X1, X2)
    sgn = np.where(s < 0, 1, 0)
    return np.sum(sgn, axis=1)


def FrameTimeC(frameNum, frameLen, inc, fs):
    ll = np.array([i for i in range(frameNum)])
    return ((ll - 1) * inc + frameLen / 2) / fs


def enframe(x, win, inc=None):
    nx = len(x)
    if isinstance(win, list) or isinstance(win, np.ndarray):
        nwin = len(win)
        nlen = nwin  # 帧长=窗长
    elif isinstance(win, int):
        nwin = 1
        nlen = win  # 设置为帧长
    if inc is None:
        inc = nlen
    nf = (nx - nlen + inc) // inc
    frameout = np.zeros((nf, nlen))
    indf = np.multiply(inc, np.array([i for i in range(nf)]))
    for i in range(nf):
        frameout[i, :] = x[indf[i]:indf[i] + nlen]
    if isinstance(win, list) or isinstance(win, np.ndarray):
        frameout = np.multiply(frameout, np.array(win))
    return frameout

def findSegment(express):
    """
    分割成語音段
    :param express:
    :return:
    """
    if express[0] == 0:
        voiceIndex = np.where(express)
    else:
        voiceIndex = express
    d_voice = np.where(np.diff(voiceIndex) > 1)[0]
    voiceseg = {}
    if len(d_voice) > 0:
        for i in range(len(d_voice) + 1):
            seg = {}
            if i == 0:
                st = voiceIndex[0]
                en = voiceIndex[d_voice[i]]
            elif i == len(d_voice):
                st = voiceIndex[d_voice[i - 1]+1]
                en = voiceIndex[-1]
            else:
                st = voiceIndex[d_voice[i - 1]+1]
                en = voiceIndex[d_voice[i]]
            seg['start'] = st
            seg['end'] = en
            seg['duration'] = en - st + 1
            voiceseg[i] = seg
    return voiceseg

def vad_TwoThr1(x, wlen, inc, NIS):
    """
    使用门限法检测语音段
    :param x: 语音信号
    :param wlen: 分帧长度
    :param inc: 帧移
    :param NIS:
    :return:
    """
    maxsilence = 15
    minlen = 5
    status = 0
    y = enframe(x, wlen, inc)
    fn = y.shape[0]
    amp = STEn(x, wlen, inc)
    ampth = np.mean(amp[:NIS])
    amp2 = 7.5 * ampth
    amp1 = 10 * ampth
    xn = 0
    count = np.zeros(fn)
    silence = np.zeros(fn)
    x1 = np.zeros(fn)
    x2 = np.zeros(fn)
    for n in range(fn):
        if status == 0 or status == 1:
            if amp[n] > amp1:
                x1[xn] = max(1, n - count[xn] - 1)
                status = 2
                silence[xn] = 0
                count[xn] += 1
            elif amp[n] > amp2 :
                status = 1
                count[xn] += 1
            else:
                status = 0
                count[xn] = 0
                x1[xn] = 0
                x2[xn] = 0

        elif status == 2:
            if amp[n] > amp2 :
                count[xn] += 1
            else:
                silence[xn] += 1
                if silence[xn] < maxsilence:
                    count[xn] += 1
                elif count[xn] < minlen:
                    status = 0
                    silence[xn] = 0
                    count[xn] = 0
                else:
                    status = 3
                    x2[xn] = x1[xn] + count[xn]
        elif status == 3:
            status = 0
            xn += 1
            count[xn] = 0
            silence[xn] = 0
            x1[xn] = 0
            x2[xn] = 0
    el = len(x1[:xn])
    if x1[el - 1] == 0:
        el -= 1
    if x2[el - 1] == 0:
        print('Error: Not find endding point!\n')
        x2[el] = fn
    SF = np.zeros(fn)
    NF = np.ones(fn)
    for i in range(el):
        SF[int(x1[i]):int(x2[i])] = 1
        NF[int(x1[i]):int(x2[i])] = 0
    voiceseg = findSegment(np.where(SF == 1)[0])
    vsl = len(voiceseg.keys())
    return voiceseg, vsl, SF, NF, amp



if __name__ == '__main__':

    wavepath = './vadtest/60_805.wav'
    f = wave.open(wavepath, 'rb')
    params = f.getparams()
    nchannels, sampwidth, fs, nframes = params[:4]  # 声道数、量化位数、采样频率、采样点数
    str_data = f.readframes(nframes)  # 读取音频,字符串格式
    f.close()
    wavedata = np.fromstring(str_data, dtype=np.short)  # 将字符串转化为浮点型数据
    data = wavedata * 1.0 / (max(abs(wavedata)))  # wave幅值归一化

    data /= np.max(data)
    N = len(data)
    wlen = 200
    inc = 80
    IS = 1
    overlap = wlen - inc
    NIS = int((IS * fs - wlen) // inc + 1)
    fn = (N - wlen) // inc + 1

    frameTime = FrameTimeC(fn, wlen, inc, fs)  # 计算出对应的时间
    time = [i / fs for i in range(N)]

    #voiceseg, vsl, SF, NF, amp, zcr = vad_TwoThr(data, wlen, inc, NIS)
    voiceseg, vsl, SF, NF, amp = vad_TwoThr1(data, wlen, inc, NIS)

    plt.subplot(2, 1, 1)
    plt.ylabel('幅值')
    plt.ylim((-1, 1))  # 设置y轴刻度范围为0~11
    plt.title('纯音频波形图')  # 设置绘图标题
    plt.plot(time, data)

    plt.subplot(2, 1, 2)
    plt.plot(frameTime, amp)
    plt.ylabel('幅值')
    plt.xlabel('时间(s)')  # 设置x、y轴标签
    plt.title('音频短时能量图')  # 设置绘图标题

    for i in range(vsl):
        plt.subplot(2, 1, 1)
        plt.vlines(frameTime[voiceseg[i]['start']],-1,1,colors='r',linestyles='dashed')
        plt.vlines(frameTime[voiceseg[i]['end']], -1, 1, colors='g', linestyles='dashed')
    plt.show()

效果图使用matlab/python进行双门限法的端点检测

所涉及知识都是参考自—>matlab在语音信号分析与合成中的应用文章来源地址https://www.toymoban.com/news/detail-485170.html

到了这里,关于使用matlab/python进行双门限法的端点检测的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【图像处理】使用Python进行实时人脸检测和识别

            你有没有想过用Python构建一个面部识别系统?不要再看了!在本教程中,我们将使用 face_recognition 库来检测和识别视频流、图像甚至使用网络摄像头实时检测和识别人脸。         人脸识别和人脸检测是计算机视觉领域的两个独立任务。         人脸检测

    2024年02月13日
    浏览(56)
  • 【采用有限元法技术计算固有频率和欧拉屈曲荷载】使用有限元法的柱子的固有频率和屈曲荷载(Matlab代码实现)

     💥💥💞💞 欢迎来到本博客 ❤️❤️💥💥 🏆博主优势: 🌞🌞🌞 博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️ 座右铭: 行百里者,半于九十。 📋📋📋 本文目录如下: 🎁🎁🎁 目录 💥1 概述 📚2 运行结果 🎉3 参考文献 🌈4 Matlab代码实现 有限元

    2024年02月15日
    浏览(48)
  • MATLAB - 计算关节扭矩以平衡端点力和力矩

    产生力矩以平衡作用在平面机器人末端执行器体上的端点力。要使用各种方法计算关节力矩,请使用刚体树机器人模型的几何雅各比(geometricJacobian)和反动力学(inverseDynamics)对象函数。 双关节刚体树机器人是一个二维平面机器人。关节配置以列向量形式输出。 端点力 e

    2024年01月16日
    浏览(36)
  • 在 python 中使用 Haar-Cascade 进行人脸检测

    介绍 在本文中,我们将讨论在 OpenCV python 中使用 Haar Cascade(级联)实现人脸检测器。 识别图像中的给定对象称为对象检测。可以使用多种技术来完成此任务,但在本文中,我们将使用带有预训练 XML 文件的 haar 级联。这是执行对象检测的最简单方法。 Haar 级联已用于低边缘

    2024年02月08日
    浏览(34)
  • Spring Cloud 微服务中 gateway 网关如何设置健康检测端点

    主要是为了让 k8s 识别到网关项目已经就绪,但是又不想在里面通过 Controller 实现。因为在 Controller 中这样做并不是最佳实践,因为 Gateway 的设计初衷是专注于路由和过滤,而不是业务逻辑的处理。 在 Gateway 中配置健康检查端点可以通过以下方式进行(可根据实际需求进行扩

    2024年01月17日
    浏览(47)
  • 利用Matlab进行图像分割和边缘检测

    1、灰度阀值分割 (1)单阈值分割图像 先将一幅彩色图像转换为灰度图像,显示其直方图,参考直方图中灰度的分布,尝试确定阈值;应反复调节阈值的大小,直至二值化的效果最为满意为止。给图像加上零均值的高斯噪声重复上述过程,注意阈值的选择。 (2)多阈值分割图

    2024年01月17日
    浏览(47)
  • Python——一文详解使用yolov5进行目标检测全流程(无需gpu)

    本文按步骤详细介绍了使用yolov5进行目标检测的全流程,包括:模型下载、环境配置、数据集准备和数据预处理、模型调整、模型训练、进行目标检测和检测结果分析。本文全部流程使用cpu完成(无需gpu),旨在跑通流程,模型训练过程较慢,且未能到达最优结果。需要 py

    2024年03月18日
    浏览(55)
  • 匈牙利法的Matlab代码及测试

    2024年02月11日
    浏览(34)
  • 01-10 周二 PyCharm远程Linux服务器配置进行端点调试

    01-10 周二 PyCharm远程Linux服务器配置 时间 版本 修改人 描述 2023年1月10日14:04:15 V0.1 宋全恒 新建文档 2023年2月6日11:03:45 V0.2 宋全恒 添加快捷指令别名的实现方便虚拟环境的切换 使用 PyCharm,您可以使用位于另一台计算机(服务器)上的解释器调试应用程序 。 参考该博客  在使用

    2024年02月07日
    浏览(62)
  • 树莓派CSI摄像头使用python调用opencv库函数进行运动检测识别

    目录 一、完成摄像头的调用 二、利用python调用opencv库函数对图像进行处理 2.1 图像处理大体流程 2.2 opencv调用函数的参数以及含义 2.2.1 ret, img = cap.read() 读取帧图像 2.2.2 cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 灰度图像 2.2.3 gray_diff_img = cv2.absdiff(gray_img, previous_img) 帧差法 2.2.4 cv2.thre

    2024年02月15日
    浏览(50)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包