음성검출이란?
말 그대로 음성이 존재하는 부분을 찾는 것이다.
그럼, 실시간 음성 검출이란?
음성이 입력되는 순간부터 실시간에 음성을 잡아내고 음성이 종료되는 것까지 실시간에 처리하는 것을 의미한다. 연속음 인식에서는 음성 검출이 많이 중요하지는 않지만 고립단어나 연결단어 인식에서는 상당히 중요하다.
특히, DTW를 사용하는 화자 종속 인식기에서는 그 성능의 상당 부분을 이 음성 검출부가 좌우한다고 알려져 있다.
일반적으로 음성 검출은 영어로 endpoint detection 즉, 끝점 검출이라는 용어로 사용된다. 음성의 시작과 끝을 찾는다는 뜻이다. 그럼, 이게 왜 어려울까?
사람의 음성 중 유성음과 같이 에너지도 크고 주기적인 신호는 잡음과 잘 구분되지만 파열음이나 마찰음 같은 음성은 잡음과 비슷한 성질을 갖고 또한 에너지도 작아서 잘 구분하기 쉽지 않다. 특히, 주변 잡음이 레벨이 높으면 더더욱 큰 문제가 됩니다.
잘 알려진 끝점 검출 알고리듬으로 Rabiner와 Sambur의 알고리듬이 있는데 이는 영교차률(zer: zero-crossing rate)과 구간 에너지(frame energy)를 사용하는 방법으로 시간 영역에서 간단하고 빠르게 음성을 검출 할 수 있다. 그러나, 이 방법은 실시간 검출에는 부적합한 off-line 검출 알고리듬입니다. 따라서, 대부분의 경우 이를 실시간 검출에 맞게 변형해서 사용한다. 참고로 주파수 영역의 특징을 이용해서 검출하는 방법도 있고 이 방법이 잡음에 대해서 강인하다고 알려져 있지만 계산량도 많고 구현도 복잡해서 실제로는 잘 사용하지 않는다.
음성을 고정된 길이로 나누는 것을 보통 framing한다고 하고 그 고정된 길이 안의 샘플들을 하나의 frame 이라고 부른다. 또한, 일반적으로 resolution을 높이기 위해서 각 frame 의 일정 샘플들은 중첩(overlap)이 된다.
예를 들어서, 16KH로 Sampling된 음성의 경우 초당 16000 샘플이 얻어지는데 이 경우 한 frame은 보통 20~40ms 정도의 샘플이 된다. 즉 320-640 샘플 정도가 되는 것이다.
중첩은 frame 길이의 2/3, 1/2 정도 사용된다. Frame = 320 샘플, 중첩 1/2인 경우 160 샘플씩 중첩 시키면 된다. 이렇게 얻어진 각고, 에너지는 각 샘플의 제곱의 합으로 나타낸다.
또한, 한 frame의 샘플 중 일부는 다음 frame과 겹치니깐 그 부분은 미리 계산된 ZCR과 에너지를 사용하면 계산을 더 줄일 수 있다.
그런데, ZCR의 경우 잡음에 상당히 민감하다. 따라서, 많은 경우 에너지를 사용하게 된다. 그래서, 대부분의 인식기에서 마이크 볼륨을 되도록 크게해서 사용하길 권장한다. 또한, 대부분의 사운드 카드에는 DC BIAS가 존재한다. 즉, 아무런 음성이 없는 경우에도 신호의 레벨이 0이 아닌 어떤 값을 갖는다는 거다. 따라서, 그 값을 미리 계산해서 제거해 주는 것이 필요하다. 또한, 경우에 따라서는 HIGH-PASS나 LOW-PASS FILTER를 SW적으로 구현해 줘야 할 필요도 있다.
음성은 짧은 구간으로 나누어서 분석하고 인식에 사용한다고 했다. 예를 들어서 초당 16000 샘플로 샘플링 한다면 (FS=16000)한 구간을 잡아 나가면 된다. 그럼, 1초 간의 음성에서 얻을 수 있는 FRAME의 개수는 몇 개 일까?
è 99 = FS/M-1 맞나? 각각 계산하기
각 FRAME에서 P차원의 특징을 추출한다면 1초의 음성은 99개의 p차원 벡터열이 된다. 이게 인식에 사용되는 것이다.
마찬가지로 음성의 검출도 frame 단위의 계산에 의해서 수행될 수 있다. 이 경우의 frame크기는 특징 추출시 보다 더 적을 수도 있지만 실시간 구현시 마찬가지로 음성의 검출도 frame 단위의 계산에 의해서 수행될 수 있다.
이 경우의 frame에서 energy와 zcr을 계산한다. 그런데, 지난 번에 말했지만 대부분의 사운드 카드는 DC bias가 존재합니다. 따라서, 이 bias를 제거해야한다. 이건 처음 어느 정도 시간 동안(1초~2초) 음성이 없다고 가정하고 채취한 계산한다. 어떻게 하나면 각 샘플의 제곱을 모두 더하고 샘플수로 나누면 된다. 그런데, 위에서 한 절반 정도씩 중첩한다고 했었다. 그러니까. 한 frame의 절반에 대해서만 계산하고 나머지는 그 전에 계산한 걸 더하면 계산량이 줄어든다.
Zcr은 본래 샘플의 부호가 바뀌는 횟수를 세면 되는데 이게 잡음에 상당히 민감하다. 잡음이 상당한 경우 zcr이 급격히 커질 수 있다. 따라서 평균적인 잡음의 레벨을 추정하고 이를 기준으로 zcr을 계산한다. 무슨 애기냐 하면 실제로 0을 지나는 샘플들을 세는 대신에 +-n 사이를 지나는 샘플의 수를 센다는 것이다. 당연히, n은 평균적인 잡음의 레벨이다. 그래도, 여전히 zcr은 조금 불안한 기준이다. 차라리 마이크 볼륨을 키우고 목소리를 조금 크게 하는게 낮다. Zcr도 그 전 frame의 것을 절반 정도 사용할 수 있다.
각 frame에서 energy와 zcr을 구한 경우 이를 이와 관련된 threshold 값들과 비교해서 음성이 개시되었는지 판정을 한다. 일단 음성이 개시된 걸로 판정되면 그 후 연속적으로 5~6frame이 계속 음성으로 판정되는지 보고 음성으로 판정되면 음성이 개시되었다고 판정한다. 이때 처음 음성으로 판정된 frame의 몇 frame 앞에서 음성이 개시되었다고 판정하는 것이 안전할 수 있다.
(마찰음이나 파열음 등 때문에) 하여간 일단 음성이 시작되고 처음 음성이 아닌 것으로 판정된 frame이 나타나면 계속 저장을 하면서 그 후로 한 20 frame 내외에서 연속해서 5~6 frame이 음성이 아닌 것으로 판정되면 음성이 끝난 것으로 판정한다.
아니면 음성이 계속되고 있다고 보고 계속 끝점 검출을 반복한다. 마찬가지로 끝으로 판정되면 그 판정된 frame 수준 이상의 에너지를 갖는 frame들이 최소한 k개 이상되지 않으면 역시 잡음으로 간주한다.
전체 평균적인 zcr에 의해서도 이러한 판단을 할 수 있다. 이러한 후처리를 통해서 잡음과 음성을 잘 구별하는 것이 중요하다. 각각의 threshold 값이나 필요한 frame 수 등은 상당히 경험적으로 얻어질 수 밖에 없다. 또한, 사용하는 사운드 카드에 따라서도 달라진다. 적당한 low-pass나 high-pass filter가 없는 경우엔 이를 sw적으로 구현해 줘야 한다. 디지털 신호 처리 책을 참고하면 간단한 필터들을 구현할 수 있다.
'★ 내가 원하는 A.I > - 음성인식' 카테고리의 다른 글
| Endpoint Detection (0) | 2012/03/22 |
|---|---|
| Hidden Markov Model (0) | 2012/03/22 |
| 음성인식 응용 (0) | 2012/03/22 |
| 음성합성 (0) | 2012/03/22 |
| 음성이해 (0) | 2012/03/22 |
| 베이즈 추론 (0) | 2012/03/22 |
