Как повысить точность cmuSphinx?

Я хочу использовать pocketShpinx для преобразования речи в текст. Я установил sphinxbase и pocketSphinx. И скачать акустическую модель/языковую модель/словарь. Затем я тестирую пример кода следующим образом:

#include <pocketsphinx/pocketsphinx.h>
#include <stdio.h>
#include <stdlib.h>
#include "debug.h"

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

  config = cmd_ln_init(NULL, ps_args(), TRUE,
                       "-hmm", "/home/madper/speech/hub4opensrc.cd_continuous_8gau",
                       "-lm",  "/home/madper/speech/language_model.arpaformat.DMP",
                       "-dict", "/home/madper/speech/cmudict/cmudict/sphinxdict/cmudict_SPHINX_40",
                       NULL);
  if (config == NULL)
    {
      DBG (("cmd_ln_init() failed.\n"));
      exit(1);
    }
  if ((ps = ps_init (config)) == NULL) /* init decoder */
    {
      DBG (("ps_init() failed.\n"));
      exit(1 );
    }
  if ((fh = fopen("test.raw", "rb")) == NULL) /* open raw file */
    {
      DBG (("fopen() failed.\n"));
      exit (1);
    }
  if ((rv = ps_decode_raw (ps, fh, "test", -1)) < 0 )
    {
      DBG (("ps_decode_raw() error!\n"));
      exit (1);
    }
  if ((hyp = ps_get_hyp(ps, &score, &uttid)) == NULL)
    {
      DBG (("ps_get_hyp() failed!\n"));
      exit (1);
    }
  printf ("Recognized: %s\n", hyp); /* this is what you say */

  fclose(fh);
  ps_free(ps);
  return 0;
}

DBG — это просто макрос для печати сообщения об ошибке, если он определен DEBUG.


Затем я пишу код для записи с микрофона, используя alsa. Как следует:

#define ALSA_PCM_NEW_HW_PARAMS_API

#include <alsa/asoundlib.h>

int main() {
  long loops;
  int rc;
  int size;
  snd_pcm_t *handle;
  snd_pcm_hw_params_t *params;
  unsigned int val;
  int dir;
  snd_pcm_uframes_t frames;
  char *buffer;

  /* Open PCM device for recording (capture). */
  rc = snd_pcm_open(&handle, "default",
                    SND_PCM_STREAM_CAPTURE, 0);
  if (rc < 0) {
    fprintf(stderr,
            "unable to open pcm device: %s\n",
            snd_strerror(rc));
    exit(1);
  }

  /* Allocate a hardware parameters object. */
  snd_pcm_hw_params_alloca(&params);

  /* Fill it in with default values. */
  snd_pcm_hw_params_any(handle, params);

  /* Set the desired hardware parameters. */

  /* Interleaved mode */
  snd_pcm_hw_params_set_access(handle, params,
                      SND_PCM_ACCESS_RW_INTERLEAVED);

  /* Signed 16-bit little-endian format */
  snd_pcm_hw_params_set_format(handle, params,
                              SND_PCM_FORMAT_S16_LE);

  /* Two channels (stereo) */
  snd_pcm_hw_params_set_channels(handle, params, 1);

  /* 44100 bits/second sampling rate (CD quality) */
  val = 16000;
  snd_pcm_hw_params_set_rate_near(handle, params,
                                  &val, &dir);

  /* Set period size to 32 frames. */
  frames = 16;
  snd_pcm_hw_params_set_period_size_near(handle,
                              params, &frames, &dir);

  /* Write the parameters to the driver */
  rc = snd_pcm_hw_params(handle, params);
  if (rc < 0) {
    fprintf(stderr,
            "unable to set hw parameters: %s\n",
            snd_strerror(rc));
    exit(1);
  }

  /* Use a buffer large enough to hold one period */
  snd_pcm_hw_params_get_period_size(params,
                                      &frames, &dir);
  size = frames * 2; /* 2 bytes/sample, 2 channels */
  buffer = (char *) malloc(size);

  /* We want to loop for 5 seconds */
  snd_pcm_hw_params_get_period_time(params,
                                         &val, &dir);
  loops = 2000000 / val;

  while (loops > 0) {
    loops--;
    rc = snd_pcm_readi(handle, buffer, frames);
    if (rc == -EPIPE) {
      /* EPIPE means overrun */
      fprintf(stderr, "overrun occurred\n");
      snd_pcm_prepare(handle);
    } else if (rc < 0) {
      fprintf(stderr,
              "error from read: %s\n",
              snd_strerror(rc));
    } else if (rc != (int)frames) {
      fprintf(stderr, "short read, read %d frames\n", rc);
    }
    rc = write(1, buffer, size);
    if (rc != size)
      fprintf(stderr,
              "short write: wrote %d bytes\n", rc);
  }

  snd_pcm_drain(handle);
  snd_pcm_close(handle);
  free(buffer);

  return 0;
}

Итак, я записываю файл raw. Затем выполните проверку речи в этом файле. Но точность очень плохая. Так же, как hello или go home даст мне hotel или MHM MHM и так далее. Так что же не так с этим кодом? Я прочитал часто задаваемые вопросы. Должен ли я использовать адаптацию акустической модели для повышения точности?

PS. Меняю стерео на моно. И звук странный. Я не могу понять, что я сказал. Итак, что в этом плохого? Это необработанный файл test.raw.


person madper    schedule 23.03.2012    source источник


Ответы (1)


Если вы посмотрите на первые вопросы и ответы в http://cmusphinx.sourceforge.net/wiki/faq вы заметите, что библиотека предполагает монофонические данные.

Вы записываете в стерео.

person HonkyTonk    schedule 23.03.2012
comment
Я изменил его на моно данные. Но точность все равно очень плохая. - person madper; 24.03.2012
comment
Вы можете предоставить аудиофайл, который хотите распознать, чтобы получить более подробную справку. Обычно вам нужно написать лучшую грамматику или создать лучшую языковую модель, чтобы она соответствовала тексту, который вы собираетесь распознавать. - person Nikolay Shmyrev; 24.03.2012
comment
@NikolayShmyrev, я загружаю свой голосовой файл. - person madper; 24.03.2012
comment
Ваш звук распознается просто отлично. Мой результат - дом. Единственное, уровень записи слишком высок, его нужно понизить. - person Nikolay Shmyrev; 25.03.2012
comment
Я протестировал этот файл с POCKETSPHINX 0.7, и результат был clinton, когда я использовал -lm, MODELDIR /lm/en_US/hub4.5000.DMP, а когда я переключился на -lm, MODELDIR /lm/en_US/wsj0vp.5000.DMP, в результате стал президентом. Интересно, это следующий шаг в технологиях распознавания голоса, что-то вроде естественного интеллекта? - person southerton; 03.07.2012