Информация о спектральной идентификации голоса от Alibaba Cloud Security: [Познай секреты идентификации — спектральная идентификация голоса](https://jaq. alibaba. com/community/art/show? spm=a313e. 7916648. 0. 0. WwucQ3&articleid=661)
govpr — это реализация на Go языка программирования для системы идентификации говорящего на основе GMM-UBM (Гауссовских смесей моделей и универсальной базовой модели). Может использоваться для верификации голоса и идентификации личности.
В настоящее время поддерживается только китайский язык для чисел, а формат аудио — wav (битрейт 16000, 16 бит, моно).
go get -v -u github.com/liuxp0827/govpr
cd $GOPATH/src/github.com/liuxp0827/govpr/example
go run main.go
Вот простой пример. Для просмотра более подробных примеров перейдите к примеру.
В примере используются аудиофайлы, содержащие только цифры (8-значные числа). После верификации голоса получается оценка, которую можно использовать для сравнения с пороговым значением для определения, является ли голос зарегистрированным.
В примере предустановлен порог 1.0. Если оценка верификации голоса >= 1.0, голос считается принадлежащим зарегистрированному пользователю. Если оценка < 1.0, голос не принадлежит зарегистрированному пользователю.
(Примечание: значение порога 1.0 не является оптимальным. Это просто пример. Также стоит отметить, что оценки для женских голосов обычно ниже, поэтому теоретически для разных полов следует использовать разные пороговые значения. Однако функция определения пола по голосу в govpr пока не реализована, но будет добавлена в будущем.)
В примере используется пять различных аудиофайлов для обучения и верификации, но на самом деле govpr лучше всего работает с аудио, содержащими одинаковые тексты. Использование пяти аудиофайлов с одинаковым содержанием для обучения и верификации приведет к лучшим результатам.
package main
import (
"github.com/liuxp0827/govpr"
"github.com/liuxp0827/govpr/log"
"github.com/liuxp0827/govpr/waveIO"
"io/ioutil"
)
type engine struct {
vprEngine *govpr.VPREngine
}
func NewEngine(sampleRate, delSilRange int, ubmFile, userModelFile string) (*engine, error) {
vprEngine, err := govpr.NewVPREngine(sampleRate, delSilRange, false, ubmFile, userModelFile)
if err != nil {
return nil, err
}
return &engine{vprEngine: vprEngine}, nil
}
func (this *engine) DestroyEngine() {
this.vprEngine = nil
}
func (this *engine) TrainSpeech(buffers [][]byte) error {
var err error
count := len(buffers)
for i := 0; i < count; i++ {
err = this.vprEngine.AddTrainBuffer(buffers[i])
if err != nil {
log.Error(err)
return err
}
}
defer this.vprEngine.ClearTrainBuffer()
defer this.vprEngine.ClearAllBuffer()
err = this.vprEngine.Train()
return err
}
func (this *engine) TrainModel() error {
err := this.vprEngine.TrainModel()
if err != nil {
log.Error(err)
return err
}
return nil
}
func (this *engine) RecSpeech(buffer []byte) (float64, error) {
err := this.vprEngine.AddVerifyBuffer(buffer)
defer this.vprEngine.ClearVerifyBuffer()
if err != nil {
log.Error(err)
return -1.0, err
}
err = this.vprEngine.VerifyModel()
if err != nil {
log.Error(err)
return -1.0, err
}
return this.vprEngine.GetScore(), nil
}
``````go
func main() {
log.SetLevel(log.LevelDebug)
vprEngine, err := NewEngine(16000, 50, "./ubm/ubm", "model/test.dat")
if err != nil {
log.Fatal(err)
}
trainlist := []string{
"wav/train/01_32468975.wav",
"wav/train/02_58769423.wav",
"wav/train/03_59682734.wav",
"wav/train/04_64958273.wav",
"wav/train/05_65432978.wav",
}
trainBuffer := make([][]byte, 0)
for _, file := range trainlist {
buf, err := loadWaveData(file)
if err != nil {
log.Error(err)
return
}
trainBuffer = append(trainBuffer, buf)
}
err = vprEngine.TrainSpeech(trainBuffer)
if err != nil {
log.Fatal(err)
}
var threshold float64 = 1.0
selfverifyBuffer, err := waveIO.WaveLoad("wav/verify/self_34986527.wav")
if err != nil {
log.Fatal(err)
}
self_score, err := vprEngine.RecSpeech(selfverifyBuffer)
if err != nil {
log.Fatal(err)
}
log.Infof("self score %f, pass? %v", self_score, self_score >= threshold)
otherverifyBuffer, err := waveIO.WaveLoad("wav/verify/other_38974652.wav")
if err != nil {
log.Fatal(err)
}
other_score, err := vprEngine.RecSpeech(otherverifyBuffer)
if err != nil {
log.Fatal(err)
}
log.Infof("other score %f, pass? %v", other_score, other_score >= threshold)
}
func loadWaveData(file string) ([]byte, error) {
data, err := ioutil.ReadFile(file)
if err != nil {
return nil, err
}
// удаляем информацию заголовка .wav 44 байта
data = data[44:]
return data, nil
}
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )