Spaces:
Runtime error
Runtime error
| # Created: 2026-03-07 | |
| # Purpose: Radar chart for 7-channel forensic features | |
| # Dependencies: plotly, numpy | |
| """Radar chart visualization for 7 forensic audio features.""" | |
| import numpy as np | |
| import plotly.graph_objects as go | |
| def plot_forensic_radar(feature_stats: dict) -> go.Figure: | |
| """7κ° ν¬λ μ νΌμ²λ₯Ό λ μ΄λ μ°¨νΈλ‘ μκ°ν. | |
| Args: | |
| feature_stats: Dict with feature names as keys and normalized values (0-1) | |
| Returns: | |
| plotly Figure (radar/polar chart) | |
| """ | |
| # 7κ° ν¬λ μ νΌμ² μ μ | |
| features = [ | |
| ("Residual Energy", "μμ°¨ μλμ§ (AI μ½λ± νμ )"), | |
| ("Harmonic Strength", "νλͺ¨λ κ°λ (μμ ꡬ쑰)"), | |
| ("Percussive Strength", "νμ κΈ° κ°λ (λ¦¬λ¬ μμ)"), | |
| ("Temporal Delta", "μκ° λ³νμ¨ (λ€μ΄λλ―Ήμ€)"), | |
| ("Temporal Accel", "μκ° κ°μλ (λ³ν μΌκ΄μ±)"), | |
| ("H/P Ratio", "νλͺ¨λ/νμ κΈ° λΉμ¨"), | |
| ("Spectral Flux", "μ€ννΈλΌ λ³νλ (μ§κ°)"), | |
| ] | |
| # κΈ°λ³Έκ° (feature_statsκ° μμΌλ©΄ μ€κ°κ°) | |
| if not feature_stats: | |
| values = [0.5] * 7 | |
| else: | |
| values = [ | |
| feature_stats.get("residual_energy", 0.5), | |
| feature_stats.get("harmonic_strength", 0.5), | |
| feature_stats.get("percussive_strength", 0.5), | |
| feature_stats.get("temporal_delta", 0.5), | |
| feature_stats.get("temporal_accel", 0.5), | |
| feature_stats.get("hp_ratio", 0.5), | |
| feature_stats.get("spectral_flux", 0.5), | |
| ] | |
| # λ μ΄λ μ°¨νΈμ© λ°μ΄ν° (첫 κ°μ λ§μ§λ§μ λ°λ³΅ν΄μ ν곑μ μμ±) | |
| categories = [f[0] for f in features] | |
| values_closed = values + [values[0]] | |
| categories_closed = categories + [categories[0]] | |
| fig = go.Figure() | |
| # νμ¬ μ€λμ€ ν¨ν΄ | |
| fig.add_trace(go.Scatterpolar( | |
| r=values_closed, | |
| theta=categories_closed, | |
| fill='toself', | |
| fillcolor='rgba(255, 71, 87, 0.3)', | |
| line=dict(color='#ff4757', width=2), | |
| name='Audio Pattern', | |
| hovertemplate="<b>%{theta}</b><br>Score: %{r:.2f}<extra></extra>" | |
| )) | |
| fig.update_layout( | |
| polar=dict( | |
| radialaxis=dict( | |
| visible=True, | |
| range=[0, 1], | |
| tickfont=dict(size=10, color='#aaa'), | |
| gridcolor='#333', | |
| ), | |
| angularaxis=dict( | |
| tickfont=dict(size=11, color='white'), | |
| gridcolor='#333', | |
| ), | |
| bgcolor='#16213e', | |
| ), | |
| plot_bgcolor='#1a1a2e', | |
| paper_bgcolor='#1a1a2e', | |
| font=dict(color='white'), | |
| margin=dict(l=80, r=80, t=40, b=40), | |
| height=400, | |
| showlegend=True, | |
| legend=dict( | |
| x=0.5, xanchor='center', | |
| y=-0.15, yanchor='top', | |
| orientation='h', | |
| font=dict(size=10) | |
| ), | |
| title=dict( | |
| text="Forensic Feature Profile", | |
| font=dict(size=14), | |
| x=0.5, xanchor='center' | |
| ) | |
| ) | |
| return fig | |
| def forensic_features_explanation() -> str: | |
| """7κ° ν¬λ μ νΌμ²μ λν μμΈ μ€λͺ HTML λ°ν.""" | |
| return """ | |
| <div style="background:#16213e;padding:20px;border-radius:12px;margin-top:10px;"> | |
| <h3 style="color:#00d2ff;margin-top:0;font-size:16px;">π¬ 7-Channel Forensic Features</h3> | |
| <div style="font-size:13px;color:#ccc;line-height:1.6;"> | |
| <details style="margin-bottom:10px;"> | |
| <summary style="cursor:pointer;color:#ffa502;font-weight:bold;"> | |
| π 1. Residual Energy (μμ°¨ μλμ§) | |
| </summary> | |
| <p style="margin:8px 0 0 20px;color:#aaa;"> | |
| AI λ΄λ΄ μ½λ±μ΄ λ¨κΈ°λ λ―ΈμΈν μ½λ± νμ . | |
| AI μμ μ μΈκ°μ΄ λ§λ μμ κ³Ό λ€λ₯Έ <b>μμν ν¨ν΄</b>μ 보μ λλ€. | |
| </p> | |
| </details> | |
| <details style="margin-bottom:10px;"> | |
| <summary style="cursor:pointer;color:#ffa502;font-weight:bold;"> | |
| π΅ 2-3. Harmonic/Percussive Strength (νλͺ¨λ/νμ κΈ° κ°λ) | |
| </summary> | |
| <p style="margin:8px 0 0 20px;color:#aaa;"> | |
| μμ μ λ©λ‘λ μ±λΆκ³Ό λ¦¬λ¬ μ±λΆμΌλ‘ λΆλ¦¬. | |
| AIλ λ μμμ <b>μλμ§ λΉμ¨</b>μ΄ λΆμμ°μ€λ½κ² μΌμ ν©λλ€. | |
| </p> | |
| </details> | |
| <details style="margin-bottom:10px;"> | |
| <summary style="cursor:pointer;color:#ffa502;font-weight:bold;"> | |
| β‘ 4-5. Temporal Delta & Accel (μκ° λ³νμ¨/κ°μλ) | |
| </summary> | |
| <p style="margin:8px 0 0 20px;color:#aaa;"> | |
| μ€ννΈλΌμ μκ°μΆ λ³ν ν¨ν΄. | |
| AI μμ μ λ³νκ° <b>λ무 λΆλλ½κ³ κ·μΉμ </b>μ λλ€ (μμ± κ³Όμ μ smoothing ν¨κ³Ό). | |
| </p> | |
| </details> | |
| <details style="margin-bottom:10px;"> | |
| <summary style="cursor:pointer;color:#ffa502;font-weight:bold;"> | |
| ποΈ 6. H/P Ratio (νλͺ¨λ/νμ κΈ° λΉμ¨) | |
| </summary> | |
| <p style="margin:8px 0 0 20px;color:#aaa;"> | |
| λ©λ‘λμ 리λ¬μ κ· ν. | |
| AIλ μ₯λ₯΄μ 무κ΄νκ² <b>νΉμ λΉμ¨λ‘ μλ ΄</b>νλ κ²½ν₯μ 보μ λλ€. | |
| </p> | |
| </details> | |
| <details> | |
| <summary style="cursor:pointer;color:#ffa502;font-weight:bold;"> | |
| π 7. Spectral Flux (μ€ννΈλΌ λ³νλ) | |
| </summary> | |
| <p style="margin:8px 0 0 20px;color:#aaa;"> | |
| μ£Όνμ μ±λΆμ νλ μκ° λ³ν μ λκ°. | |
| AIλ λ³νκ° <b>μΌκ΄μ μ΄κ³ μμΈ‘ κ°λ₯</b>ν©λλ€ (νλ₯ μ μμ±μ νΉμ±). | |
| </p> | |
| </details> | |
| </div> | |
| <div style="margin-top:15px;padding:12px;background:#1a1a2e;border-radius:8px;border-left:3px solid #00d2ff;"> | |
| <p style="margin:0;font-size:12px;color:#aaa;"> | |
| <b style="color:#00d2ff;">π‘ ν΅μ¬ μ리:</b> | |
| AI μμ± λͺ¨λΈμ <b>물리μ μ κΈ°μ λΆκ·μΉμ±</b>μ μλ²½ν μ¬ννμ§ λͺ»ν©λλ€. | |
| μ΄ 7κ° νΌμ²λ κ·Έλ¬ν λ―ΈμΈν μ°¨μ΄λ₯Ό μ λννμ¬ AI μκ·Έλμ²λ₯Ό νμ§ν©λλ€. | |
| </p> | |
| </div> | |
| </div> | |
| """ | |