Merge b50af72e05 into 6e03a47867
This commit is contained in:
commit
48bd10b3c8
75
ui/app.js
75
ui/app.js
|
|
@ -10,11 +10,65 @@ import { wsService } from './services/websocket.service.js';
|
|||
import { healthService } from './services/health.service.js';
|
||||
import { sensingService } from './services/sensing.service.js';
|
||||
import { backendDetector } from './utils/backend-detector.js';
|
||||
import { i18n } from './i18n/index.js';
|
||||
import zhCN from './i18n/locales/zh-CN.js';
|
||||
import enUS from './i18n/locales/en-US.js';
|
||||
|
||||
class WiFiDensePoseApp {
|
||||
constructor() {
|
||||
this.components = {};
|
||||
this.isInitialized = false;
|
||||
this.i18n = i18n;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化国际化模块
|
||||
*/
|
||||
initializeI18n() {
|
||||
i18n.register('zh-CN', zhCN);
|
||||
i18n.register('en-US', enUS);
|
||||
const locale = i18n.init();
|
||||
console.log(`[App] i18n initialized with locale: ${locale}`);
|
||||
|
||||
i18n.onLocaleChange(() => {
|
||||
i18n.updateDOM();
|
||||
});
|
||||
|
||||
i18n.updateDOM();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前语言
|
||||
* @returns {string} 当前语言代码
|
||||
*/
|
||||
getLocale() {
|
||||
return i18n.getLocale();
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置语言
|
||||
* @param {string} locale - 语言代码
|
||||
*/
|
||||
setLocale(locale) {
|
||||
i18n.setLocale(locale);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取可用语言列表
|
||||
* @returns {string[]} 语言代码数组
|
||||
*/
|
||||
getAvailableLocales() {
|
||||
return i18n.getAvailableLocales();
|
||||
}
|
||||
|
||||
/**
|
||||
* 翻译文本
|
||||
* @param {string} key - 翻译键
|
||||
* @param {Object} params - 参数
|
||||
* @returns {string} 翻译后的文本
|
||||
*/
|
||||
t(key, params = {}) {
|
||||
return i18n.t(key, params);
|
||||
}
|
||||
|
||||
// Initialize application
|
||||
|
|
@ -22,6 +76,9 @@ class WiFiDensePoseApp {
|
|||
try {
|
||||
console.log('Initializing WiFi DensePose UI...');
|
||||
|
||||
// Initialize i18n first
|
||||
this.initializeI18n();
|
||||
|
||||
// Set up error handling
|
||||
this.setupErrorHandling();
|
||||
|
||||
|
|
@ -39,7 +96,7 @@ class WiFiDensePoseApp {
|
|||
|
||||
} catch (error) {
|
||||
console.error('Failed to initialize application:', error);
|
||||
this.showGlobalError('Failed to initialize application. Please refresh the page.');
|
||||
this.showGlobalError(i18n.t('errors.initFailed'));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -227,6 +284,22 @@ class WiFiDensePoseApp {
|
|||
window.addEventListener('beforeunload', () => {
|
||||
this.cleanup();
|
||||
});
|
||||
|
||||
// Handle language selector
|
||||
this.setupLanguageSelector();
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置语言选择器
|
||||
*/
|
||||
setupLanguageSelector() {
|
||||
const selector = document.getElementById('languageSelector');
|
||||
if (selector) {
|
||||
selector.value = i18n.getLocale();
|
||||
selector.addEventListener('change', (e) => {
|
||||
i18n.setLocale(e.target.value);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Handle window resize
|
||||
|
|
|
|||
|
|
@ -0,0 +1,238 @@
|
|||
/**
|
||||
* @file i18n 核心模块 - 提供国际化语言支持
|
||||
* @description 轻量级国际化解决方案,支持多语言切换、参数插值、嵌套翻译
|
||||
*/
|
||||
|
||||
const DEFAULT_LOCALE = 'en-US';
|
||||
const STORAGE_KEY = 'wifi-densepose-locale';
|
||||
|
||||
class I18n {
|
||||
constructor() {
|
||||
this.currentLocale = DEFAULT_LOCALE;
|
||||
this.translations = new Map();
|
||||
this.fallbackLocale = DEFAULT_LOCALE;
|
||||
this.observers = new Set();
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册语言包
|
||||
* @param {string} locale - 语言代码 (如 'zh-CN', 'en-US')
|
||||
* @param {Object} messages - 翻译消息对象
|
||||
*/
|
||||
register(locale, messages) {
|
||||
if (!locale || typeof locale !== 'string') {
|
||||
console.error('[I18n] Invalid locale:', locale);
|
||||
return;
|
||||
}
|
||||
this.translations.set(locale, messages);
|
||||
console.log(`[I18n] Registered locale: ${locale}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置当前语言
|
||||
* @param {string} locale - 语言代码
|
||||
*/
|
||||
setLocale(locale) {
|
||||
if (!this.translations.has(locale)) {
|
||||
console.warn(`[I18n] Locale "${locale}" not registered, using fallback`);
|
||||
locale = this.fallbackLocale;
|
||||
}
|
||||
|
||||
const oldLocale = this.currentLocale;
|
||||
this.currentLocale = locale;
|
||||
|
||||
try {
|
||||
localStorage.setItem(STORAGE_KEY, locale);
|
||||
} catch (e) {
|
||||
console.warn('[I18n] Failed to save locale to localStorage');
|
||||
}
|
||||
|
||||
document.documentElement.lang = locale.split('-')[0];
|
||||
|
||||
this.observers.forEach(callback => {
|
||||
try {
|
||||
callback(locale, oldLocale);
|
||||
} catch (e) {
|
||||
console.error('[I18n] Observer callback error:', e);
|
||||
}
|
||||
});
|
||||
|
||||
console.log(`[I18n] Locale changed: ${oldLocale} -> ${locale}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前语言
|
||||
* @returns {string} 当前语言代码
|
||||
*/
|
||||
getLocale() {
|
||||
return this.currentLocale;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有已注册的语言列表
|
||||
* @returns {string[]} 语言代码数组
|
||||
*/
|
||||
getAvailableLocales() {
|
||||
return Array.from(this.translations.keys());
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化语言设置
|
||||
* @returns {string} 检测到的语言代码
|
||||
*/
|
||||
init() {
|
||||
let savedLocale = null;
|
||||
|
||||
try {
|
||||
savedLocale = localStorage.getItem(STORAGE_KEY);
|
||||
} catch (e) {
|
||||
console.warn('[I18n] Failed to read locale from localStorage');
|
||||
}
|
||||
|
||||
if (savedLocale && this.translations.has(savedLocale)) {
|
||||
this.currentLocale = savedLocale;
|
||||
} else {
|
||||
const browserLocale = this.detectBrowserLocale();
|
||||
this.currentLocale = browserLocale;
|
||||
}
|
||||
|
||||
document.documentElement.lang = this.currentLocale.split('-')[0];
|
||||
console.log(`[I18n] Initialized with locale: ${this.currentLocale}`);
|
||||
|
||||
return this.currentLocale;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测浏览器语言
|
||||
* @returns {string} 检测到的语言代码
|
||||
*/
|
||||
detectBrowserLocale() {
|
||||
const browserLang = navigator.language || navigator.userLanguage;
|
||||
|
||||
if (this.translations.has(browserLang)) {
|
||||
return browserLang;
|
||||
}
|
||||
|
||||
const baseLang = browserLang.split('-')[0];
|
||||
for (const locale of this.translations.keys()) {
|
||||
if (locale.startsWith(baseLang)) {
|
||||
return locale;
|
||||
}
|
||||
}
|
||||
|
||||
return this.fallbackLocale;
|
||||
}
|
||||
|
||||
/**
|
||||
* 翻译文本
|
||||
* @param {string} key - 翻译键,支持点分隔符嵌套 (如 'nav.dashboard')
|
||||
* @param {Object} params - 插值参数
|
||||
* @returns {string} 翻译后的文本
|
||||
*/
|
||||
t(key, params = {}) {
|
||||
const messages = this.translations.get(this.currentLocale);
|
||||
let text = this.getNestedValue(messages, key);
|
||||
|
||||
if (text === undefined) {
|
||||
const fallbackMessages = this.translations.get(this.fallbackLocale);
|
||||
text = this.getNestedValue(fallbackMessages, key);
|
||||
}
|
||||
|
||||
if (text === undefined) {
|
||||
console.warn(`[I18n] Missing translation for key: "${key}"`);
|
||||
return key;
|
||||
}
|
||||
|
||||
if (typeof text === 'string' && Object.keys(params).length > 0) {
|
||||
text = this.interpolate(text, params);
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取嵌套对象的值
|
||||
* @param {Object} obj - 源对象
|
||||
* @param {string} key - 点分隔的键路径
|
||||
* @returns {*} 找到的值或 undefined
|
||||
*/
|
||||
getNestedValue(obj, key) {
|
||||
if (!obj || typeof key !== 'string') return undefined;
|
||||
|
||||
const keys = key.split('.');
|
||||
let value = obj;
|
||||
|
||||
for (const k of keys) {
|
||||
if (value && typeof value === 'object' && k in value) {
|
||||
value = value[k];
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 插值替换参数
|
||||
* @param {string} text - 包含 {param} 占位符的文本
|
||||
* @param {Object} params - 参数对象
|
||||
* @returns {string} 替换后的文本
|
||||
*/
|
||||
interpolate(text, params) {
|
||||
return text.replace(/\{(\w+)\}/g, (match, key) => {
|
||||
return params.hasOwnProperty(key) ? String(params[key]) : match;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 监听语言变化
|
||||
* @param {Function} callback - 回调函数 (newLocale, oldLocale) => void
|
||||
* @returns {Function} 取消监听函数
|
||||
*/
|
||||
onLocaleChange(callback) {
|
||||
this.observers.add(callback);
|
||||
return () => this.observers.delete(callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新页面中所有带有 data-i18n 属性的元素
|
||||
*/
|
||||
updateDOM() {
|
||||
const elements = document.querySelectorAll('[data-i18n]');
|
||||
|
||||
elements.forEach(element => {
|
||||
const key = element.getAttribute('data-i18n');
|
||||
const attr = element.getAttribute('data-i18n-attr') || 'textContent';
|
||||
const params = element.getAttribute('data-i18n-params');
|
||||
|
||||
let parsedParams = {};
|
||||
if (params) {
|
||||
try {
|
||||
parsedParams = JSON.parse(params);
|
||||
} catch (e) {
|
||||
console.warn('[I18n] Failed to parse params:', params);
|
||||
}
|
||||
}
|
||||
|
||||
const text = this.t(key, parsedParams);
|
||||
|
||||
if (attr === 'textContent') {
|
||||
element.textContent = text;
|
||||
} else if (attr === 'innerHTML') {
|
||||
element.innerHTML = text;
|
||||
} else if (attr === 'placeholder') {
|
||||
element.placeholder = text;
|
||||
} else if (attr === 'title') {
|
||||
element.title = text;
|
||||
} else {
|
||||
element.setAttribute(attr, text);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const i18n = new I18n();
|
||||
|
||||
export { i18n, I18n };
|
||||
export default i18n;
|
||||
|
|
@ -0,0 +1,287 @@
|
|||
/**
|
||||
* @file English (US) Language Pack
|
||||
* @description WiFi DensePose Application English Translation
|
||||
*/
|
||||
|
||||
export default {
|
||||
meta: {
|
||||
title: 'WiFi DensePose: Human Tracking Through Walls',
|
||||
description: 'Human Tracking Through Walls Using WiFi Signals'
|
||||
},
|
||||
|
||||
header: {
|
||||
title: 'WiFi DensePose',
|
||||
subtitle: 'Human Tracking Through Walls Using WiFi Signals'
|
||||
},
|
||||
|
||||
nav: {
|
||||
dashboard: 'Dashboard',
|
||||
hardware: 'Hardware',
|
||||
demo: 'Live Demo',
|
||||
architecture: 'Architecture',
|
||||
performance: 'Performance',
|
||||
applications: 'Applications',
|
||||
sensing: 'Sensing',
|
||||
training: 'Training',
|
||||
observatory: 'Observatory'
|
||||
},
|
||||
|
||||
dashboard: {
|
||||
title: 'Revolutionary WiFi-Based Human Pose Detection',
|
||||
description: 'AI can track your full-body movement through walls using just WiFi signals. Researchers at Carnegie Mellon have trained a neural network to turn basic WiFi signals into detailed wireframe models of human bodies.',
|
||||
|
||||
status: {
|
||||
title: 'System Status',
|
||||
apiServer: 'API Server',
|
||||
hardware: 'Hardware',
|
||||
inference: 'Inference',
|
||||
streaming: 'Streaming',
|
||||
datasource: 'Data Source'
|
||||
},
|
||||
|
||||
metrics: {
|
||||
title: 'System Metrics',
|
||||
cpuUsage: 'CPU Usage',
|
||||
memoryUsage: 'Memory Usage',
|
||||
diskUsage: 'Disk Usage'
|
||||
},
|
||||
|
||||
features: {
|
||||
title: 'Features'
|
||||
},
|
||||
|
||||
stats: {
|
||||
title: 'Live Statistics',
|
||||
activePersons: 'Active Persons',
|
||||
avgConfidence: 'Avg Confidence',
|
||||
totalDetections: 'Total Detections',
|
||||
zoneOccupancy: 'Zone Occupancy'
|
||||
},
|
||||
|
||||
benefits: {
|
||||
throughWalls: {
|
||||
title: 'Through Walls',
|
||||
description: 'Works through solid barriers with no line of sight required'
|
||||
},
|
||||
privacy: {
|
||||
title: 'Privacy-Preserving',
|
||||
description: 'No cameras or visual recording - just WiFi signal analysis'
|
||||
},
|
||||
realtime: {
|
||||
title: 'Real-Time',
|
||||
description: 'Maps 24 body regions in real-time at 100Hz sampling rate'
|
||||
},
|
||||
lowCost: {
|
||||
title: 'Low Cost',
|
||||
description: 'Built using $30 commercial WiFi hardware'
|
||||
}
|
||||
},
|
||||
|
||||
systemStats: {
|
||||
bodyRegions: 'Body Regions',
|
||||
samplingRate: 'Sampling Rate',
|
||||
accuracy: 'Accuracy (AP@50)',
|
||||
hardwareCost: 'Hardware Cost'
|
||||
}
|
||||
},
|
||||
|
||||
hardware: {
|
||||
title: 'Hardware Configuration',
|
||||
|
||||
antenna: {
|
||||
title: '3×3 Antenna Array',
|
||||
helpText: 'Click antennas to toggle their state',
|
||||
transmitters: 'Transmitters (3)',
|
||||
receivers: 'Receivers (6)'
|
||||
},
|
||||
|
||||
wifi: {
|
||||
title: 'WiFi Configuration',
|
||||
frequency: 'Frequency',
|
||||
frequencyValue: '2.4GHz ± 20MHz',
|
||||
subcarriers: 'Subcarriers',
|
||||
subcarriersValue: '30',
|
||||
samplingRate: 'Sampling Rate',
|
||||
samplingRateValue: '100 Hz',
|
||||
totalCost: 'Total Cost',
|
||||
totalCostValue: '$30'
|
||||
},
|
||||
|
||||
csi: {
|
||||
title: 'Real-time CSI Data',
|
||||
amplitude: 'Amplitude',
|
||||
phase: 'Phase'
|
||||
}
|
||||
},
|
||||
|
||||
demo: {
|
||||
title: 'Live Demonstration',
|
||||
|
||||
controls: {
|
||||
startStream: 'Start Stream',
|
||||
stopStream: 'Stop Stream',
|
||||
ready: 'Ready'
|
||||
},
|
||||
|
||||
signal: {
|
||||
title: 'WiFi Signal Analysis',
|
||||
signalStrength: 'Signal Strength',
|
||||
processingLatency: 'Processing Latency'
|
||||
},
|
||||
|
||||
pose: {
|
||||
title: 'Human Pose Detection',
|
||||
personsDetected: 'Persons Detected',
|
||||
confidence: 'Confidence',
|
||||
keypoints: 'Keypoints'
|
||||
}
|
||||
},
|
||||
|
||||
architecture: {
|
||||
title: 'System Architecture',
|
||||
|
||||
steps: {
|
||||
csiInput: {
|
||||
title: 'CSI Input',
|
||||
description: 'Channel State Information collected from WiFi antenna array'
|
||||
},
|
||||
phaseSanitization: {
|
||||
title: 'Phase Sanitization',
|
||||
description: 'Remove hardware-specific noise and normalize signal phase'
|
||||
},
|
||||
modalityTranslation: {
|
||||
title: 'Modality Translation',
|
||||
description: 'Convert WiFi signals to visual representation using CNN'
|
||||
},
|
||||
densePose: {
|
||||
title: 'DensePose-RCNN',
|
||||
description: 'Extract human pose keypoints and body part segmentation'
|
||||
},
|
||||
wireframeOutput: {
|
||||
title: 'Wireframe Output',
|
||||
description: 'Generate final human pose wireframe visualization'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
performance: {
|
||||
title: 'Performance Analysis',
|
||||
|
||||
wifiBased: {
|
||||
title: 'WiFi-based (Same Layout)',
|
||||
averagePrecision: 'Average Precision',
|
||||
ap50: 'AP@50',
|
||||
ap75: 'AP@75'
|
||||
},
|
||||
|
||||
imageBased: {
|
||||
title: 'Image-based (Reference)',
|
||||
averagePrecision: 'Average Precision',
|
||||
ap50: 'AP@50',
|
||||
ap75: 'AP@75'
|
||||
},
|
||||
|
||||
advantages: {
|
||||
title: 'Advantages & Limitations',
|
||||
pros: {
|
||||
title: 'Advantages',
|
||||
items: [
|
||||
'Through-wall detection',
|
||||
'Privacy preserving',
|
||||
'Lighting independent',
|
||||
'Low cost hardware',
|
||||
'Uses existing WiFi'
|
||||
]
|
||||
},
|
||||
cons: {
|
||||
title: 'Limitations',
|
||||
items: [
|
||||
'Performance drops in different layouts',
|
||||
'Requires WiFi-compatible devices',
|
||||
'Training requires synchronized data'
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
applications: {
|
||||
title: 'Real-World Applications',
|
||||
|
||||
elderlyCare: {
|
||||
title: 'Elderly Care Monitoring',
|
||||
description: 'Monitor elderly individuals for falls or emergencies without invading privacy. Track movement patterns and detect anomalies in daily routines.',
|
||||
features: ['Fall Detection', 'Activity Monitoring', 'Emergency Alert']
|
||||
},
|
||||
|
||||
homeSecurity: {
|
||||
title: 'Home Security Systems',
|
||||
description: 'Detect intruders and monitor home security without visible cameras. Track multiple persons and identify suspicious movement patterns.',
|
||||
features: ['Intrusion Detection', 'Multi-person Tracking', 'Invisible Monitoring']
|
||||
},
|
||||
|
||||
healthcare: {
|
||||
title: 'Healthcare Patient Monitoring',
|
||||
description: 'Monitor patients in hospitals and care facilities. Track vital signs through movement analysis and detect health emergencies.',
|
||||
features: ['Vital Sign Analysis', 'Movement Tracking', 'Health Alerts']
|
||||
},
|
||||
|
||||
smartBuilding: {
|
||||
title: 'Smart Building Occupancy',
|
||||
description: 'Optimize building energy consumption by tracking occupancy patterns. Control lighting, HVAC, and security systems automatically.',
|
||||
features: ['Energy Optimization', 'Occupancy Tracking', 'Smart Controls']
|
||||
},
|
||||
|
||||
arVr: {
|
||||
title: 'AR/VR Applications',
|
||||
description: 'Enable full-body tracking for virtual and augmented reality applications without wearing additional sensors or cameras.',
|
||||
features: ['Full Body Tracking', 'Sensor-free', 'Immersive Experience']
|
||||
},
|
||||
|
||||
implementation: {
|
||||
title: 'Implementation Considerations',
|
||||
description: 'While WiFi DensePose offers revolutionary capabilities, successful implementation requires careful consideration of environment setup, data privacy regulations, and system calibration for optimal performance.'
|
||||
}
|
||||
},
|
||||
|
||||
training: {
|
||||
title: 'Model Training',
|
||||
description: 'Record CSI data, train pose estimation models, and manage .rvf files'
|
||||
},
|
||||
|
||||
common: {
|
||||
loading: 'Loading...',
|
||||
error: 'Error',
|
||||
success: 'Success',
|
||||
warning: 'Warning',
|
||||
info: 'Info',
|
||||
confirm: 'Confirm',
|
||||
cancel: 'Cancel',
|
||||
save: 'Save',
|
||||
delete: 'Delete',
|
||||
edit: 'Edit',
|
||||
add: 'Add',
|
||||
search: 'Search',
|
||||
noData: 'No data available',
|
||||
retry: 'Retry',
|
||||
close: 'Close',
|
||||
back: 'Back',
|
||||
next: 'Next',
|
||||
previous: 'Previous',
|
||||
submit: 'Submit',
|
||||
reset: 'Reset'
|
||||
},
|
||||
|
||||
errors: {
|
||||
initFailed: 'Failed to initialize application. Please refresh the page.',
|
||||
unexpectedError: 'An unexpected error occurred',
|
||||
connectionLost: 'Connection lost',
|
||||
backendUnavailable: 'Backend unavailable — start sensing-server'
|
||||
},
|
||||
|
||||
notifications: {
|
||||
mockServerActive: 'Mock server active - testing mode',
|
||||
connectedToBackend: 'Connected to Rust sensing server',
|
||||
pageHidden: 'Page hidden, pausing updates',
|
||||
pageVisible: 'Page visible, resuming updates'
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,287 @@
|
|||
/**
|
||||
* @file 中文简体语言包
|
||||
* @description WiFi DensePose 应用中文简体翻译
|
||||
*/
|
||||
|
||||
export default {
|
||||
meta: {
|
||||
title: 'WiFi DensePose: 穿墙人体追踪',
|
||||
description: '使用 WiFi 信号进行穿墙人体追踪'
|
||||
},
|
||||
|
||||
header: {
|
||||
title: 'WiFi DensePose',
|
||||
subtitle: '使用 WiFi 信号进行穿墙人体追踪'
|
||||
},
|
||||
|
||||
nav: {
|
||||
dashboard: '仪表盘',
|
||||
hardware: '硬件配置',
|
||||
demo: '实时演示',
|
||||
architecture: '系统架构',
|
||||
performance: '性能分析',
|
||||
applications: '应用场景',
|
||||
sensing: '感知',
|
||||
training: '模型训练',
|
||||
observatory: '观测站'
|
||||
},
|
||||
|
||||
dashboard: {
|
||||
title: '革命性的 WiFi 人体姿态检测',
|
||||
description: 'AI 可以仅使用 WiFi 信号穿透墙壁追踪您的全身动作。卡内基梅隆大学的研究人员训练了一个神经网络,可以将基本的 WiFi 信号转换为详细的人体线框模型。',
|
||||
|
||||
status: {
|
||||
title: '系统状态',
|
||||
apiServer: 'API 服务器',
|
||||
hardware: '硬件',
|
||||
inference: '推理引擎',
|
||||
streaming: '数据流',
|
||||
datasource: '数据源'
|
||||
},
|
||||
|
||||
metrics: {
|
||||
title: '系统指标',
|
||||
cpuUsage: 'CPU 使用率',
|
||||
memoryUsage: '内存使用率',
|
||||
diskUsage: '磁盘使用率'
|
||||
},
|
||||
|
||||
features: {
|
||||
title: '功能特性'
|
||||
},
|
||||
|
||||
stats: {
|
||||
title: '实时统计',
|
||||
activePersons: '活动人数',
|
||||
avgConfidence: '平均置信度',
|
||||
totalDetections: '总检测次数',
|
||||
zoneOccupancy: '区域占用'
|
||||
},
|
||||
|
||||
benefits: {
|
||||
throughWalls: {
|
||||
title: '穿墙检测',
|
||||
description: '无需视线,可穿透实体障碍物工作'
|
||||
},
|
||||
privacy: {
|
||||
title: '隐私保护',
|
||||
description: '无需摄像头或视频录制,仅分析 WiFi 信号'
|
||||
},
|
||||
realtime: {
|
||||
title: '实时处理',
|
||||
description: '以 100Hz 采样率实时映射 24 个身体区域'
|
||||
},
|
||||
lowCost: {
|
||||
title: '低成本',
|
||||
description: '使用价值 30 美元的商用 WiFi 硬件构建'
|
||||
}
|
||||
},
|
||||
|
||||
systemStats: {
|
||||
bodyRegions: '身体区域',
|
||||
samplingRate: '采样率',
|
||||
accuracy: '准确率 (AP@50)',
|
||||
hardwareCost: '硬件成本'
|
||||
}
|
||||
},
|
||||
|
||||
hardware: {
|
||||
title: '硬件配置',
|
||||
|
||||
antenna: {
|
||||
title: '3×3 天线阵列',
|
||||
helpText: '点击天线切换其状态',
|
||||
transmitters: '发射器 (3)',
|
||||
receivers: '接收器 (6)'
|
||||
},
|
||||
|
||||
wifi: {
|
||||
title: 'WiFi 配置',
|
||||
frequency: '频率',
|
||||
frequencyValue: '2.4GHz ± 20MHz',
|
||||
subcarriers: '子载波',
|
||||
subcarriersValue: '30',
|
||||
samplingRate: '采样率',
|
||||
samplingRateValue: '100 Hz',
|
||||
totalCost: '总成本',
|
||||
totalCostValue: '$30'
|
||||
},
|
||||
|
||||
csi: {
|
||||
title: '实时 CSI 数据',
|
||||
amplitude: '幅度',
|
||||
phase: '相位'
|
||||
}
|
||||
},
|
||||
|
||||
demo: {
|
||||
title: '实时演示',
|
||||
|
||||
controls: {
|
||||
startStream: '开始流',
|
||||
stopStream: '停止流',
|
||||
ready: '就绪'
|
||||
},
|
||||
|
||||
signal: {
|
||||
title: 'WiFi 信号分析',
|
||||
signalStrength: '信号强度',
|
||||
processingLatency: '处理延迟'
|
||||
},
|
||||
|
||||
pose: {
|
||||
title: '人体姿态检测',
|
||||
personsDetected: '检测到的人数',
|
||||
confidence: '置信度',
|
||||
keypoints: '关键点'
|
||||
}
|
||||
},
|
||||
|
||||
architecture: {
|
||||
title: '系统架构',
|
||||
|
||||
steps: {
|
||||
csiInput: {
|
||||
title: 'CSI 输入',
|
||||
description: '从 WiFi 天线阵列收集信道状态信息'
|
||||
},
|
||||
phaseSanitization: {
|
||||
title: '相位净化',
|
||||
description: '去除硬件特定噪声并归一化信号相位'
|
||||
},
|
||||
modalityTranslation: {
|
||||
title: '模态转换',
|
||||
description: '使用 CNN 将 WiFi 信号转换为视觉表示'
|
||||
},
|
||||
densePose: {
|
||||
title: 'DensePose-RCNN',
|
||||
description: '提取人体姿态关键点和身体部位分割'
|
||||
},
|
||||
wireframeOutput: {
|
||||
title: '线框输出',
|
||||
description: '生成最终的人体姿态线框可视化'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
performance: {
|
||||
title: '性能分析',
|
||||
|
||||
wifiBased: {
|
||||
title: '基于 WiFi (相同布局)',
|
||||
averagePrecision: '平均精度',
|
||||
ap50: 'AP@50',
|
||||
ap75: 'AP@75'
|
||||
},
|
||||
|
||||
imageBased: {
|
||||
title: '基于图像 (参考)',
|
||||
averagePrecision: '平均精度',
|
||||
ap50: 'AP@50',
|
||||
ap75: 'AP@75'
|
||||
},
|
||||
|
||||
advantages: {
|
||||
title: '优势与局限',
|
||||
pros: {
|
||||
title: '优势',
|
||||
items: [
|
||||
'穿墙检测',
|
||||
'隐私保护',
|
||||
'不受光照影响',
|
||||
'低成本硬件',
|
||||
'利用现有 WiFi'
|
||||
]
|
||||
},
|
||||
cons: {
|
||||
title: '局限',
|
||||
items: [
|
||||
'不同布局下性能下降',
|
||||
'需要兼容 WiFi 的设备',
|
||||
'训练需要同步数据'
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
applications: {
|
||||
title: '实际应用场景',
|
||||
|
||||
elderlyCare: {
|
||||
title: '老年人监护',
|
||||
description: '在不侵犯隐私的情况下监测老年人的跌倒或紧急情况。追踪活动模式并检测日常行为异常。',
|
||||
features: ['跌倒检测', '活动监测', '紧急报警']
|
||||
},
|
||||
|
||||
homeSecurity: {
|
||||
title: '家庭安防系统',
|
||||
description: '无需可见摄像头即可检测入侵者并监控家庭安全。追踪多人并识别可疑行为模式。',
|
||||
features: ['入侵检测', '多人追踪', '隐形监控']
|
||||
},
|
||||
|
||||
healthcare: {
|
||||
title: '医疗患者监护',
|
||||
description: '在医院和护理机构监测患者。通过动作分析追踪生命体征并检测健康紧急情况。',
|
||||
features: ['生命体征分析', '动作追踪', '健康警报']
|
||||
},
|
||||
|
||||
smartBuilding: {
|
||||
title: '智能建筑占用',
|
||||
description: '通过追踪占用模式优化建筑能耗。自动控制照明、暖通空调和安防系统。',
|
||||
features: ['节能优化', '占用追踪', '智能控制']
|
||||
},
|
||||
|
||||
arVr: {
|
||||
title: 'AR/VR 应用',
|
||||
description: '为虚拟和增强现实应用实现全身追踪,无需佩戴额外传感器或摄像头。',
|
||||
features: ['全身追踪', '无传感器', '沉浸体验']
|
||||
},
|
||||
|
||||
implementation: {
|
||||
title: '实施注意事项',
|
||||
description: '虽然 WiFi DensePose 提供了革命性的能力,但成功实施需要仔细考虑环境设置、数据隐私法规和系统校准以获得最佳性能。'
|
||||
}
|
||||
},
|
||||
|
||||
training: {
|
||||
title: '模型训练',
|
||||
description: '记录 CSI 数据、训练姿态估计模型并管理 .rvf 文件'
|
||||
},
|
||||
|
||||
common: {
|
||||
loading: '加载中...',
|
||||
error: '错误',
|
||||
success: '成功',
|
||||
warning: '警告',
|
||||
info: '信息',
|
||||
confirm: '确认',
|
||||
cancel: '取消',
|
||||
save: '保存',
|
||||
delete: '删除',
|
||||
edit: '编辑',
|
||||
add: '添加',
|
||||
search: '搜索',
|
||||
noData: '暂无数据',
|
||||
retry: '重试',
|
||||
close: '关闭',
|
||||
back: '返回',
|
||||
next: '下一步',
|
||||
previous: '上一步',
|
||||
submit: '提交',
|
||||
reset: '重置'
|
||||
},
|
||||
|
||||
errors: {
|
||||
initFailed: '应用初始化失败,请刷新页面。',
|
||||
unexpectedError: '发生意外错误',
|
||||
connectionLost: '连接已断开',
|
||||
backendUnavailable: '后端不可用 — 请启动 sensing-server'
|
||||
},
|
||||
|
||||
notifications: {
|
||||
mockServerActive: '模拟服务器已激活 - 测试模式',
|
||||
connectedToBackend: '已连接到 Rust 感知服务器',
|
||||
pageHidden: '页面隐藏,暂停更新',
|
||||
pageVisible: '页面可见,恢复更新'
|
||||
}
|
||||
};
|
||||
266
ui/index.html
266
ui/index.html
|
|
@ -3,40 +3,44 @@
|
|||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>WiFi DensePose: Human Tracking Through Walls</title>
|
||||
<title data-i18n="meta.title">WiFi DensePose: Human Tracking Through Walls</title>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<!-- Header -->
|
||||
<header class="header">
|
||||
<h1>WiFi DensePose</h1>
|
||||
<p class="subtitle">Human Tracking Through Walls Using WiFi Signals</p>
|
||||
<h1 data-i18n="header.title">WiFi DensePose</h1>
|
||||
<p class="subtitle" data-i18n="header.subtitle">Human Tracking Through Walls Using WiFi Signals</p>
|
||||
<div class="header-info">
|
||||
<span class="api-version"></span>
|
||||
<span class="api-environment"></span>
|
||||
<span class="overall-health"></span>
|
||||
<select id="languageSelector" class="language-selector" title="Select Language">
|
||||
<option value="en-US">English</option>
|
||||
<option value="zh-CN">中文简体</option>
|
||||
</select>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- Navigation -->
|
||||
<nav class="nav-tabs">
|
||||
<button class="nav-tab active" data-tab="dashboard">Dashboard</button>
|
||||
<button class="nav-tab" data-tab="hardware">Hardware</button>
|
||||
<button class="nav-tab" data-tab="demo">Live Demo</button>
|
||||
<button class="nav-tab" data-tab="architecture">Architecture</button>
|
||||
<button class="nav-tab" data-tab="performance">Performance</button>
|
||||
<button class="nav-tab" data-tab="applications">Applications</button>
|
||||
<button class="nav-tab" data-tab="sensing">Sensing</button>
|
||||
<button class="nav-tab" data-tab="training">Training</button>
|
||||
<a href="observatory.html" class="nav-tab" style="text-decoration:none">Observatory</a>
|
||||
<button class="nav-tab active" data-tab="dashboard" data-i18n="nav.dashboard">Dashboard</button>
|
||||
<button class="nav-tab" data-tab="hardware" data-i18n="nav.hardware">Hardware</button>
|
||||
<button class="nav-tab" data-tab="demo" data-i18n="nav.demo">Live Demo</button>
|
||||
<button class="nav-tab" data-tab="architecture" data-i18n="nav.architecture">Architecture</button>
|
||||
<button class="nav-tab" data-tab="performance" data-i18n="nav.performance">Performance</button>
|
||||
<button class="nav-tab" data-tab="applications" data-i18n="nav.applications">Applications</button>
|
||||
<button class="nav-tab" data-tab="sensing" data-i18n="nav.sensing">Sensing</button>
|
||||
<button class="nav-tab" data-tab="training" data-i18n="nav.training">Training</button>
|
||||
<a href="observatory.html" class="nav-tab" style="text-decoration:none" data-i18n="nav.observatory">Observatory</a>
|
||||
</nav>
|
||||
|
||||
<!-- Dashboard Tab -->
|
||||
<section id="dashboard" class="tab-content active">
|
||||
<div class="hero-section">
|
||||
<h2>Revolutionary WiFi-Based Human Pose Detection</h2>
|
||||
<p class="hero-description">
|
||||
<h2 data-i18n="dashboard.title">Revolutionary WiFi-Based Human Pose Detection</h2>
|
||||
<p class="hero-description" data-i18n="dashboard.description">
|
||||
AI can track your full-body movement through walls using just WiFi signals.
|
||||
Researchers at Carnegie Mellon have trained a neural network to turn basic WiFi
|
||||
signals into detailed wireframe models of human bodies.
|
||||
|
|
@ -47,30 +51,30 @@
|
|||
|
||||
<!-- Live Status Panel -->
|
||||
<div class="live-status-panel">
|
||||
<h3>System Status</h3>
|
||||
<h3 data-i18n="dashboard.status.title">System Status</h3>
|
||||
<div class="status-grid">
|
||||
<div class="component-status" data-component="api">
|
||||
<span class="component-name">API Server</span>
|
||||
<span class="component-name" data-i18n="dashboard.status.apiServer">API Server</span>
|
||||
<span class="status-text">-</span>
|
||||
<span class="status-message"></span>
|
||||
</div>
|
||||
<div class="component-status" data-component="hardware">
|
||||
<span class="component-name">Hardware</span>
|
||||
<span class="component-name" data-i18n="dashboard.status.hardware">Hardware</span>
|
||||
<span class="status-text">-</span>
|
||||
<span class="status-message"></span>
|
||||
</div>
|
||||
<div class="component-status" data-component="inference">
|
||||
<span class="component-name">Inference</span>
|
||||
<span class="component-name" data-i18n="dashboard.status.inference">Inference</span>
|
||||
<span class="status-text">-</span>
|
||||
<span class="status-message"></span>
|
||||
</div>
|
||||
<div class="component-status" data-component="streaming">
|
||||
<span class="component-name">Streaming</span>
|
||||
<span class="component-name" data-i18n="dashboard.status.streaming">Streaming</span>
|
||||
<span class="status-text">-</span>
|
||||
<span class="status-message"></span>
|
||||
</div>
|
||||
<div class="component-status" data-component="datasource" id="dashboard-datasource">
|
||||
<span class="component-name">Data Source</span>
|
||||
<span class="component-name" data-i18n="dashboard.status.datasource">Data Source</span>
|
||||
<span class="status-text">-</span>
|
||||
<span class="status-message"></span>
|
||||
</div>
|
||||
|
|
@ -79,24 +83,24 @@
|
|||
|
||||
<!-- System Metrics -->
|
||||
<div class="system-metrics-panel">
|
||||
<h3>System Metrics</h3>
|
||||
<h3 data-i18n="dashboard.metrics.title">System Metrics</h3>
|
||||
<div class="metrics-grid">
|
||||
<div class="metric-item">
|
||||
<span class="metric-label">CPU Usage</span>
|
||||
<span class="metric-label" data-i18n="dashboard.metrics.cpuUsage">CPU Usage</span>
|
||||
<div class="progress-bar" data-type="cpu">
|
||||
<div class="progress-fill normal" style="width: 0%"></div>
|
||||
</div>
|
||||
<span class="cpu-usage">0%</span>
|
||||
</div>
|
||||
<div class="metric-item">
|
||||
<span class="metric-label">Memory Usage</span>
|
||||
<span class="metric-label" data-i18n="dashboard.metrics.memoryUsage">Memory Usage</span>
|
||||
<div class="progress-bar" data-type="memory">
|
||||
<div class="progress-fill normal" style="width: 0%"></div>
|
||||
</div>
|
||||
<span class="memory-usage">0%</span>
|
||||
</div>
|
||||
<div class="metric-item">
|
||||
<span class="metric-label">Disk Usage</span>
|
||||
<span class="metric-label" data-i18n="dashboard.metrics.diskUsage">Disk Usage</span>
|
||||
<div class="progress-bar" data-type="disk">
|
||||
<div class="progress-fill normal" style="width: 0%"></div>
|
||||
</div>
|
||||
|
|
@ -107,30 +111,30 @@
|
|||
|
||||
<!-- Features Status -->
|
||||
<div class="features-panel">
|
||||
<h3>Features</h3>
|
||||
<h3 data-i18n="dashboard.features.title">Features</h3>
|
||||
<div class="features-status"></div>
|
||||
</div>
|
||||
|
||||
<!-- Live Statistics -->
|
||||
<div class="live-stats-panel">
|
||||
<h3>Live Statistics</h3>
|
||||
<h3 data-i18n="dashboard.stats.title">Live Statistics</h3>
|
||||
<div class="stats-grid">
|
||||
<div class="stat-item">
|
||||
<span class="stat-label">Active Persons</span>
|
||||
<span class="stat-label" data-i18n="dashboard.stats.activePersons">Active Persons</span>
|
||||
<span class="person-count">0</span>
|
||||
</div>
|
||||
<div class="stat-item">
|
||||
<span class="stat-label">Avg Confidence</span>
|
||||
<span class="stat-label" data-i18n="dashboard.stats.avgConfidence">Avg Confidence</span>
|
||||
<span class="avg-confidence">0%</span>
|
||||
</div>
|
||||
<div class="stat-item">
|
||||
<span class="stat-label">Total Detections</span>
|
||||
<span class="stat-label" data-i18n="dashboard.stats.totalDetections">Total Detections</span>
|
||||
<span class="detection-count">0</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="zones-panel">
|
||||
<h4>Zone Occupancy</h4>
|
||||
<h4 data-i18n="dashboard.stats.zoneOccupancy">Zone Occupancy</h4>
|
||||
<div class="zones-summary"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -138,42 +142,42 @@
|
|||
<div class="key-benefits">
|
||||
<div class="benefit-card">
|
||||
<div class="benefit-icon">🏠</div>
|
||||
<h3>Through Walls</h3>
|
||||
<p>Works through solid barriers with no line of sight required</p>
|
||||
<h3 data-i18n="dashboard.benefits.throughWalls.title">Through Walls</h3>
|
||||
<p data-i18n="dashboard.benefits.throughWalls.description">Works through solid barriers with no line of sight required</p>
|
||||
</div>
|
||||
<div class="benefit-card">
|
||||
<div class="benefit-icon">🔒</div>
|
||||
<h3>Privacy-Preserving</h3>
|
||||
<p>No cameras or visual recording - just WiFi signal analysis</p>
|
||||
<h3 data-i18n="dashboard.benefits.privacy.title">Privacy-Preserving</h3>
|
||||
<p data-i18n="dashboard.benefits.privacy.description">No cameras or visual recording - just WiFi signal analysis</p>
|
||||
</div>
|
||||
<div class="benefit-card">
|
||||
<div class="benefit-icon">⚡</div>
|
||||
<h3>Real-Time</h3>
|
||||
<p>Maps 24 body regions in real-time at 100Hz sampling rate</p>
|
||||
<h3 data-i18n="dashboard.benefits.realtime.title">Real-Time</h3>
|
||||
<p data-i18n="dashboard.benefits.realtime.description">Maps 24 body regions in real-time at 100Hz sampling rate</p>
|
||||
</div>
|
||||
<div class="benefit-card">
|
||||
<div class="benefit-icon">💰</div>
|
||||
<h3>Low Cost</h3>
|
||||
<p>Built using $30 commercial WiFi hardware</p>
|
||||
<h3 data-i18n="dashboard.benefits.lowCost.title">Low Cost</h3>
|
||||
<p data-i18n="dashboard.benefits.lowCost.description">Built using $30 commercial WiFi hardware</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="system-stats">
|
||||
<div class="stat" data-stat="body-regions">
|
||||
<span class="stat-value">24</span>
|
||||
<span class="stat-label">Body Regions</span>
|
||||
<span class="stat-label" data-i18n="dashboard.systemStats.bodyRegions">Body Regions</span>
|
||||
</div>
|
||||
<div class="stat" data-stat="sampling-rate">
|
||||
<span class="stat-value">100Hz</span>
|
||||
<span class="stat-label">Sampling Rate</span>
|
||||
<span class="stat-label" data-i18n="dashboard.systemStats.samplingRate">Sampling Rate</span>
|
||||
</div>
|
||||
<div class="stat" data-stat="accuracy">
|
||||
<span class="stat-value">87.2%</span>
|
||||
<span class="stat-label">Accuracy (AP@50)</span>
|
||||
<span class="stat-label" data-i18n="dashboard.systemStats.accuracy">Accuracy (AP@50)</span>
|
||||
</div>
|
||||
<div class="stat" data-stat="hardware-cost">
|
||||
<span class="stat-value">$30</span>
|
||||
<span class="stat-label">Hardware Cost</span>
|
||||
<span class="stat-label" data-i18n="dashboard.systemStats.hardwareCost">Hardware Cost</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -181,12 +185,12 @@
|
|||
|
||||
<!-- Hardware Tab -->
|
||||
<section id="hardware" class="tab-content">
|
||||
<h2>Hardware Configuration</h2>
|
||||
<h2 data-i18n="hardware.title">Hardware Configuration</h2>
|
||||
|
||||
<div class="hardware-grid">
|
||||
<div class="antenna-section">
|
||||
<h3>3×3 Antenna Array</h3>
|
||||
<p class="help-text">Click antennas to toggle their state</p>
|
||||
<h3 data-i18n="hardware.antenna.title">3×3 Antenna Array</h3>
|
||||
<p class="help-text" data-i18n="hardware.antenna.helpText">Click antennas to toggle their state</p>
|
||||
<div class="antenna-array">
|
||||
<div class="antenna-grid">
|
||||
<div class="antenna tx active" data-type="TX1"></div>
|
||||
|
|
@ -202,11 +206,11 @@
|
|||
<div class="antenna-legend">
|
||||
<div class="legend-item">
|
||||
<div class="legend-color tx"></div>
|
||||
<span>Transmitters (3)</span>
|
||||
<span data-i18n="hardware.antenna.transmitters">Transmitters (3)</span>
|
||||
</div>
|
||||
<div class="legend-item">
|
||||
<div class="legend-color rx"></div>
|
||||
<span>Receivers (6)</span>
|
||||
<span data-i18n="hardware.antenna.receivers">Receivers (6)</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="array-status"></div>
|
||||
|
|
@ -214,38 +218,38 @@
|
|||
</div>
|
||||
|
||||
<div class="config-section">
|
||||
<h3>WiFi Configuration</h3>
|
||||
<h3 data-i18n="hardware.wifi.title">WiFi Configuration</h3>
|
||||
<div class="config-grid">
|
||||
<div class="config-item">
|
||||
<label>Frequency</label>
|
||||
<div class="config-value">2.4GHz ± 20MHz</div>
|
||||
<label data-i18n="hardware.wifi.frequency">Frequency</label>
|
||||
<div class="config-value" data-i18n="hardware.wifi.frequencyValue">2.4GHz ± 20MHz</div>
|
||||
</div>
|
||||
<div class="config-item">
|
||||
<label>Subcarriers</label>
|
||||
<div class="config-value">30</div>
|
||||
<label data-i18n="hardware.wifi.subcarriers">Subcarriers</label>
|
||||
<div class="config-value" data-i18n="hardware.wifi.subcarriersValue">30</div>
|
||||
</div>
|
||||
<div class="config-item">
|
||||
<label>Sampling Rate</label>
|
||||
<div class="config-value">100 Hz</div>
|
||||
<label data-i18n="hardware.wifi.samplingRate">Sampling Rate</label>
|
||||
<div class="config-value" data-i18n="hardware.wifi.samplingRateValue">100 Hz</div>
|
||||
</div>
|
||||
<div class="config-item">
|
||||
<label>Total Cost</label>
|
||||
<div class="config-value">$30</div>
|
||||
<label data-i18n="hardware.wifi.totalCost">Total Cost</label>
|
||||
<div class="config-value" data-i18n="hardware.wifi.totalCostValue">$30</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="csi-data">
|
||||
<h4>Real-time CSI Data</h4>
|
||||
<h4 data-i18n="hardware.csi.title">Real-time CSI Data</h4>
|
||||
<div class="csi-display">
|
||||
<div class="csi-row">
|
||||
<span>Amplitude:</span>
|
||||
<span data-i18n="hardware.csi.amplitude">Amplitude:</span>
|
||||
<div class="csi-bar">
|
||||
<div class="csi-fill amplitude" style="width: 75%"></div>
|
||||
</div>
|
||||
<span class="csi-value">0.75</span>
|
||||
</div>
|
||||
<div class="csi-row">
|
||||
<span>Phase:</span>
|
||||
<span data-i18n="hardware.csi.phase">Phase:</span>
|
||||
<div class="csi-bar">
|
||||
<div class="csi-fill phase" style="width: 60%"></div>
|
||||
</div>
|
||||
|
|
@ -259,50 +263,50 @@
|
|||
|
||||
<!-- Demo Tab -->
|
||||
<section id="demo" class="tab-content">
|
||||
<h2>Live Demonstration</h2>
|
||||
<h2 data-i18n="demo.title">Live Demonstration</h2>
|
||||
|
||||
<div class="demo-controls">
|
||||
<button id="startDemo" class="btn btn--primary">Start Stream</button>
|
||||
<button id="stopDemo" class="btn btn--secondary" disabled>Stop Stream</button>
|
||||
<button id="startDemo" class="btn btn--primary" data-i18n="demo.controls.startStream">Start Stream</button>
|
||||
<button id="stopDemo" class="btn btn--secondary" disabled data-i18n="demo.controls.stopStream">Stop Stream</button>
|
||||
<div class="demo-status">
|
||||
<span class="status status--info" id="demoStatus">Ready</span>
|
||||
<span class="status status--info" id="demoStatus" data-i18n="demo.controls.ready">Ready</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="demo-grid">
|
||||
<div class="signal-panel">
|
||||
<h3>WiFi Signal Analysis</h3>
|
||||
<h3 data-i18n="demo.signal.title">WiFi Signal Analysis</h3>
|
||||
<div class="signal-display">
|
||||
<canvas id="signalCanvas" width="400" height="200"></canvas>
|
||||
</div>
|
||||
<div class="signal-metrics">
|
||||
<div class="metric">
|
||||
<span>Signal Strength:</span>
|
||||
<span data-i18n="demo.signal.signalStrength">Signal Strength:</span>
|
||||
<span id="signalStrength">-45 dBm</span>
|
||||
</div>
|
||||
<div class="metric">
|
||||
<span>Processing Latency:</span>
|
||||
<span data-i18n="demo.signal.processingLatency">Processing Latency:</span>
|
||||
<span id="latency">12 ms</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pose-panel">
|
||||
<h3>Human Pose Detection</h3>
|
||||
<h3 data-i18n="demo.pose.title">Human Pose Detection</h3>
|
||||
<div class="pose-display">
|
||||
<canvas id="poseCanvas" width="400" height="300"></canvas>
|
||||
</div>
|
||||
<div class="detection-info">
|
||||
<div class="info-item">
|
||||
<span>Persons Detected:</span>
|
||||
<span data-i18n="demo.pose.personsDetected">Persons Detected:</span>
|
||||
<span id="personCount">0</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span>Confidence:</span>
|
||||
<span data-i18n="demo.pose.confidence">Confidence:</span>
|
||||
<span id="confidence">0.0%</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span>Keypoints:</span>
|
||||
<span data-i18n="demo.pose.keypoints">Keypoints:</span>
|
||||
<span id="keypoints">0/0</span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -312,7 +316,7 @@
|
|||
|
||||
<!-- Architecture Tab -->
|
||||
<section id="architecture" class="tab-content">
|
||||
<h2>System Architecture</h2>
|
||||
<h2 data-i18n="architecture.title">System Architecture</h2>
|
||||
|
||||
<div class="architecture-flow">
|
||||
<img src="https://pplx-res.cloudinary.com/image/upload/v1748813853/gpt4o_images/m7zztcttnue7vaxclvuw.png"
|
||||
|
|
@ -321,28 +325,28 @@
|
|||
<div class="flow-steps">
|
||||
<div class="step-card" data-step="1">
|
||||
<div class="step-number">1</div>
|
||||
<h3>CSI Input</h3>
|
||||
<p>Channel State Information collected from WiFi antenna array</p>
|
||||
<h3 data-i18n="architecture.steps.csiInput.title">CSI Input</h3>
|
||||
<p data-i18n="architecture.steps.csiInput.description">Channel State Information collected from WiFi antenna array</p>
|
||||
</div>
|
||||
<div class="step-card" data-step="2">
|
||||
<div class="step-number">2</div>
|
||||
<h3>Phase Sanitization</h3>
|
||||
<p>Remove hardware-specific noise and normalize signal phase</p>
|
||||
<h3 data-i18n="architecture.steps.phaseSanitization.title">Phase Sanitization</h3>
|
||||
<p data-i18n="architecture.steps.phaseSanitization.description">Remove hardware-specific noise and normalize signal phase</p>
|
||||
</div>
|
||||
<div class="step-card" data-step="3">
|
||||
<div class="step-number">3</div>
|
||||
<h3>Modality Translation</h3>
|
||||
<p>Convert WiFi signals to visual representation using CNN</p>
|
||||
<h3 data-i18n="architecture.steps.modalityTranslation.title">Modality Translation</h3>
|
||||
<p data-i18n="architecture.steps.modalityTranslation.description">Convert WiFi signals to visual representation using CNN</p>
|
||||
</div>
|
||||
<div class="step-card" data-step="4">
|
||||
<div class="step-number">4</div>
|
||||
<h3>DensePose-RCNN</h3>
|
||||
<p>Extract human pose keypoints and body part segmentation</p>
|
||||
<h3 data-i18n="architecture.steps.densePose.title">DensePose-RCNN</h3>
|
||||
<p data-i18n="architecture.steps.densePose.description">Extract human pose keypoints and body part segmentation</p>
|
||||
</div>
|
||||
<div class="step-card" data-step="5">
|
||||
<div class="step-number">5</div>
|
||||
<h3>Wireframe Output</h3>
|
||||
<p>Generate final human pose wireframe visualization</p>
|
||||
<h3 data-i18n="architecture.steps.wireframeOutput.title">Wireframe Output</h3>
|
||||
<p data-i18n="architecture.steps.wireframeOutput.description">Generate final human pose wireframe visualization</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -350,7 +354,7 @@
|
|||
|
||||
<!-- Performance Tab -->
|
||||
<section id="performance" class="tab-content">
|
||||
<h2>Performance Analysis</h2>
|
||||
<h2 data-i18n="performance.title">Performance Analysis</h2>
|
||||
|
||||
<div class="performance-chart">
|
||||
<img src="https://pplx-res.cloudinary.com/image/upload/v1748813924/pplx_code_interpreter/af6ef268_nsauu6.jpg"
|
||||
|
|
@ -359,60 +363,60 @@
|
|||
|
||||
<div class="performance-grid">
|
||||
<div class="performance-card">
|
||||
<h3>WiFi-based (Same Layout)</h3>
|
||||
<h3 data-i18n="performance.wifiBased.title">WiFi-based (Same Layout)</h3>
|
||||
<div class="metric-list">
|
||||
<div class="metric-item">
|
||||
<span>Average Precision:</span>
|
||||
<span data-i18n="performance.wifiBased.averagePrecision">Average Precision:</span>
|
||||
<span class="metric-value">43.5%</span>
|
||||
</div>
|
||||
<div class="metric-item">
|
||||
<span>AP@50:</span>
|
||||
<span data-i18n="performance.wifiBased.ap50">AP@50:</span>
|
||||
<span class="metric-value success">87.2%</span>
|
||||
</div>
|
||||
<div class="metric-item">
|
||||
<span>AP@75:</span>
|
||||
<span data-i18n="performance.wifiBased.ap75">AP@75:</span>
|
||||
<span class="metric-value">44.6%</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="performance-card">
|
||||
<h3>Image-based (Reference)</h3>
|
||||
<h3 data-i18n="performance.imageBased.title">Image-based (Reference)</h3>
|
||||
<div class="metric-list">
|
||||
<div class="metric-item">
|
||||
<span>Average Precision:</span>
|
||||
<span data-i18n="performance.imageBased.averagePrecision">Average Precision:</span>
|
||||
<span class="metric-value success">84.7%</span>
|
||||
</div>
|
||||
<div class="metric-item">
|
||||
<span>AP@50:</span>
|
||||
<span data-i18n="performance.imageBased.ap50">AP@50:</span>
|
||||
<span class="metric-value success">94.4%</span>
|
||||
</div>
|
||||
<div class="metric-item">
|
||||
<span>AP@75:</span>
|
||||
<span data-i18n="performance.imageBased.ap75">AP@75:</span>
|
||||
<span class="metric-value success">77.1%</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="limitations-section">
|
||||
<h3>Advantages & Limitations</h3>
|
||||
<h3 data-i18n="performance.advantages.title">Advantages & Limitations</h3>
|
||||
<div class="pros-cons">
|
||||
<div class="pros">
|
||||
<h4>Advantages</h4>
|
||||
<h4 data-i18n="performance.advantages.pros.title">Advantages</h4>
|
||||
<ul>
|
||||
<li>Through-wall detection</li>
|
||||
<li>Privacy preserving</li>
|
||||
<li>Lighting independent</li>
|
||||
<li>Low cost hardware</li>
|
||||
<li>Uses existing WiFi</li>
|
||||
<li data-i18n="performance.advantages.pros.items.0">Through-wall detection</li>
|
||||
<li data-i18n="performance.advantages.pros.items.1">Privacy preserving</li>
|
||||
<li data-i18n="performance.advantages.pros.items.2">Lighting independent</li>
|
||||
<li data-i18n="performance.advantages.pros.items.3">Low cost hardware</li>
|
||||
<li data-i18n="performance.advantages.pros.items.4">Uses existing WiFi</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="cons">
|
||||
<h4>Limitations</h4>
|
||||
<h4 data-i18n="performance.advantages.cons.title">Limitations</h4>
|
||||
<ul>
|
||||
<li>Performance drops in different layouts</li>
|
||||
<li>Requires WiFi-compatible devices</li>
|
||||
<li>Training requires synchronized data</li>
|
||||
<li data-i18n="performance.advantages.cons.items.0">Performance drops in different layouts</li>
|
||||
<li data-i18n="performance.advantages.cons.items.1">Requires WiFi-compatible devices</li>
|
||||
<li data-i18n="performance.advantages.cons.items.2">Training requires synchronized data</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -422,68 +426,68 @@
|
|||
|
||||
<!-- Applications Tab -->
|
||||
<section id="applications" class="tab-content">
|
||||
<h2>Real-World Applications</h2>
|
||||
<h2 data-i18n="applications.title">Real-World Applications</h2>
|
||||
|
||||
<div class="applications-grid">
|
||||
<div class="app-card">
|
||||
<div class="app-icon">👴</div>
|
||||
<h3>Elderly Care Monitoring</h3>
|
||||
<p>Monitor elderly individuals for falls or emergencies without invading privacy. Track movement patterns and detect anomalies in daily routines.</p>
|
||||
<h3 data-i18n="applications.elderlyCare.title">Elderly Care Monitoring</h3>
|
||||
<p data-i18n="applications.elderlyCare.description">Monitor elderly individuals for falls or emergencies without invading privacy. Track movement patterns and detect anomalies in daily routines.</p>
|
||||
<div class="app-features">
|
||||
<span class="feature-tag">Fall Detection</span>
|
||||
<span class="feature-tag">Activity Monitoring</span>
|
||||
<span class="feature-tag">Emergency Alert</span>
|
||||
<span class="feature-tag" data-i18n="applications.elderlyCare.features.0">Fall Detection</span>
|
||||
<span class="feature-tag" data-i18n="applications.elderlyCare.features.1">Activity Monitoring</span>
|
||||
<span class="feature-tag" data-i18n="applications.elderlyCare.features.2">Emergency Alert</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="app-card">
|
||||
<div class="app-icon">🏠</div>
|
||||
<h3>Home Security Systems</h3>
|
||||
<p>Detect intruders and monitor home security without visible cameras. Track multiple persons and identify suspicious movement patterns.</p>
|
||||
<h3 data-i18n="applications.homeSecurity.title">Home Security Systems</h3>
|
||||
<p data-i18n="applications.homeSecurity.description">Detect intruders and monitor home security without visible cameras. Track multiple persons and identify suspicious movement patterns.</p>
|
||||
<div class="app-features">
|
||||
<span class="feature-tag">Intrusion Detection</span>
|
||||
<span class="feature-tag">Multi-person Tracking</span>
|
||||
<span class="feature-tag">Invisible Monitoring</span>
|
||||
<span class="feature-tag" data-i18n="applications.homeSecurity.features.0">Intrusion Detection</span>
|
||||
<span class="feature-tag" data-i18n="applications.homeSecurity.features.1">Multi-person Tracking</span>
|
||||
<span class="feature-tag" data-i18n="applications.homeSecurity.features.2">Invisible Monitoring</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="app-card">
|
||||
<div class="app-icon">🏥</div>
|
||||
<h3>Healthcare Patient Monitoring</h3>
|
||||
<p>Monitor patients in hospitals and care facilities. Track vital signs through movement analysis and detect health emergencies.</p>
|
||||
<h3 data-i18n="applications.healthcare.title">Healthcare Patient Monitoring</h3>
|
||||
<p data-i18n="applications.healthcare.description">Monitor patients in hospitals and care facilities. Track vital signs through movement analysis and detect health emergencies.</p>
|
||||
<div class="app-features">
|
||||
<span class="feature-tag">Vital Sign Analysis</span>
|
||||
<span class="feature-tag">Movement Tracking</span>
|
||||
<span class="feature-tag">Health Alerts</span>
|
||||
<span class="feature-tag" data-i18n="applications.healthcare.features.0">Vital Sign Analysis</span>
|
||||
<span class="feature-tag" data-i18n="applications.healthcare.features.1">Movement Tracking</span>
|
||||
<span class="feature-tag" data-i18n="applications.healthcare.features.2">Health Alerts</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="app-card">
|
||||
<div class="app-icon">🏢</div>
|
||||
<h3>Smart Building Occupancy</h3>
|
||||
<p>Optimize building energy consumption by tracking occupancy patterns. Control lighting, HVAC, and security systems automatically.</p>
|
||||
<h3 data-i18n="applications.smartBuilding.title">Smart Building Occupancy</h3>
|
||||
<p data-i18n="applications.smartBuilding.description">Optimize building energy consumption by tracking occupancy patterns. Control lighting, HVAC, and security systems automatically.</p>
|
||||
<div class="app-features">
|
||||
<span class="feature-tag">Energy Optimization</span>
|
||||
<span class="feature-tag">Occupancy Tracking</span>
|
||||
<span class="feature-tag">Smart Controls</span>
|
||||
<span class="feature-tag" data-i18n="applications.smartBuilding.features.0">Energy Optimization</span>
|
||||
<span class="feature-tag" data-i18n="applications.smartBuilding.features.1">Occupancy Tracking</span>
|
||||
<span class="feature-tag" data-i18n="applications.smartBuilding.features.2">Smart Controls</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="app-card">
|
||||
<div class="app-icon">🥽</div>
|
||||
<h3>AR/VR Applications</h3>
|
||||
<p>Enable full-body tracking for virtual and augmented reality applications without wearing additional sensors or cameras.</p>
|
||||
<h3 data-i18n="applications.arVr.title">AR/VR Applications</h3>
|
||||
<p data-i18n="applications.arVr.description">Enable full-body tracking for virtual and augmented reality applications without wearing additional sensors or cameras.</p>
|
||||
<div class="app-features">
|
||||
<span class="feature-tag">Full Body Tracking</span>
|
||||
<span class="feature-tag">Sensor-free</span>
|
||||
<span class="feature-tag">Immersive Experience</span>
|
||||
<span class="feature-tag" data-i18n="applications.arVr.features.0">Full Body Tracking</span>
|
||||
<span class="feature-tag" data-i18n="applications.arVr.features.1">Sensor-free</span>
|
||||
<span class="feature-tag" data-i18n="applications.arVr.features.2">Immersive Experience</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="implementation-note">
|
||||
<h3>Implementation Considerations</h3>
|
||||
<p>While WiFi DensePose offers revolutionary capabilities, successful implementation requires careful consideration of environment setup, data privacy regulations, and system calibration for optimal performance.</p>
|
||||
<h3 data-i18n="applications.implementation.title">Implementation Considerations</h3>
|
||||
<p data-i18n="applications.implementation.description">While WiFi DensePose offers revolutionary capabilities, successful implementation requires careful consideration of environment setup, data privacy regulations, and system calibration for optimal performance.</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
|
@ -493,8 +497,8 @@
|
|||
<!-- Training Tab -->
|
||||
<section id="training" class="tab-content">
|
||||
<div class="tab-header">
|
||||
<h2>Model Training</h2>
|
||||
<p>Record CSI data, train pose estimation models, and manage .rvf files</p>
|
||||
<h2 data-i18n="training.title">Model Training</h2>
|
||||
<p data-i18n="training.description">Record CSI data, train pose estimation models, and manage .rvf files</p>
|
||||
</div>
|
||||
<div id="training-container" style="display: flex; gap: 20px; flex-wrap: wrap;">
|
||||
<div id="training-panel-container" style="flex: 1; min-width: 400px;"></div>
|
||||
|
|
|
|||
38
ui/style.css
38
ui/style.css
|
|
@ -1409,6 +1409,7 @@ canvas {
|
|||
justify-content: center;
|
||||
margin-top: var(--space-16);
|
||||
font-size: var(--font-size-sm);
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.api-version,
|
||||
|
|
@ -2424,3 +2425,40 @@ canvas {
|
|||
.pose-trail-btn:hover {
|
||||
background: rgba(var(--color-primary-rgb), 0.2);
|
||||
}
|
||||
|
||||
/* Language Selector */
|
||||
.language-selector {
|
||||
padding: var(--space-4) var(--space-12);
|
||||
padding-right: var(--space-28);
|
||||
border-radius: var(--radius-base);
|
||||
font-size: var(--font-size-sm);
|
||||
font-weight: var(--font-weight-medium);
|
||||
cursor: pointer;
|
||||
background-color: var(--color-surface);
|
||||
border: 1px solid var(--color-border);
|
||||
color: var(--color-text);
|
||||
appearance: none;
|
||||
background-image: var(--select-caret-light);
|
||||
background-repeat: no-repeat;
|
||||
background-position: right var(--space-8) center;
|
||||
background-size: 12px;
|
||||
transition: all 0.2s ease;
|
||||
min-width: 100px;
|
||||
}
|
||||
|
||||
.language-selector:hover {
|
||||
border-color: var(--color-primary);
|
||||
background-color: var(--color-secondary-hover);
|
||||
}
|
||||
|
||||
.language-selector:focus {
|
||||
outline: none;
|
||||
box-shadow: var(--focus-ring);
|
||||
border-color: var(--color-primary);
|
||||
}
|
||||
|
||||
.language-selector option {
|
||||
padding: var(--space-8);
|
||||
background-color: var(--color-surface);
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue