좋은 질문이에요! 👌
OpenCV가 영상 처리에 특화된 라이브러리라면, 파이썬에서 음성(오디오) 처리를 할 때는 여러 모듈들이 있습니다. 용도별로 정리해드릴게요:
🎙️ 음성 입력/출력(녹음·재생)
- PyAudio : 마이크 입력, 스피커 출력 같은 저수준 오디오 입출력 라이브러리
- sounddevice : NumPy 배열 기반으로 간단히 녹음/재생 가능
- playsound : 단순히 mp3/wav 같은 오디오 파일을 재생할 때 사용
🔊 음성 신호 처리(파형·스펙트럼)
- librosa : 음성 신호 분석, 특징 추출(MFCC, 스펙트로그램 등)
- scipy.signal : 필터링, 푸리에 변환 등 기본 신호처리 기능 제공
- torchaudio : PyTorch와 연동해 딥러닝용 오디오 전처리에 많이 사용
🗣️ 음성 인식(STT: Speech To Text)
- SpeechRecognition : 구글/비스퍼 등 다양한 STT API 연결 지원
- whisper (OpenAI Whisper) : 최신 음성 인식 모델, 한글도 잘 지원
🔈 음성 합성(TTS: Text To Speech)
- pyttsx3 : 오프라인 TTS 라이브러리 (윈도우/맥/리눅스 지원)
- gTTS : 구글 TTS API 기반, 한국어 지원, MP3로 저장 가능
- Coqui TTS : 딥러닝 기반 고품질 오픈소스 TTS
🤖 고급/딥러닝 기반
- transformers (Hugging Face) : Wav2Vec2, Whisper, TTS 모델 제공
- ESPnet / fairseq : 음성 인식·합성 연구용 프레임워크
- torchaudio : STT/TTS 모델 학습에 활용
👉 정리하면:
- 입출력 → sounddevice, PyAudio
- 신호처리 → librosa, scipy.signal
- 음성인식 → SpeechRecognition, whisper
- TTS → pyttsx3, gTTS
큰 그림
- 마이크 캡처: sounddevice로 16kHz 모노 스트리밍
- VAD(음성/무음 구분): webrtcvad로 말할 때만 청크를 모아 지연 최소화
- STT: faster-whisper(Whisper 가속 구현)로 청크 단위 즉시 인식
- TTS: 빠르게는 pyttsx3(윈도우 SAPI5, 오프라인)로 말하기
- (선택) 인식 텍스트 → NLU/명령 처리 → 답변 텍스트 → TTS
Windows 설치 (Python 3.10~3.11 권장)
# 새 가상환경(권장)
python -m venv venv
.\venv\Scripts\activate
# 필수
pip install --upgrade pip
pip install sounddevice numpy webrtcvad faster-whisper pyttsx3
# (선택) PyTorch가 필요한 건 아니지만 나중에 torchaudio 쓰면 설치
# CUDA가 없다면 cpu 전용으로 설치됩니다.
# pip install torch torchaudio --index-url https://download.pytorch.org/whl/cpu
예제: 실시간 STT + 즉시 TTS 에코
- 20ms 프레임 단위로 VAD 적용
- 말이 멈추면(무음 0.6초) 모인 청크를 STT → 바로 pyttsx3로 읽어줌
- Whisper 모델 크기: tiny/base/small/medium/large-v3 (작을수록 지연↓, 정확도↓)
# realtime_stt_tts.py
import queue
import sys
import time
import numpy as np
import sounddevice as sd
import webrtcvad
import pyttsx3
from faster_whisper import WhisperModel
#####################
# 설정값 (지연/정확도 트레이드오프)
#####################
SAMPLE_RATE = 16000 # Whisper 권장
CHANNELS = 1
FRAME_DURATION_MS = 20 # 10/20/30ms만 가능(webrtcvad 제약)
VAD_AGGRESSIVENESS = 2 # 0~3 (클수록 더 공격적으로 음성으로 판단)
MAX_SILENCE_SECS = 0.6 # 이만큼 무음이면 한 문장 끝으로 간주
WHISPER_MODEL_SIZE = "small" # "tiny", "base", "small" 권장(실시간)
WHISPER_DEVICE = "cpu" # "cpu" 또는 "cuda" (CUDA 빌드 세팅 시)
LANGUAGE = "ko" # 한국어 고정(자동감지 원하면 None)
BEAM_SIZE = 1 # 속도 우선
#####################
# 준비: TTS
#####################
tts = pyttsx3.init() # Windows: SAPI5
tts.setProperty("rate", 180) # 말속도
tts.setProperty("volume", 1.0)
#####################
# 준비: Whisper
#####################
print("Loading Whisper model... (first time can take a bit)")
model = WhisperModel(
WHISPER_MODEL_SIZE,
device=WHISPER_DEVICE,
compute_type="int8" if WHISPER_DEVICE == "cpu" else "float16" # CPU는 int8 추천
)
#####################
# 준비: 오디오 & VAD
#####################
audio_q = queue.Queue()
frame_len = int(SAMPLE_RATE * FRAME_DURATION_MS / 1000) # 샘플 수(20ms=320)
vad = webrtcvad.Vad(VAD_AGGRESSIVENESS)
def audio_callback(indata, frames, time_info, status):
if status:
print(status, file=sys.stderr)
# float32 -> int16 변환 (webrtcvad는 16bit PCM 필요)
pcm16 = np.clip(indata[:, 0], -1.0, 1.0)
pcm16 = (pcm16 * 32767).astype(np.int16)
audio_q.put(pcm16.tobytes())
return
#####################
# 유틸: VAD 프레이밍
#####################
def bytes_to_vad_frames(byte_buffer):
# 20ms 단위로 자르기
chunk_size = frame_len * 2 # int16 = 2 bytes
for i in range(0, len(byte_buffer), chunk_size):
yield byte_buffer[i:i+chunk_size]
def is_speech(frame_bytes):
# webrtcvad는 16kHz mono 16bit PCM little-endian 필요
if len(frame_bytes) != frame_len * 2:
return False
try:
return vad.is_speech(frame_bytes, SAMPLE_RATE)
except Exception:
return False
#####################
# 메인 루프
#####################
def main():
print("Starting audio stream...")
with sd.InputStream(
channels=CHANNELS,
samplerate=SAMPLE_RATE,
dtype="float32",
blocksize=frame_len, # 20ms 콜백
callback=audio_callback,
latency="low"
):
voiced_bytes = bytearray()
last_voice_time = None
buffering = bytearray()
while True:
# 큐에서 받아 프레임 묶기
try:
block = audio_q.get(timeout=1.0) # 1초 대기
buffering.extend(block)
except queue.Empty:
continue
# 20ms 단위로 검사
for f in bytes_to_vad_frames(buffering):
if len(f) < frame_len * 2:
# 다음 블록과 합치기 위해 루프 종료
buffering = bytearray(f)
break
speech = is_speech(f)
if speech:
voiced_bytes.extend(f)
last_voice_time = time.time()
else:
# 무음
pass
# 문장 끝났는지 체크
if last_voice_time is not None and (time.time() - last_voice_time) > MAX_SILENCE_SECS and len(voiced_bytes) > 0:
# STT 수행
segment_pcm = np.frombuffer(voiced_bytes, dtype=np.int16).astype(np.float32) / 32768.0
# faster-whisper에 직접 배열 전달 가능
# vad로 이미 잘랐으므로 no_speech_threshold 완화
segments, info = model.transcribe(
segment_pcm,
language=LANGUAGE,
beam_size=BEAM_SIZE,
vad_filter=False, # 이미 수동 VAD 적용
temperature=0.0,
no_speech_threshold=0.2,
condition_on_previous_text=False
)
text_out = ""
for seg in segments:
text_out += seg.text
text_out = text_out.strip()
if text_out:
print(f"[STT] {text_out}")
# (여기서 NLU/명령 처리 로직을 넣을 수 있음)
# reply_text = handle_command(text_out)
reply_text = text_out # 데모: 그대로 따라 말하기
# TTS
tts.say(reply_text)
tts.runAndWait()
# 다음 문장 준비
voiced_bytes = bytearray()
last_voice_time = None
else:
# 프레임 루프를 정상 종료한 경우, 버퍼 비움
buffering = bytearray()
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
print("\nBye")
# 실행
python realtime_stt_tts.py
# 말하고 멈추면(무음 0.6초) 즉시 인식 → 스피커로 읽어줍니다.
튜닝 포인트(중요)
- 지연 줄이기
- WHISPER_MODEL_SIZE: tiny 또는 base로 ↓
- MAX_SILENCE_SECS: 0.6 → 0.3~0.5로 ↓
- FRAME_DURATION_MS: 20ms 유지(10ms는 CPU 부하↑)
- 가능하면 CUDA 빌드로 WHISPER_DEVICE="cuda", compute_type="float16"
- 정확도 올리기
- 모델을 small 이상으로 ↑
- LANGUAGE=None로 자동감지(영/한 혼용 시 유리)
- VAD aggressiveness를 1~2로 조절(3은 침소봉대 가능)
- 말 잘 끊기게
- MAX_SILENCE_SECS 조절 + VAD 강도 조절
- 긴 문장 실시간 자막 느낌이면, 무음 임계값을 짧게 잡아 “짧게-짧게” 인식
모델 연결 확장
- NLU/명령 처리: STT 결과를 키워드 매칭, 정규식, 또는 LLM API로 처리
- 고급 TTS: 더 자연스러운 음색이 필요하면
- Coqui TTS 로컬 모델(오프라인),
- Windows SAPI5 보이스(설정 → 접근성 → 내레이터 → 보이스 설치 후 pyttsx3에서 선택)
- 오디오 전처리: pydub/scipy.signal로 노멀라이즈, HPF/LPF 필터, AGC 등
- 핀치 포인트: 에코·하울링 방지 필요하면 헤드셋 사용 or WebRTC AEC(별도 구현)
원하시면 위 데모를 **“명령어 반응 봇”**으로 바꿔서
예) “원, 100픽셀 그려” → OpenCV로 도형 그리기,
“녹화 시작” → 화면/카메라 녹화 시작,
같은 액션을 바로 붙여드릴게요.
'Projects > AI 아이트래킹 모델 프로젝트' 카테고리의 다른 글
| [도메인 공부 ] 2. 아이트래커 + 스테레오 비전 (0) | 2025.09.11 |
|---|---|
| [도메인 공부 ] 1. 스테레오 알고리즘 (0) | 2025.09.10 |
| [도메인 공부] 홍채 이동에 따른 상대좌표 문제 (0) | 2025.09.08 |
| 눈 내부 정규화, 2차 다항 캘리브레이션, 월드 평면 정합 (0) | 2025.09.05 |
| [도메인 공부] EMA 개념, MediaPipe iris 모델 (0) | 2025.09.03 |