티스토리 뷰

Kinect

[Kinect 프로젝트] Kinect를 활용한 한글 인식

생각많은 소심남 2013. 1. 1. 21:25

간만에 키넥트 관련 내용을 다뤄봅니다. 

몇주전에 방명록을 통해서 키넥트를 가지고 한글도 인식할 수 있는지를 문의하시는 분이 계셨습니다. 이론상으로는 가능한데 저도 막상 테스트를 해보지 않아서 자세히 알려드리기 힘들었는데 다행히도 영어 인식 구조와 거의 동일하다는 것을 직접해보고 알았습니다. 그래서 간단하게 한글을 통해서 키넥트의 tilt 모터를 제어하는 예제를 소개하고자 합니다.

우선 내용의 원 출처는 다음과 같습니다.

http://kaki104.tistory.com/entry/SpeechRecognition-in-Kinect-for-Windows


주 원리는 다음과 같습니다. 

사실 키넥트에서 공식적으로 지원하는 언어는 기본으로 제공되는 영어 엔진을 포함해서 11개의 언어입니다. 그런데 그중에는 한국어에 대한 지원이 포함되어 있지 않습니다. 그 대신 MS에서 제공하는 Speech SDK에는 한국어가 들어가 있습니다. 즉, 키넥트 SDK가 제공하는 소스가 아닌 Speech SDK를 이용하자는 겁니다. 그래서 사용하는 Speech Engine도 키넥트에서 제공하는 엔진은 이름안에 Kinect가 포함되어 있지만 Speech SDK에서 뽑아온 엔진에는 TELE라는 단어가 들어가 있습니다.


자 우선  설치해줘야 하는게 Speech SDK인데 이건 Kinect Development Toolkit에 포함되어 있습니다.




WPF Application으로 빈 프로젝트를 하나 생성해줍니다. 그리고 다음의 Reference를 추가시켜줍니다.




그리고 당연히 코드상에서도 네임스페이스로 추가시켜줘야 하겠지요. 참고로 음성관련 내용을 사용하기 위해서는 Thread를 사용해야 합니다. 그래야 이 어플리케이션을 돌리면서 다른 기능을 같이 수행할 수 있게 됩니다.

 


이렇게 설정을 하고 나서 화면에 아이템들을 배치해봅시다. 우선은 무슨 말이 인식되었는지를 나타낼 Textblock이 들어가야 할것이고요. tilt 기능을 테스트 하려면 ColorStream을 뽑아주는 게 좋겠지요. 이것을 표현할 Image 컨트롤을 다음과 같이 삽입해줍니다.


그러면 TextBlock에 출력시킬 내용은 TextBlock1.Text로 불러오면 될것이고 ColorStream의 결과물은 colorImage로 집어넣어주면 되겠지요. 일단 XAML 상에 컨트롤 배치는 끝났습니다. 이제는 모두 코드 상에서 처리해주면 될 겁니다.

우선은 몇가지 변수에 대한 선언을 해줍니다. 늘 그러하듯 키넥트 변수도 선언해주고 앞에서 언급했던 Thread에 대한 부분도 선언해줘야 합니다. 

 


필요한 내용은 Thread 자체와 그 Thread의 시작점, 그리고 사용할 엔진에 대한 선언입니다. 그런데 한국어를 인식하는 엔진이 sre에 담기는게 아니라 따로 RecognizerInfo라는 자료형이 있습니다. 이걸 통해서 한국어 엔진의 id를 찾고 그걸 인식시키는 과정이 필요한데 그럴려면 우선 한국어 엔진을 찾아봐야 하겠지요. 그래서 XAML상에 올려놓은 TextBlock 상에 한국어 인식 엔진이 있는지 없는지를 표현해봅시다.



이걸 그대로 해석하자면 한국을 의미하는 기호인 KR이 id안에 포함되어 있으면 그걸 표현하라는 겁니다. 이 상태로 실행을 시켜봅시다. 아래와 같이 표현되면 지금 컴퓨터 상에는 한국어 인식 엔진이 설치되어 있는 겁니다.



만약 이 부분이 출력되지 않는다면 앞에서 소개한 Speech SDK를 다시 설치하시기 바랍니다. 지금 이 과정은 한국어 인식엔진이 있는지를 확인하는 과정이었고, 있는지를 확인했으니까 그 정보를 RecognizerInfo에 집어넣어줍니다. 그리고 나서 이 ri의 ID를 앞에서 선언한 sre에 담아줌으로써 엔진 인식 과정은 끝나게 됩니다.




이제 엔진을 인식시켰으니까 한글 문법사전을 만들어줘야 합니다. 사람과는 다르게 컴퓨터는 자각적으로 단어를 인식하지 못합니다. 사전에 정의해준 단언만 들어왔을 경우에 그와 유사한 결과값을 표현할 뿐이지, 그 외의 단어에 대해서는 false 결과값만 출력합니다. 

저는 앞에서 언급한 것처럼 tilt 모터를 제어할 거니까 다음과 같이 사용할 단어를 선정해줬습니다.



이렇게 하면 이 어플리케이션은 위에서 선언한 세 문장에 대해서만 인식하고 나머지 문장은 인식하지 못합니다.물론 이런 내용을 따로 클래스화시키면 대화형 로봇을 만들 수 있겠지요. 이 포스트의 목적은 한글 인식이 되는지를 확인하는 것이므로 그 부분까지는 가지 않습니다. 이렇게 사전을 만들었으니까 이걸 하나의 문법으로 정의해줘야 합니다. 물론 이게 어떤 문화권의 언어다 라는 걸 Culture라는 속성을 통해서 정의해줄 수 있습니다. 


하나의 문법이 형성되고 이걸 앞에서 선언한 엔진에 집어넣어주면 이제 끝입니다. 그러고 나서 인식 이벤트를 생성하면 되겠습니다.



여기서 한가지 알아둬야 할 내용이 있습니다. 잘 보시면 지금 이벤트를 SpeechRecognized로 표현했지만 이 것 말고도 SpeechHypothesized 라는 이벤트가 또 있습니다. 이 두 이벤트는 둘다 SpeechRecognizedEventArgs를 통과하는데 기본적은 음식인식의 단계는 인식-추정의 과정을 거칩니다. 즉, 키넥트로 음성 정보가 들어왔을 때 그걸 바로 표현할 수 있는 값이 Recognized 인 것이고, 그 값을 토대로 추정한 결과값이 Hypothesized에서 나타나게 됩니다. 물론 지금 상에서는 사실 별 차이가 없겠지만 음성정보의 정확성을 활용한 앱을 기획중이라면 이 부분을 잘 고려하시고 맞는 이벤트 핸들러를 사용하시기 바랍니다. 조금 더 찾아보고 싶으신 분은 다음 문서를 참고하시기 바랍니다.


Speech_Walkthrough.docx


물론 Beta SDK 기반이긴 한데 기본적인 사용법은 지금도 똑같습니다.


일단 이벤트 채우는 것은 좀있다가 하고 이렇게 엔진 설정을 마쳤으니까 키넥트를 활성화시켜야 합니다. 유의할 사항은 키넥트에서 음성관련 정보를 다룰 때에는 반드시 키넥트 자체가 실행된 후에 AudioSource가 켜져야 한다는 겁니다. 지금 무슨 말인지 모르겠다고 하시는 분은 일단 기본적인 키넥트 기능부터 활성화 시키십시요. 저는 앞에서 언급한 것처럼 ColorStream을 표현할 겁니다.



먼저 이렇게 기능을 활성화 시켜주고 colorFrameReady에 대한 이벤트를 작성합니다. 이부분은 다른 포스트에서도 설명을 많이 했으므로 자세한 설명을 생략하도록 하겠습니다.


이제 이러고 난 후에 앞에서 생성한 Thread 상에 음성관련 기능을 올리라는 겁니다. 즉 이렇게 표현이 될 겁니다.



여기서 sensorInit이라는 건 임의로 만든 음성 기능 활성 메서드입니다. 당연히 새로 메서드를 만들었으니까 밑에다가 정의를 해줘야 합니다.


이게 바로 제가 말하고자 한 바입니다. 당연히 지금 이 sensorInit이라는 메서드는 앞에서 sensor.Start()이 된 후에 실행됩니다. 그 후에 Kinect에서 받아온 AudioSource를 Start하는 과정이 들어가야 정상적으로 오디오 입력을 받을 수 있다는 겁니다. Kinect SDK에 알려진 버그로 이렇게 구성하게 되었습니다.(만약 사용하고자 하는 키넥트 기능중에 Skeletal Tracking이 있을 경우에는 이 순서가 반드시 지켜져야 합니다. 자세한 내용은 다음 페이지 : http://msdn.microsoft.com/en-us/library/jj663798.aspx 를 참고하시기 바랍니다.)


아까 만들어둔 SpeechRecognized 이벤트에 다음과 같이 넣어주면 음성 인식이 되는지 테스트 해볼 수 있습니다.



결과는 다음과 같습니다.


한글로 정확히 인식이 됩니다. 그런데 이렇게만 하면 원래 목적인 tilt 모터 제어가 안될 겁니다. 이제 문구에 따른 조건문을 그 이벤트 안에 집어넣어주면 되겠지요. 저는 다음과 같이 구성했습니다.



이렇게 하면 어떻게 되는지 한번 동영상으로 보겠습니다.



이게 대역폭 때문에 음성이 조금 이상하게 변조되는데 그와는 관계없이 음성이 정상적으로 인식되는 것을 보실 수 있을겁니다. 이와 같은 방식으로 다양한 언어에도 적용시킬 수가 있습니다.


다시 말씀드리지만 이 SpeechEngine을 통한 인식은 사전에 정의된 문법이 있어야 하며, 이 부분은 제가 한 것처럼 사용자가 직접 지정할 수 있는 부분입니다. 저는 그 중에서도 키넥트이 tilt 제어를 적용시켜 본 것이고요. 그냥 간단한 샘플인 거지요. 아마 여러분들은 더 나은 프로그램을 개발할 수 있을겁니다. 2013년 첫글을 이 걸로 작성하게 되었네요 :)

댓글