2013-03-07 3 views
0

여러 다른 외부 입력 (키보드 누름, 동작 제스처, 음성)을 사용하여 유사한 출력을 생성 할 수있는 응용 프로그램을 작성 중입니다 (예 : 키보드는 "여행"이라는 단어를 크게 소리내어 말하는 것과 같은 일을합니다). 그렇기 때문에 입력 관리자가 서로에 대해 알 필요가 없습니다. 특히, Kinect의 내장 마이크 (음성 관리자는 모든 마이크에서 작동해야 함)를 사용하고 있어도 Kinect 관리자 (가능한 한 많이)에게 음성 관리자에 대해 알리고 싶지 않습니다. Microsoft.Speech와 반대되는 음성 관리자에서 System.Speech를 사용하고 있습니다.Kinect 음성 인식 및 골격 추적이 함께 작동하지 않습니다.

Kinect 동작 인식 모듈이 활성화 되 자마자 음성 모듈이 입력을받지 않는 문제가 있습니다. inverting the skeleton stream and audio stream과 같은 많은 것들을 시도해 보았습니다. 오디오 스트림을 다른 방식으로 캡처하는 등의 작업을했습니다. 문제를 좁혔습니다 : 모듈을 초기화하는 방법에 대한 내용은 내 응용 프로그램의 이벤트 처리 방법과 잘 일치하지 않습니다.

모션 캡처가 시작될 때까지 응용 프로그램이 훌륭하게 작동합니다. 나는 완전히 넥트 모듈을 제외하면, 이것은 내 주요 방법은 모습입니다 : 내 GUI가 외부 프로그램에 의해 처리되기 때문에 내가 Application.Run()을 사용하고

// Main.cs 
    public static void Main() 
    { 

     // Create input managers 
     KeyboardMouseManager keymanager = new KeyboardMouseManager(); 
     SpeechManager speechmanager = new SpeechManager(); 

     // Start listening for keyboard input 
     keymanager.start();  

     // Start listening for speech input 
     speechmanager.start() 

     try 
     { 
      Application.Run(); 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show(ex.StackTrace); 
     } 

    } 

. 이 C# 응용 프로그램의 유일한 작업은 입력 이벤트를 받고 해당 입력을 기반으로 외부 스크립트를 실행하는 것입니다.

키보드 및 스피치 모듈 모두 이벤트를 산발적으로 수신합니다. 반면 Kinect는 지속적으로 이벤트를 생성합니다. 제스처가 자주 발생하지 않으면 폴링 루프가 각 설문 사이의 대기 시간으로 응답 할 수 있습니다. 그러나, 저는 Kinect를 사용하여 마우스 움직임을 제어하고 있습니다 ... 나는 뼈대 이벤트 캡처 사이에 기다릴 여유가 없습니다. 마우스가 매우 지체되기 때문입니다. 내 해골 캡처 루프가 가능한 한 일정해야합니다. Kinect 관리자가 동일한 스레드 (또는 메시지 펌프)에있을 수 없기 때문에 큰 문제가있었습니다. 차이점이 조금 어둡기 때문에 여기에 문제가 있다고 생각합니다. 이해하는 방식으로 동일한 스레드에 있으면 키보드 또는 음성 이벤트가 일관되게 통과되지 않습니다. 대신, 내 Kinect 관리자가 System.Windows.Forms에서 상속 받도록 솔루션을 해킹하여 Application.Run()과 작동하도록했습니다. 이제 내 주요 방법은 다음과 같습니다 : 어떤 이유

// Main.cs 
    public static void Main() 
    { 

     // Create input managers 
     KeyboardMouseManager keymanager = new KeyboardMouseManager(); 
     KinectManager kinectManager = new KinectManager(); 
     SpeechManager speechmanager = new SpeechManager(); 

     // Start listening for keyboard input 
     keymanager.start(); 

     // Attempt to launch the kinect sensor 
     bool kinectLoaded = kinectManager.start(); 


     // Use the default microphone (if applicable) if kinect isn't hooked up 
     // Use the kinect microphone array if the kinect is working 
     if (kinectLoaded) 
     { 
      speechmanager.start(kinectManager); 
     } 
     else 
     { 
      speechmanager.start(); 
     } 


     try 
     { 
      // THIS IS THE PLACE I THINK I'M DOING SOMETHING WRONG 
      Application.Run(kinectManager); 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show(ex.StackTrace); 
     } 

는 키 넥트 마이크는 이러한 관찰이 잘못되었거나 경우가있다 (즉시 키 넥트 센서가 시작되면 그 "기본 다움"을 잃는다 해결 방법, 알려주세요). 그 때문에, 나는이처럼 보이는 음성 관리자에 특별한 start() 방법하도록 요구했다 : 참고로

// SpeechManager.cs 

    /** For use with the Kinect Microphone **/ 
    public void start(KinectManager kinect) 
    { 
     // Get the speech recognizer information 
     RecognizerInfo recogInfo = SpeechRecognitionEngine.InstalledRecognizers().FirstOrDefault(); 

     if (null == recogInfo) 
     { 
      Console.WriteLine("Error: No recognizer information found on Kinect"); 
      return; 
     } 

     SpeechRecognitionEngine recognizer = new SpeechRecognitionEngine(recogInfo.Id); 

     // Loads all of the grammars into the recognizer engine 
     loadSpeechBindings(recognizer); 

     // Set speech event handler 
     recognizer.SpeechRecognized += speechRecognized; 

     using (var s = kinect.getAudioSource().Start()) 
     { 
      // Set the input to the Kinect audio stream 
      recognizer.SetInputToAudioStream(s, new SpeechAudioFormatInfo(EncodingFormat.Pcm, 16000, 16, 1, 32000, 2, null)); 

      // Recognize asycronous speech events 
      recognizer.RecognizeAsync(RecognizeMode.Multiple); 
     } 
    } 

를, 키 넥트 관리자의 start() 방법은 다음과 같습니다

// KinectManager.cs 
    public bool start() 
    { 
     // Code from Microsoft Sample 
     kinect = (from sensorToCheck in KinectSensor.KinectSensors where sensorToCheck.Status == KinectStatus.Connected select sensorToCheck).FirstOrDefault(); 

     // Fail elegantly if no kinect is detected 
     if (kinect == null) 
     { 
      connected = false; 
      Console.WriteLine("Couldn't find a Kinect"); 
      return false; 
     } 

     // Start listening 
     kinect.Start(); 

     // Enable listening for all skeletons 
     kinect.SkeletonStream.Enable(); 

     // Obtain the KinectAudioSource to do audio capture 
     source = kinect.AudioSource; 
     source.EchoCancellationMode = EchoCancellationMode.None; // No AEC for this sample 
     source.AutomaticGainControlEnabled = false; // Important to turn this off for speech recognition 

     kinect.AllFramesReady += new EventHandler<AllFramesReadyEventArgs>(allFramesReady); 

     connected = true; 
     return true; 
    } 

모션 캡처를 사용하지 않도록 설정하면 (내 main() 모양이 첫 번째 코드 세그먼트와 비슷 함) 음성 인식이 정상적으로 작동합니다. 모션 캡처를 활성화하면 모션이 훌륭하게 작동하지만 인식이 인식되지 않습니다. 두 경우 모두 키보드 이벤트가 항상 작동합니다. 오류가 없으며 추적을 통해 음성 관리자의 모든 데이터가 올바르게 초기화되었음을 알게되었습니다 ... 은 음성 인식 이벤트가 사라지는 것처럼처럼 보입니다. 입력 모듈이 독립적으로 작동 할 수 있도록이 코드를 어떻게 재구성 할 수 있습니까? 스레딩을 사용합니까 아니면 Application.Run() 만 다른 방식으로 사용합니까?

+0

어떤 SDK와 어떤 Kinect를 사용하고 있습니까? XBox 또는 Windows? 또한 어떤 버전의 Speech API를 사용하고 있습니까? –

+0

SDK 버전 1을 사용하고 있으며 Windows에서 kinect를 사용하고 있습니다. System.Speech 버전 4를 사용하고 있습니다. –

답변

1

Microsoft Kinect SDK에는 오디오 프로세서를 시작한 후 골격을 추적하기 시작하면 오디오가 처리되지 않는 것 중 하나 인 known issues이 있습니다. 알려진 이슈에서 :

Audio is not processed if skeleton stream is enabled after starting audio capture 

Due to a bug, enabling or disabling the SkeletonStream will stop the AudioSource 
stream returned by the Kinect sensor. The following sequence of instructions will 
stop the audio stream: 
    kinectSensor.Start(); 
    kinectSensor.AudioSource.Start(); // --> this will create an audio stream 
    kinectSensor.SkeletonStream.Enable(); // --> this will stop the audio stream as an undesired side effect 

The workaround is to invert the order of the calls or to restart the AudioSource after changing SkeletonStream status. 
    Workaround #1 (start audio after skeleton): 
    kinectSensor.Start(); 
    kinectSensor.SkeletonStream.Enable(); 
    kinectSensor.AudioSource.Start(); 

    Workaround #2 (restart audio after skeleton): 
    kinectSensor.Start(); 
    kinectSensor.AudioSource.Start(); // --> this will create an audio stream 
    kinectSensor.SkeletonStream.Enable(); // --> this will stop the audio stream as an undesired side effect 
    kinectSensor.AudioSource.Start(); // --> this will create another audio stream 

Resetting the SkeletonStream engine status is an expensive call. It should be made at application startup only, unless the app has specific needs that require turning Skeleton on and off. 

또한 SDK의 "버전 1"을 사용한다고 말하면 "버전 1.6"을 의미합니다. 1.5 또는 1.6 이외의 것을 사용하는 경우, 1.5에서 변경된 많은 사항으로 인해 자신이 아플뿐입니다.

+0

답변 해 주셔서 감사합니다! 나는 나의 질문의 꼭대기에 언급했는데, 나는 이미 이것을 시도했지만 실제로 아무것도 변경하지 않았다. 내 SDK 버전을 더 살펴본 후에 내가 구식이라고 생각하는 것이 맞다고 생각합니다. 내가 그것을 업데이트하고 무슨 일이 일어나는지 보도록하겠습니다. –

+0

죄송합니다, 오디오/스켈레톤 초기화 명령에 대한 언급을 놓쳤습니다 ... 긴 게시물이었습니다. :) –

관련 문제