feat(exercise): 优化死虫式训练姿态检测算法
- 调整视频处理频率从每帧处理改为每2帧处理 - 添加膝角趋势平滑算法减少单帧抖动误判 - 改进对角伸展检测逻辑支持准备位手臂上举 - 优化状态机确保严格回到准备姿态才计数 - 添加姿态丢失时的候选帧清理机制 - 更新音频文件生成路径至resources目录 - 改进macOS音频生成使用AIFF格式提高质量 - 添加详细的帧处理日志输出间隔配置
This commit is contained in:
+29
-24
@@ -21,27 +21,27 @@ def generate_rep_audio_files(
|
||||
|
||||
默认生成到:
|
||||
|
||||
app/audio/reps/0.wav
|
||||
app/audio/reps/1.wav
|
||||
resources/audio/reps/0.aiff # macOS
|
||||
resources/audio/reps/0.wav # Windows / Linux
|
||||
...
|
||||
app/audio/reps/200.wav
|
||||
resources/audio/reps/200.aiff 或 200.wav
|
||||
|
||||
服务启动时调用一次即可。
|
||||
"""
|
||||
output_dir.mkdir(parents=True, exist_ok=True)
|
||||
system = platform.system().lower()
|
||||
suffix = ".aiff" if system == "darwin" else ".wav"
|
||||
|
||||
missing_counts = [
|
||||
count
|
||||
for count in range(0, max_count + 1)
|
||||
if overwrite or not _audio_path(output_dir, count).exists()
|
||||
if overwrite or not _audio_path(output_dir, count, suffix=suffix).exists()
|
||||
]
|
||||
|
||||
if not missing_counts:
|
||||
logger.info("Rep audio files already prepared: {}", output_dir)
|
||||
return
|
||||
|
||||
system = platform.system().lower()
|
||||
|
||||
logger.info(
|
||||
"Preparing rep audio files, system={}, count={}, output_dir={}",
|
||||
system,
|
||||
@@ -79,22 +79,27 @@ def _generate_with_macos_say(
|
||||
raise RuntimeError("macOS say command not found")
|
||||
|
||||
for count in counts:
|
||||
audio_file = _audio_path(output_dir, count)
|
||||
audio_file = _audio_path(output_dir, count, suffix=".aiff")
|
||||
|
||||
subprocess.run(
|
||||
[
|
||||
"say",
|
||||
"-r",
|
||||
str(rate),
|
||||
"--file-format=WAVE",
|
||||
"-o",
|
||||
str(audio_file),
|
||||
str(count),
|
||||
],
|
||||
stdout=subprocess.DEVNULL,
|
||||
stderr=subprocess.DEVNULL,
|
||||
check=True,
|
||||
)
|
||||
try:
|
||||
subprocess.run(
|
||||
[
|
||||
"say",
|
||||
"-r",
|
||||
str(rate),
|
||||
"--file-format=AIFF",
|
||||
"-o",
|
||||
str(audio_file),
|
||||
str(count),
|
||||
],
|
||||
stdout=subprocess.DEVNULL,
|
||||
stderr=subprocess.PIPE,
|
||||
text=True,
|
||||
check=True,
|
||||
)
|
||||
except subprocess.CalledProcessError as exc:
|
||||
message = exc.stderr.strip() or f"exit status {exc.returncode}"
|
||||
raise RuntimeError(f"Failed to generate {audio_file}: {message}") from exc
|
||||
|
||||
|
||||
def _generate_with_pyttsx3(
|
||||
@@ -114,11 +119,11 @@ def _generate_with_pyttsx3(
|
||||
engine.setProperty("volume", 1.0)
|
||||
|
||||
for count in counts:
|
||||
audio_file = _audio_path(output_dir, count)
|
||||
audio_file = _audio_path(output_dir, count, suffix=".wav")
|
||||
engine.save_to_file(str(count), str(audio_file))
|
||||
|
||||
engine.runAndWait()
|
||||
|
||||
|
||||
def _audio_path(output_dir: Path, count: int) -> Path:
|
||||
return output_dir / f"{count}.wav"
|
||||
def _audio_path(output_dir: Path, count: int, *, suffix: str) -> Path:
|
||||
return output_dir / f"{count}{suffix}"
|
||||
|
||||
Reference in New Issue
Block a user