2017-11-27 42 views
1

이 예는 내 debian 9 시스템에서 음성 인식 라이브러리 pocketsphinx의 C 코드를 컴파일했습니다.pocketsphinx는 마이크를 통해 녹음 된 단어 (명령)를 효율적으로 인식 할 수 없습니다.

goforward.raw라는 파일에 샘플 오디오를 녹음했는데 goforward.raw에는 "go forward"명령이 있습니다.

pockesphinx_continuous 프로그램은 리눅스의 arecord 도구를 사용하여 헤드폰을 통해 녹음 된 단어를 효율적으로 인식하지 않으며 주어진 예제 코드에서도 인식하지 않습니다. 부분 인식 즉, "앞으로 이동"명령을 "앞으로 이동"으로 인식하지만 괜찮습니다. 그러나 다른 명령은 매우 잘못 인식됩니다. 당신이 인사하면, 그것은 당신이 누구인지 밝혀줍니다.

재미있는 점은 텍스트 투 스피치 도구 pico2wave를 사용하여 만든 오디오 파일은 pico2wave 도구를 통해 만든 wav 파일에서 단어를 추출 할 때 80 % 정확도와 같이 매우 효율적으로 인식된다는 것입니다. 내가해야합니까, 그것은 명령과 함께 작동하도록 무엇

/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*- */ 
/* ==================================================================== 
* Copyright (c) 1999-2010 Carnegie Mellon University. All rights 
* reserved. 
* 
* Redistribution and use in source and binary forms, with or without 
* modification, are permitted provided that the following conditions 
* are met: 
* 
* 1. Redistributions of source code must retain the above copyright 
* notice, this list of conditions and the following disclaimer. 
* 
* 2. Redistributions in binary form must reproduce the above copyright 
* notice, this list of conditions and the following disclaimer in 
* the documentation and/or other materials provided with the 
* distribution. 
* 
* This work was supported in part by funding from the Defense Advanced 
* Research Projects Agency and the National Science Foundation of the 
* United States of America, and the CMU Sphinx Speech Consortium. 
* 
* THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND 
* ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY 
* NOR ITS EMPLOYEES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
* 
* ==================================================================== 
* 
*/ 
/* 
* continuous.c - Simple pocketsphinx command-line application to test 
*    both continuous listening/silence filtering from microphone 
*    and continuous file transcription. 
*/ 

/* 
* This is a simple example of pocketsphinx application that uses continuous listening 
* with silence filtering to automatically segment a continuous stream of audio input 
* into utterances that are then decoded. 
* 
* Remarks: 
* - Each utterance is ended when a silence segment of at least 1 sec is recognized. 
* - Single-threaded implementation for portability. 
* - Uses audio library; can be replaced with an equivalent custom library. 
*/ 

#include <stdio.h> 
#include <string.h> 
#include <assert.h> 

#if !defined(_WIN32_WCE) 
#include <signal.h> 
#include <setjmp.h> 
#endif 
#if defined(WIN32) && !defined(GNUWINCE) 
#include <time.h> 
#else 
#include <sys/types.h> 
#include <sys/time.h> 
#endif 

#include <sphinxbase/err.h> 
#include <sphinxbase/ad.h> 

#include "pocketsphinx.h" 

static const arg_t cont_args_def[] = { 
    POCKETSPHINX_OPTIONS, 
    /* Argument file. */ 
    {"-argfile", 
    ARG_STRING, 
    NULL, 
    "Argument file giving extra arguments."}, 
    {"-adcdev", 
    ARG_STRING, 
    NULL, 
    "Name of audio device to use for input."}, 
    {"-infile", 
    ARG_STRING, 
    NULL, 
    "Audio file to transcribe."}, 
    {"-time", 
    ARG_BOOLEAN, 
    "no", 
    "Print word times in file transcription."}, 
    CMDLN_EMPTY_OPTION 
}; 

static ps_decoder_t *ps; 
static cmd_ln_t *config = cmd_ln_init(NULL, ps_args(), TRUE, 
            "-hmm", "/home/bsnayak/Trainguard_MT2/pocketsphinx/model9/hmm/trainguard/", 
            "-jsgf", "/home/bsnayak/Trainguard_MT2/pocketsphinx/model9/lm2/trainguardmt_adv_2.jsgf", 
            "-dict", "/home/bsnayak/Trainguard_MT2/pocketsphinx/model9/dict/trainguard.dic", 
            NULL); 




static FILE *rawfd; 

static void 
print_word_times(int32 start) 
{ 
    ps_seg_t *iter = ps_seg_iter(ps, NULL); 
    while (iter != NULL) { 
     int32 sf, ef, pprob; 
     float conf; 

     ps_seg_frames(iter, &sf, &ef); 
     pprob = ps_seg_prob(iter, NULL, NULL, NULL); 
     conf = logmath_exp(ps_get_logmath(ps), pprob); 
     printf("%s %f %f %f\n", ps_seg_word(iter), (sf + start)/100.0, 
       (ef + start)/100.0, conf); 
     iter = ps_seg_next(iter); 
    } 
} 

/* 
* Continuous recognition from a file 
*/ 
static void 
recognize_from_file() 
{ 

    int16 adbuf[4096]; 

    const char *hyp; 
    const char *uttid; 

    int32 k; 
    uint8 cur_vad_state, vad_state; 

    char waveheader[44]; 
    if ((rawfd = fopen(cmd_ln_str_r(config, "-infile"), "rb")) == NULL) { 
     E_FATAL_SYSTEM("Failed to open file '%s' for reading", 
         cmd_ln_str_r(config, "-infile")); 
    } 

    //skip wav header 
    fread(waveheader, 1, 44, rawfd); 
    cur_vad_state = 0; 
    ps_start_utt(ps, NULL); 
    while ((k = fread(adbuf, sizeof(int16), 4096, rawfd)) > 0) { 
     ps_process_raw(ps, adbuf, k, FALSE, FALSE); 
     vad_state = ps_get_vad_state(ps); 
     if (cur_vad_state && !vad_state) { 
      //speech->silence transition, 
      //time to end utterance and start new one 
      ps_end_utt(ps); 
      hyp = ps_get_hyp(ps, NULL, &uttid); 
      printf("%s: %s\n", uttid, hyp); 
      fflush(stdout); 
      ps_start_utt(ps, NULL); 
     } 
     cur_vad_state = vad_state; 
    } 
    ps_end_utt(ps); 
    hyp = ps_get_hyp(ps, NULL, &uttid); 
    printf("%s: %s\n", uttid, hyp); 
    fflush(stdout); 

    fclose(rawfd); 
} 

/* Sleep for specified msec */ 
static void 
sleep_msec(int32 ms) 
{ 
#if (defined(WIN32) && !defined(GNUWINCE)) || defined(_WIN32_WCE) 
    Sleep(ms); 
#else 
    /* ------------------- Unix ------------------ */ 
    struct timeval tmo; 

    tmo.tv_sec = 0; 
    tmo.tv_usec = ms * 1000; 

    select(0, NULL, NULL, NULL, &tmo); 
#endif 
} 

/* 
* Main utterance processing loop: 
*  for (;;) { 
*  start utterance and wait for speech to process 
*  decoding till end-of-utterance silence will be detected 
*  print utterance result; 
*  } 
*/ 
static void 
recognize_from_microphone() 
{ 
    ad_rec_t *ad; 
    int16 adbuf[4096]; 
    uint8 cur_vad_state, vad_state; 
    int32 k; 
    char const *hyp; 
    char const *uttid; 

    if ((ad = ad_open_dev(cmd_ln_str_r(config, "-adcdev"), 
          (int) cmd_ln_float32_r(config, 
               "-samprate"))) == NULL) 
     E_FATAL("Failed to open audio device\n"); 
    if (ad_start_rec(ad) < 0) 
     E_FATAL("Failed to start recording\n"); 

    if (ps_start_utt(ps, NULL) < 0) 
     E_FATAL("Failed to start utterance\n"); 
    cur_vad_state = 0; 
    /* Indicate listening for next utterance */ 
    printf("READY....\n"); 
    fflush(stdout); 
    fflush(stderr); 
    for (;;) { 
     if ((k = ad_read(ad, adbuf, 4096)) < 0) 
      E_FATAL("Failed to read audio\n"); 
     sleep_msec(100); 
     ps_process_raw(ps, adbuf, k, FALSE, FALSE); 
     vad_state = ps_get_vad_state(ps); 
     if (vad_state && !cur_vad_state) { 
      //silence -> speech transition, 
      // let user know that he is heard 
      printf("Listening...\n"); 
      fflush(stdout); 
     } 
     if (!vad_state && cur_vad_state) { 
      //speech -> silence transition, 
      //time to start new utterance 
      ps_end_utt(ps); 
      hyp = ps_get_hyp(ps, NULL, &uttid); 
      printf("%s: %s\n", uttid, hyp); 
      fflush(stdout); 
      //Exit if the first word spoken was GOODBYE 
      if (hyp && (strcmp(hyp, "good bye") == 0)) 
       break; 
      if (ps_start_utt(ps, NULL) < 0) 
       E_FATAL("Failed to start utterance\n"); 
      /* Indicate listening for next utterance */ 
      printf("READY....\n"); 
      fflush(stdout); 
      fflush(stderr); 
     } 
     cur_vad_state = vad_state; 
    } 
    ad_close(ad); 
} 

static jmp_buf jbuf; 
static void 
sighandler(int signo) 
{ 
    longjmp(jbuf, 1); 
} 

int 
main(int argc, char *argv[]) 
{ 
    char const *cfg; 
/* 
    config = cmd_ln_parse_r(NULL, cont_args_def, argc, argv, TRUE); 

    ///* Handle argument file as -argfile. */ 
    /* if (config && (cfg = cmd_ln_str_r(config, "-argfile")) != NULL) { 
     config = cmd_ln_parse_file_r(config, cont_args_def, cfg, FALSE); 
    } 
    if (config == NULL) 
     return 1; 

    ps_default_search_args(config); 
    ps = ps_init(config); 
    if (ps == NULL) 
     return 1; 
*/ 


if (config == NULL) 
return 1; 
ps = ps_init(config); 
if (ps == NULL) 
return 1; 

    E_INFO("%s COMPILED ON: %s, AT: %s\n\n", argv[0], __DATE__, __TIME__); 

    if (cmd_ln_str_r(config, "-infile") != NULL) { 
     recognize_from_file(); 
    } 
    else { 

     /* Make sure we exit cleanly (needed for profiling among other things) */ 
     /* Signals seem to be broken in arm-wince-pe. */ 
#if !defined(GNUWINCE) && !defined(_WIN32_WCE) && !defined(__SYMBIAN32__) 
     signal(SIGINT, &sighandler); 
#endif 

     if (setjmp(jbuf) == 0) { 
      recognize_from_microphone(); 
     } 
    } 

    ps_free(ps); 
    return 0; 
} 

/** Silvio Moioli: Windows CE/Mobile entry point added. */ 
#if defined(_WIN32_WCE) 
#pragma comment(linker,"/entry:mainWCRTStartup") 
#include <windows.h> 

//Windows Mobile has the Unicode main only 
int 
wmain(int32 argc, wchar_t * wargv[]) 
{ 
    char **argv; 
    size_t wlen; 
    size_t len; 
    int i; 

    argv = malloc(argc * sizeof(char *)); 
    for (i = 0; i < argc; i++) { 
     wlen = lstrlenW(wargv[i]); 
     len = wcstombs(NULL, wargv[i], wlen); 
     argv[i] = malloc(len + 1); 
     wcstombs(argv[i], wargv[i], wlen); 
    } 

    //assuming ASCII parameters 
    return main(argc, argv); 
} 
#endif 

: 여기

Here is the example pockesphinx code: 

#include <pocketsphinx.h> 


int 
main(int argc, char *argv[]) 
{ 
    ps_decoder_t *ps; 
    cmd_ln_t *config; 
    FILE *fh; 
    char const *hyp, *uttid; 
    int16 buf[512]; 
    int rv; 
    int32 score; 

    config = cmd_ln_init(NULL, ps_args(), TRUE, 
       "-hmm", MODELDIR "/en-us/en-us", 
       "-lm", MODELDIR "/en-us/en-us.lm.bin", 
       "-dict", MODELDIR "/en-us/cmudict-en-us.dict", 
       NULL); 
    if (config == NULL) { 
    fprintf(stderr, "Failed to create config object, see log for details\n"); 
    return -1; 
    } 

    ps = ps_init(config); 
    if (ps == NULL) { 
    fprintf(stderr, "Failed to create recognizer, see log for details\n"); 
    return -1; 
    } 

    fh = fopen("goforward.raw", "rb"); 
    if (fh == NULL) { 
    fprintf(stderr, "Unable to open input file goforward.raw\n"); 
    return -1; 
    } 

    rv = ps_start_utt(ps); 

    while (!feof(fh)) { 
    size_t nsamp; 
    nsamp = fread(buf, 2, 512, fh); 
    rv = ps_process_raw(ps, buf, nsamp, FALSE, FALSE); 
    } 

    rv = ps_end_utt(ps); 
    hyp = ps_get_hyp(ps, &score); 
    printf("Recognized: %s\n", hyp); 

    fclose(fh); 
    ps_free(ps); 
    cmd_ln_free_r(config); 

    return 0; 
} 

는 pocketsphinx에서 공식 패키지가 제공하는 pocketsphinx_continuous 도구 코드를 무엇입니까? 약간의 오인 또는 억양의 차이가 있어도 더 효율적으로 인식됩니다.

답변

1

이것은 동일한 문제가있는 사람들을위한 것입니다. 제가 개인적으로 질문하는 이유는 pocketsphinx 음성 인식 라이브러리에 대한 이야기가 거의 없기 때문에 배우거나 작업하기가 매우 어렵다는 것입니다. 커뮤니티 활동이 거의 없기 때문입니다. 공식 사이트는 이해하기 쉬운 안내서를 제공하지 않으며 공식 문서는 pocketsphinx 라이브러리에 대한 응용 프로그램을 작성하려는 개발자를위한 안내서보다 더 많은 연구가 필요합니다.

그래서 기본 언어 모델과 사전을 사용하여 음성 인식에 성공했지만 효율성과 정확성을 원하는 경우에는 자신의 언어 모델과 사전을 만들어야합니다. 아니면 새로운 악센트를 추가하고 싶을 수도 있습니다 기본 언어 모델로

단어 또는 문장을 텍스트 파일에 포함하는 샘플 언어 corspus를 작성하면됩니다. 그런 다음 Sphinx lmtool을 사용하여 언어 모델 (lm 파일)과 사전 (dic 파일)을 만듭니다.

다음으로 컴파일 과정에서 기본 언어 모델과 사전을 제공하는 대신이 새로운 lm 및 dic 파일 매개 변수를 제공해야합니다.

그게 바로 단어를 매우 빠르고 정확하게 인식 할 수 있습니다. 다음은 전체 프로세스에 대한 링크입니다. http://ghatage.com/tech/2012/12/13/Make-Pocketsphinx-recognize-new-words/