深度学习用于工业参数优化(基于深度学习的单通道语音增强)

本文代码请见: https://github.com/Ryuk17/SpeechAlgorithms

作者:凌逆战

博客地址(转载请指明出处): https://www.cnblogs.com/LXP-Never/p/14142108.html

传统的语音增强方法基于一些设定好的先验假设,但是这些先验假设存在一定的不合理之处。此外传统语音增强依赖于参数的设定,人工经验等。随着深度学习的发展,越来越多的人开始注意使用深度学习来解决语音增强问题。由于单通道使用场景较多,本文就以单通道语音增强为例。

目前基于深度神经网络单通道语音增强方法大致可以分为两类:

第一种基于 映射 的方法 第二种基于 mask 的方法

基于映射的语音增强

基于映射的语音增强方法通过训练神经网络模型直接学习带噪语音和纯净语音之间的映射关系,有两种映射方案:

频谱映射 :使用模型预测语音的时频域表示,之后再将语音的时频域表示通过波形合成技术恢复成时域信号。使用最多的时频域表示特征是短时傅里叶变换谱,利用人耳对相位不敏感的特性,一般只预测短时傅里叶变换幅度谱,并使用混合语音的相位合成预测语音的波形。

波形映射 :直接将带噪语音波形输入到模型,模型直接输出纯净语音波形的方法。

我们以频谱映射举例说明一下:

训练阶段

输入:这里采用较为简单地特征,即 带噪声语音信号的幅度谱 ,也可以采用其他的特征。值得一提的是,如果你的输入是一帧,对应输出也是一帧的话效果一般不会很好。因此一般采用 扩帧 的技术,如下图所示,即每次输入除了当前帧外还需要输入当前帧的前几帧和后几帧。这是因为语音具有短时相关性,对输入几帧是为了更好的学习这种相关性

Label: 数据的 label为纯净语音信号的幅度谱 ,这里只需要一帧就够了。 损失函数: 学习噪声幅度谱与纯净语音信号的幅度谱类似于一个回归问题,因此损失函数采用回归常用的损失函数,如均方误差(MSE)、均方根误差(RMSE)或平均绝对值误差(MAE)等…. 最后一层的激活函数 :由于是回归问题,最后一层采用线性激活函数 其他 :输入的幅度谱进行 归一化 可以加速学习过程和更好的收敛。如果不采用幅度谱可以采用功率谱,要注意的是功率谱如果采用的单位是dB,需要对数据进行预处理,因为log的定义域不能为0,简单的方法就是在取对数前给等于0的功率谱加上一个非常小的数

增强阶段

输入: 输入为噪声信号的幅度谱,这里同样需要扩帧。对输入数据进行处理可以在语音信号加上值为0的语音帧,或者舍弃首尾的几帧。如果训练过程对输入进行了归一化,那么这里同样需要进行归一化 输出: 输入为估计的纯净语音幅度谱 重构波形: 在计算输入信号幅度谱的时候需要保存每一帧的相位信息,然后用保存好的相位信息和模型输出的幅度谱重构语音波形,代码如下所示。

spectrum = magnitude * np.exp(1.0j * phase)

基于Mask的语音增强

Mask这个单词有的地方翻译成掩蔽有的地方翻译成掩膜,我个人倾向于翻译成“掩蔽”,本文就用掩蔽作为Mask的翻译。

时频掩蔽

我们都知道语音信号可以通过时域波形或者频域的各种频谱表示,此外语谱图可以同时展示时域和频域的信息,因此被广泛应用,如下图所示。语谱图上的像素点就可以称为 时频单元

现在我们假设有两段语音信号,一段是纯净信号,另一段是噪声,他们混合在一起了,时域波形和对应的语谱图分别如下图所示:

如果我们想将纯净语音信号从混合信号中抽离在时域方面是很难做到的。现在我们从语谱图(语音的时频单元)角度入手去解决语音分离问题。首先我们提出两个假设:

1、我们假设信号能量稀疏的,即对于大多数时频区域它的能量为0,如下图所示,我们可以看到大多数区域的值,即频域能量为0。

2、我们假设信号能量不相交的,即它们的时频区域不重叠或者重叠较少,如下图所示,我们可以看到时频区域不为0的地方不重叠或者有较少部分的重叠。

基于以上两点假设,我们就可以分离我们想要的信号和噪声信号。给可能属于一个信号源的区域分配掩码为1,其余的分配掩码0,如下图所示。

我们通过0和1的二值掩码然后乘以混合信号的语谱图就可以得到我们想要喜好的语谱图了,如下图所示。

神经模型一般直接预测时频掩蔽M(t,f)M(t,f),之后再通过M(t,f)M(t,f)与混合语音Y(t,f)Y(t,f)相乘得到预测的纯净语音^S(t,f)=^M(t,f)\otimesY(t,y)S^(t,f)=M^(t,f)\otimesY(t,y),其中⊗⊗代表哈达玛乘积(Hadamard Product)。在语音增强研究的发展过程中,研究人员提出了一系列的时频掩蔽作为训练目标:

理想二值掩蔽(Ideal Binary Mask,IBM)

原理 :由于 语音在时频域上是稀疏分布 的,对于一个具体的时频单元,语音和噪声的能量差异通常比较大,因此大多数时频单元上的信噪比极高或极低。IBM 是对这种现实情况的简化描述,将连续的时频单元信噪比离散化为两种状态 1 和0, 在一个时频单元内:如果语音占主导(高信噪比),则被标记为 1;反之如果噪声占主导(低信噪比),则标记为 0 。最后将 IBM 和带噪语音相乘,实际上就是将低信噪比的时频单元置零,以此达到消除噪声的目的。

因此,IBM 的值由时频单元上的信噪比SNR(t,f)和设定的阈值比较之后决定:

公式1:IBM(t,f)={1,SNR(t,f)>LC0, else 公式1:IBM(t,f)={1,SNR⁡(t,f)>LC0, else

其中LC为阈值,一般取0,SNR计算公式为:

公式2:SNR(t,f)=10∗log10(|S(t,f)|2|N(t,f)|2)公式2:SNR⁡(t,f)=10∗log⁡10(|S(t,f)|2|N(t,f)|2)

优点 :IBM 作为二值目标,只需要使用简单的二分类模型进行预测,并且可以有效地提高语音的可懂度。 缺点 :IBM 只有 0 和 1 两种取值,对带噪语音的处理过于粗暴,处理过程中引入了较大的噪声,无法有效地改善语音质量。

我看到过很多种写法

def IBM(clean_speech, noise):
"""计算 ideal binary mask (IBM)
Erdogan, Hakan, et al. "Phase-sensitive and recognition-boosted speech separation using deep recurrent neural networks." ICASSP, 2015.
:param clean_speech: 纯净语音 STFT
:param noise: 噪声 STFT
:return: 纯净语音的理想二值掩膜 IBM
"""
mask = np.zeros(np.shape(clean_speech), dtype=np.float32)
mask[np.abs(clean_speech) >= np.abs(noise)] = 1.0
return mask

第二种

def IBM_SNR(clean_speech, noise_speech):
"""计算 ideal binary mask (IBM)
Erdogan, Hakan, et al. "Phase-sensitive and recognition-boosted speech separation using deep recurrent neural networks." ICASSP, 2015.
:param clean_speech: 纯净语音 STFT
:param noise_speech: 带噪语音 STFT
:return: 纯净语音的理想二值掩膜 IBM
"""
_eps = np.finfo(np.float).eps # 避免除以0
theta = 0.5 # a majority vote
alpha = 1 # ratio of magnitudes
mask = np.divide(np.abs(clean_speech) ** alpha, (_eps np.abs(noise_speech) ** alpha))
mask[np.where(mask >= theta)] = 1
mask[np.where(mask < theta)] = 0
return mask

第二种

第三种

def IBM_SNR(clean_speech, noise_speech,delta_size):
"""计算 ideal binary mask (IBM)
Erdogan, Hakan, et al. "Phase-sensitive and recognition-boosted speech separation using deep recurrent neural networks." ICASSP, 2015.
:param clean_speech: 纯净语音 STFT
:param noise_speech: 带噪语音 STFT
:return: 纯净语音的理想二值掩膜 IBM
"""
_eps = np.finfo(np.float).eps # 避免除以0
local_snr = 0
ibm = np.where(10. * np.log10(np.abs(clean_speech) ** 2 / np.abs(noise_speech) ** 2) >= local_snr, 1., 0.)

if delta_size > 0:
ibm = ibm[:, delta_size: -delta_size]
return ibm

View Code

理想浮值掩蔽(Ideal Ratio Mask,IRM)

原理 :基于语音和噪声正交,即不相关的假设下,即S(t,f)⋅N(t,f)=0S(t,f)⋅N(t,f)=0,IRM直接刻画了时频单元内纯净语音能量和带噪语音能量的比值,是目前使用非常广泛的一种掩蔽方法。

在这个假设下带噪语音的能量可以表示为:

公式2:|Y(t,f)|2=|S(t,f) N(t,f)|2=|S(t,f)|2 |N(t,f)|2公式2:|Y(t,f)|2=|S(t,f) N(t,f)|2=|S(t,f)|2 |N(t,f)|2

因此得到 IRM 为:

公式3:IRM(t,f)=(|S(t,f)|2|Y(t,f)|2)β=(|S(t,f)|2|S(t,f)|2 |N(t,f)|2)β公式3:IRM(t,f)=(|S(t,f)|2|Y(t,f)|2)β=(|S(t,f)|2|S(t,f)|2 |N(t,f)|2)β

其中ββ 为可调节尺度因子,一般取0.5。 IRM取值在 0 到 1 之间,值越大代表时频单元内语音占的比重越高。另外,IRM 的平方形式就是经典的维纳滤波器(Wiener Filter),它是均方误差意义上的最优滤波器。

优点 :IRM 是分布在 0 到 1 的连续值,因此 IRM 是对目标语音更加准确的刻画,这使得 IRM 可以有效地同时提升语音的质量和可懂度。 缺点 :使用未处理的相位信息进行语音重构(相位对于感知质量也很重要)

def IRM(clean_speech, noise):
"""计算Compute ideal ratio mask (IRM)
"Phase-sensitive and recognition-boosted speech separation using deep recurrent neural networks," in ICASSP 2015, Brisbane, April, 2015.
:param clean_speech: 纯净语音 STFT
:param noise: 噪音 STFT
:return: 在原始音频域中分离(恢复)的语音
"""
_eps = np.finfo(np.float).eps # 防止分母出现0
mask = np.abs(clean_speech) / (np.abs(clean_speech) np.abs(noise) _eps)
return mask

def Wiener_like(clean_speech, noise):
"""计算Wiener-like Mask
"Phase-sensitive and recognition-boosted speech separation using deep recurrent neural networks," in ICASSP 2015, Brisbane, April, 2015.
:param clean_speech: 纯净语音 STFT
:param noise: 噪音 STFT
:return: 在原始音频域中分离(恢复)的语音
"""
_eps = np.finfo(np.float).eps # 防止分母出现0
mask = np.divide((np.abs(clean_speech) ** 2 _eps),
(np.abs(clean_speech) ** 2 np.abs(noise) ** 2) _eps)
return mask

理想幅度掩蔽(Ideal Amplitude Mask,IAM)

原理 :IAM也称为Spectral Magnitude Mask(SMM),不对噪声和语音做出正交假设,IAM刻画的也是纯净语音和带噪语音的能量比值

公式4:IAM(t,f)=|S(t,f)||Y(t,f)|公式4:IAM⁡(t,f)=|S(t,f)||Y(t,f)|

由于在语音和噪声叠加的过程中,存在反相相消的情况,因此并不能保证带噪语音的幅值总是大于纯净语音的幅值,因此 IAM 的范围是[0, ∞][0, ∞]。如果目标中出现非常大的数值,会导致训练过程出现异常。为了稳定训练,一般会将 IAM 进行截断到一定的范围内。为了确定合适的截断范围,我们可以在训练数据上采样 100 句语音并计算 IAM,就可以对IAM 的数值范围得到一个近似的估计,得到如图 3.4 的结果。一般将 IAM 截断到[0, 1]或者[0, 2]即可,因为只有非常少部分的 IAM 落在了[2, ∞][2, ∞]的区间内。

图* IAM数值分布直方图

def IAM(clean_speech, noise_speech):
"""计算ideal amplitude mask (IAM)
"Phase-sensitive and recognition-boosted speech separation using deep recurrent neural networks," in ICASSP 2015, Brisbane, April, 2015.
:param clean_speech: 纯净语音 STFT
:param noise_speech: 带噪语音 STFT
:return:
"""
_eps = np.finfo(np.float).eps # 避免除以0
mask = np.abs(clean_speech) / (np.abs(noise_speech) _eps)
return mask

相位敏感掩蔽(Phase Sensitive Mask,PSM)

原理 :PSM考虑到相位误差的时频掩蔽

PSM在形式上是 IAM 乘上纯净语音和带噪语音之间的余弦相似度

公式5:PSM(t,f)=|S(t,f)||Y(t,f)|cos(θS−θY)公式5:PSM(t,f)=|S(t,f)||Y(t,f)|cos⁡(θS−θY)

式中θS−θYθS−θY表示纯净语音和带噪语音的相位差,不难看出,PSM 的取值范围是[−∞, ∞][−∞, ∞],因此也需要截断,我们同样使用直方图统计PSM的数值分布范围,从下图可以看出在0 和 1 附近出现两个明显的峰值,这也再次说明了 IBM 目标设计的合理性。为了方便,一般将 PSM 截断到[0, 1],或者是适当将截断的区间放大到[-1, 2]。

PSM数值分布直方图

优点 :纯净语音相位和带噪语音相位的差异,加入相位信息之后,PSM方法可以获得更高的SNR,因而降噪效果比IAM更好。

def PSM(clean_speech, noise_speech):
"""计算ideal phase-sensitive mask (PSM)
:param clean_speech: 纯净语音 STFT
:param noise_speech:带噪语音 STFT
:return:
"""
_eps = np.finfo(np.float).eps # 防止分母出现0
clean_speech_phase = np.angle(clean_speech)
noise_speech_phase = np.angle(noise_speech)
mask = np.abs(clean_speech) / np.abs(noise_speech) * np.cos(clean_speech_phase - noise_speech_phase)
# Truncated Phase Sensitive Masking
# Theta = np.clip(np.cos(clean_speech_phase-noise_speech_phase), a_min=0., a_max=1.)
# mask = np.divide(np.abs(clean_speech), _eps np.abs(noise_speech)) * Theta
return mask

复数理想浮值掩蔽(Complex Ideal Ratio Mask,cIRM)

参考文献:2015_ Complex ratio masking for monaural speech separation

原理 :在复数域的理想浮值掩膜,同时增强幅度谱和相位谱

条件:⎧⎪ ⎪ ⎪ ⎪⎨⎪ ⎪ ⎪ ⎪⎩Y=Yr iYiM=Mr iMiS=Sr iSiSt,f=Mt,f∗Yt,f条件:{Y=Yr iYiM=Mr iMiS=Sr iSiSt,f=Mt,f∗Yt,f==>Sr iSi=(Mr iMi)∗(Yr iYi)=(MrYr−MiYi) i(MrYi MiYr)Sr iSi=(Mr iMi)∗(Yr iYi)=(MrYr−MiYi) i(MrYi MiYr),

那么:{Sr=MrYr−MiYiSi=MrYi MiYr{Sr=MrYr−MiYiSi=MrYi MiYr解方程得:⎧⎪⎨⎪⎩Mr=YrSr YiSiY2r Y2iMi=YrSi−YiSrY2r Y2i{Mr=YrSr YiSiYr2 Yi2Mi=YrSi−YiSrYr2 Yi2

最终:McIRM=Mr iMi=YrSr YiSiY2r Y2i iYrSi−YiSrY2r Y2iMcIRM=Mr iMi=YrSr YiSiYr2 Yi2 iYrSi−YiSrYr2 Yi2

式中,YY是带噪语音,SS是纯净语音。

优点 :cIRM能够同时增强嘈杂语音的幅度和相位响应,cIRM是加性噪声假设下的最优掩蔽,可以从带噪语音中完美重构纯净语音信号

def cIRM(clean_speech, noise_speech):
"""使用复理想比率掩码将语音从源信号的短时傅里叶变换和混合源信号的短时傅里叶变换中分离出来
:param clean_speech:纯净语音
:param noise_speech:带噪语音
:return:
"""
cIRM_r = (np.real(noise_speech) * np.real(clean_speech) np.imag(noise_speech) * np.imag(clean_speech)) / \
(np.real(noise_speech) ** 2 np.imag(noise_speech) ** 2)

cIRM_i = (np.real(noise_speech) * np.imag(clean_speech) - np.imag(noise_speech) * np.real(clean_speech)) / \
(np.real(noise_speech) ** 2 np.imag(noise_speech) ** 2)

mask = cIRM_r cIRM_i * 1j
return mask

总结

语音增强中的大部分掩蔽类方法,都可以看成在 特定的假设条件下cIRM 的近似 。如果将 cIRM 在直角坐标系下分解,cIRM 在实数轴上的投影就是 PSM 。如果再将 cIRM在极坐标系下分解,cIRM 的模值就是 IAM 。而 IRM 又是 IAM 在噪声语音不相关假设下的简化形式, IBM 则可以认为是 IRM 的二值版本。

各种理想掩蔽的性能比较

度量IBMIRMIAMPSMcIRMPESQ2.473.333.453.714.49STOI0.910.940.970.971

从上表中我们可以看到 cIRM 可以实现对纯净语音几乎无损地重构,其他掩蔽由于进行了某些特定的假设,所以都会在一定程度上造成性能损失。虽然 cIRM 是最优掩蔽,但是使用其他简化的掩蔽方法可以降低预测的难度。这也是早期的语音增强研究选择使用 IBM 或者是 IRM 等简单掩蔽目标的原因。在模型容量有限的情况下,cIRM 经常并不是最好的选择,选择和模型建模能力匹配的目标才能获得最优的增强性能。

题外话

但是,这里存在一个问题,我们无法从语谱图中还原语音信号。为了解决这一问题,我们首先还原所有的频率分量,即对二值掩码做个镜像后拼接。假设我们计算语谱图时使用的是512点SFTF,我们一般去前257点进行分析和处理,在这里我们将前257点的后255做镜像,然后拼接在一起得到512点频率分量,如下图所示。

然后根据这个还原语音信号。这里指的一提的是,在进行STFT后的相位信息要保存,用于还原语音信号。

基于掩蔽的语音增强和基于映射的语音增强模型训练和增强过程类似,这里只提几个重要的地方,其余地方参考上面内容。

Label :数据的label为根据信噪比计算的IBM或者IRM,这里只需要一帧就够了 损失函数 :IBM的损失函数可以用交叉熵,IRM的损失函数还是用均方差 最后一层的激活函数 :IBM只有0和1两个值,IRM范围为[0,1],因此采用sigmoid激活函数就可以了 重构波形 :首先用噪声幅度谱与计算的Mask值对应位置相乘,代码如下,然后根据相位信息重构语音波形。

enhance_magnitude = np.multiply(magnitude, mask)

Demo效果以及代码

首先看下实验效果,首先是基于映射语音增强的结果:

基于IBM语音增强的结果:

基于IRM语音增强的结果:

训练代码:

"""
@FileName: IBM.py
@Description: Implement IBM
@Author: Ryuk
@CreateDate: 2020/05/08
@LastEditTime: 2020/05/08
@LastEditors: Please set LastEditors
@Version: v0.1
"""

import numpy as np
import librosa
from sklearn.preprocessing import StandardScaler
from keras.layers import *
from keras.models import Sequential


def generateDataset():
mix, sr = librosa.load("./mix.wav", sr=8000)
clean,sr = librosa.load("./clean.wav", sr=8000)

win_length = 256
hop_length = 128
nfft = 512

mix_spectrum = librosa.stft(mix, win_length=win_length, hop_length=hop_length, n_fft=nfft)
clean_spectrum = librosa.stft(clean, win_length=win_length, hop_length=hop_length, n_fft=nfft)

mix_mag = np.abs(mix_spectrum).T
clean_mag = np.abs(clean_spectrum).T


frame_num = mix_mag.shape[0] - 4
feature = np.zeros([frame_num, 257*5])
k = 0
for i in range(frame_num - 4):
frame = mix_mag[k:k 5]
feature[i] = np.reshape(frame, 257*5)
k = 1

snr = np.divide(clean_mag, mix_mag)
mask = np.around(snr, 0)
mask[np.isnan(mask)] = 1
mask[mask > 1] = 1

label = mask[2:-2]

ss = StandardScaler()
feature = ss.fit_transform(feature)
return feature, label


def getModel():
model = Sequential()
model.add(Dense(2048, input_dim=1285))
model.add(BatchNormalization())

model.add(LeakyReLU(alpha=0.1))
model.add(Dropout(0.1))

model.add(Dense(2048))
model.add(BatchNormalization())
model.add(LeakyReLU(alpha=0.1))
model.add(Dropout(0.1))

model.add(Dense(2048))
model.add(BatchNormalization())
model.add(LeakyReLU(alpha=0.1))
model.add(Dropout(0.1))

model.add(Dense(257))
model.add(BatchNormalization())
model.add(Activation('sigmoid'))
return model

def train(feature, label, model):
model.compile(optimizer='adam',
loss='mse',
metrics=['mse'])
model.fit(feature, label, batch_size=128, epochs=20, validation_split=0.1)
model.save("./model.h5")

def main():
feature, label = generateDataset()
model = getModel()
train(feature, label, model)


if __name__ == "__main__":
main()

增强代码:

"""
@FileName: Inference.py
@Description: Implement Inference
@Author: Ryuk
@CreateDate: 2020/05/08
@LastEditTime: 2020/05/08
@LastEditors: Please set LastEditors
@Version: v0.1
"""

import librosa
import numpy as np
from basic_functions import *
import matplotlib.pyplot as plt
from sklearn.preprocessing import StandardScaler
from keras.models import load_model

def show(data, s):
plt.figure(1)
ax1 = plt.subplot(2, 1, 1)
ax2 = plt.subplot(2, 1, 2)
plt.sca(ax1)
plt.plot(data)
plt.sca(ax2)
plt.plot(s)
plt.show()


model = load_model("./model.h5")
data, fs = librosa.load("./test.wav", sr=8000)

win_length = 256
hop_length = 128
nfft = 512

spectrum = librosa.stft(data, win_length=win_length, hop_length=hop_length, n_fft=nfft)
magnitude = np.abs(spectrum).T
phase = np.angle(spectrum).T

frame_num = magnitude.shape[0] - 4
feature = np.zeros([frame_num, 257 * 5])
k = 0
for i in range(frame_num - 4):
frame = magnitude[k:k 5]
feature[i] = np.reshape(frame, 257 * 5)
k = 1

ss = StandardScaler()
feature = ss.fit_transform(feature)
mask = model.predict(feature)
mask[mask > 0.5] = 1
mask[mask <= 0.5] = 0

fig = plt.figure()
plt.imshow(mask, cmap='Greys', interpolation='none')
plt.show()
plt.close(fig)

magnitude = magnitude[2:-2]
en_magnitude = np.multiply(magnitude, mask)
phase = phase[2:-2]

en_spectrum = en_magnitude.T * np.exp(1.0j * phase.T)
frame = librosa.istft(en_spectrum, win_length=win_length, hop_length=hop_length)

show(data, frame)
librosa.output.write_wav("./output.wav",frame, sr=8000)

参考

【论文】2020_李劲东_基于深度学习的单通道语音增强研究

【博客文章】 DNN单通道语音增强(附Demo代码)

【博客文章】 基于Mask的语音分离

【github代码】 speech-segmentation-project/masks.py

【github代码】 ASP/MaskingMethods.py

【github代码】 DC-TesNet/time_domain_mask.py

【github代码】 ASC_baseline/compute_mask.py

本文代码请见: https://github.com/Ryuk17/SpeechAlgorithms

作者:凌逆战

博客地址(转载请指明出处): https://www.cnblogs.com/LXP-Never/p/14142108.html

,

halcon深度学习分几步(机器视觉halcon学习系列---XLD的介绍和使用)

定义

XLD是eXtended Line Description的缩写,中文你可以直译过来解释为 扩展线的描述,XLD可以来表达轮廓和多边形数据。XLD属于图像变量,轮廓是一系列的二维点组成,一系列点连接成线,这里的可以看到这些连接的线是从像素中穿过去的,我们叫这是亚像素精度(sub_pixel),在halcon中,XLD不仅包括点集,而且XLD里面保存了局部和全局的属性,典型的属性有点的幅度以及轮廓分割的回归参数

XLD轮廓

在halcon中,还可以对轮廓XLD进行一系列的处理,例如可以通过select_shape_xld选择特定的特征对象XLD,还可以segment_contour_xld来把轮廓分割,还可以把union_*_contours_xld一系列算子对轮廓进行合并等操作。

我们认识了XLD之后,我们可以使用XLD拿来干嘛呢? XLD可以用来做测量,XLD创建模板,XLD可以用来拟合直线等。

获取XLD

在获取XLD中,一种是交互式画XLD,draw_xld,这种方式在实际基本没有使用,意义不大。还有一种是通过read_contour_xld_dxf读取XLD,这是通过CAD画的轮廓图,或者通过write_contour_xld_dxf写入的轮廓,这里面可能在某些应用中会使用,前期通过CAD建模,读取到XLD后我们就可以拿来用作匹配的轮廓。

xld保存

dxf轮廓转换

还有一种方式是直接通过算法来获取XLD轮廓,在这里是基于亚像素的轮廓,对应着有彩色图像和灰度图像的获取。edge_color_sub_pix、edges_sub_pix,这两个算子我们会经常使用。

我们还可以通过gen_contour_*_xld系列算子来转换成XLD,只不过,在这里有些是亚像素精度,有些是像素精度。

当我们得到轮廓后,还需要对轮廓进行修饰,常用的使用select_shap_xld,主要的特征有四类,基本、形状、点、moments等特征。

select_shape_xld

有时候也需要对轮廓进行分割,通过segment_contours_xld来进行分割,获取特定轮廓的坐标点通过get_contour_xld算子获取,这个算子输出轮廓的坐标点集,我们可以使用这些点集来进行特定的应用,可以是拟合直线、拟合圆、判断最大最小值,这就是你的业务逻辑的事情了。

总结一下,XLD是halcon里面的一种数据格式,把点集封装了一下,点集连接成线,这些点集有一些自己的特性,halcon已经封装好了,XLD在应用中是广泛使用的一种工具,用来分割图像特征,学会使用XLD工具会给我们工作带来极大的便利。

,

深度学习英语教学(读CNN学英语感恩生活)

How to become more grateful, and why that will make you happier, healthier and more resilient

resilient [rɪˈzɪliənt]有弹性(或弹力)的;可迅速恢复的;有适应力的;能复原的

(CNN) – If you really think about it, so many of us should be in a perpetual state of gratitude.

think about it 思考;想一想;想想看 perpetual [pəˈpetʃuəl]永恒的;永久的;没完没了的;不间断的;持续的;长久的 gratitude n. 感激;感谢

Which of these do you have going for you right now? Family. Friends. Love. Health. Freedom from war and natural disaster. Imagination. Community. A roof over our heads. Common decency. Hope. Opportunity. Memories. Financial stability. Favorite places. Days off work. Good weather. The golden age of television. Books. Music. Ice cream. Weekends. A friendly exchange. Something good that happened today. Something bad that didn't happen today. A good cup of coffee.

have sth going for sb 具有某种有利条件或优势 freedom from 免于;没有 decency [ˈdiːsnsi]体面;端庄 days off work 休息天 exchange 交流;互动

You may not have everything you want (or even need) on my list or yours, but that probably still leaves buckets — nay, container ships — full of tangible and conceptual items for which to be grateful. Things can always be better, but they can always be worse. It often depends on how you look at that proverbial glass of water.

bucket 水桶 nay (强调刚提及之事)不仅如此;不 container ship 集装箱船 tangible [ˈtændʒəbl]有形的;实际的;真实的;可触摸的;可触知的;可感知的 conceptual 概念(上)的;观念(上)的 depend on 取决于 proverbial [prəˈvɜːrbiəl]谚语的;谚语表达的;如谚语所说的;众所周知;著名

To get in better touch with gratefulness — and get the health benefits of doing so — the trick is to find easy ways to count blessings more often than, say, over an annual turkey dinner. Keep your thankfulness boiling on the front burner of your mind, and you will increase your general appreciation of life.

get in touch with 接触 trick 诀窍;秘诀 blessings 上帝的恩宠;祝福;祝颂;赞同;许可;好事;有益之事 turkey dinner 感恩节火鸡大餐 on the front burner 处于首要地位 appreciation 欣赏;理解;体谅;同情;感激;感谢

Try to be more grateful for the small, mundane things that give you joy and meaning, as well as the big ones. Acknowledging just a handful each day will benefit you, and there are ways to make that a habit.

mundane [mʌnˈdeɪn]单调的;平凡的

Whatever way you start infusing your life with more moments of gratitude, in the short and long term, you will be grateful that you did.

infuse with 灌入,灌输,注入 in the short/long term 短期/长期来看

,

本文Hash:a0974117245989fb64777c5a6b4a606eb6dd149e

声明:此文由 Mike 分享发布,并不意味布布狗赞同其观点。文章内容仅供参考,此文如侵犯到您的合法权益,请联系我们。