-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathstream_classify.py
More file actions
154 lines (123 loc) Β· 5.97 KB
/
Copy pathstream_classify.py
File metadata and controls
154 lines (123 loc) Β· 5.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#!/usr/bin/env python3
"""
Real-time Metal Detector Audio Classification
Stream live audio from metal detectors and classify patterns in real-time
using advanced machine learning models.
Usage:
python stream_classify.py --device 0 --duration 60
python stream_classify.py --list-devices
python stream_classify.py --help
"""
import argparse
import sys
from pathlib import Path
import time
from rich.console import Console
from rich.table import Table
from rich.panel import Panel
from src.audio.streaming import RealTimeMetalDetector, StreamingConfig, list_audio_devices
console = Console()
def main():
"""Main real-time classification function."""
parser = argparse.ArgumentParser(description="Real-time metal detector audio classification")
parser.add_argument("--device", type=int, help="Audio input device ID")
parser.add_argument("--list-devices", action="store_true", help="List available audio devices")
parser.add_argument("--duration", type=float, default=60.0, help="Recording duration in seconds")
parser.add_argument("--confidence-threshold", type=float, default=0.7, help="Confidence threshold for detection")
parser.add_argument("--classification-interval", type=float, default=2.0, help="Seconds between classifications")
parser.add_argument("--save-detections", type=str, help="Directory to save detected patterns")
parser.add_argument("--model-dir", type=str, default="models/advanced", help="Model directory")
parser.add_argument("--no-visualization", action="store_true", help="Disable real-time visualization")
args = parser.parse_args()
# List devices if requested
if args.list_devices:
devices = list_audio_devices()
console.print("π€ Available Audio Input Devices:", style="bold")
if not devices:
console.print("β No audio input devices found!")
return
table = Table()
table.add_column("ID", style="cyan")
table.add_column("Device Name", style="green")
table.add_column("Channels", style="yellow")
table.add_column("Sample Rate", style="blue")
for device in devices:
table.add_row(
str(device['id']),
device['name'],
str(device['channels']),
f"{device['sample_rate']:.0f} Hz"
)
console.print(table)
return
# Initialize streaming configuration
config = StreamingConfig(
device_id=args.device,
confidence_threshold=args.confidence_threshold,
classification_interval=args.classification_interval
)
model_dir = Path(args.model_dir)
console.print(Panel.fit("π Real-time Metal Detector AI", style="bold blue"))
# Initialize classifier
try:
detector = RealTimeMetalDetector(config=config, model_path=model_dir)
except Exception as e:
console.print(f"β Error initializing detector: {e}", style="red")
return
# Check if models exist
if not detector.classifier.is_ready():
console.print("β No trained models found!")
console.print("π‘ Train models first using: python train_model.py")
return
# Display configuration
console.print(f"π€ Audio Device: {args.device or 'default'}")
console.print(f"β±οΈ Duration: {args.duration} seconds")
console.print(f"π― Classification Interval: {args.classification_interval}s")
console.print(f"π₯ Confidence Threshold: {args.confidence_threshold}")
console.print(f"π Model Directory: {model_dir}")
# Start streaming
try:
detector.start_streaming(visualize=not args.no_visualization)
if args.no_visualization:
console.print(f"π€ Streaming started... Running for {args.duration} seconds")
console.print("Press Ctrl+C to stop early")
# Run for specified duration
time.sleep(args.duration)
except KeyboardInterrupt:
console.print("\nβΉοΈ Stopped by user", style="yellow")
except Exception as e:
console.print(f"β Error during streaming: {e}", style="red")
finally:
detector.stop_streaming()
# Show final statistics
stats = detector.get_detection_summary()
console.print("\nπ Final Session Statistics:", style="bold")
console.print(f"Total detections: {stats['total_detections']}")
console.print(f"High confidence: {stats.get('high_confidence_detections', 0)}")
console.print(f"Average confidence: {stats.get('average_confidence', 0):.3f}")
console.print(f"Session duration: {stats.get('session_duration', 0):.1f}s")
# Show label distribution
if 'label_distribution' in stats and stats['label_distribution']:
console.print("\nπ·οΈ Label Distribution:")
label_table = Table()
label_table.add_column("Label", style="cyan")
label_table.add_column("Count", style="magenta")
label_table.add_column("Percentage", style="yellow")
total_labels = sum(stats['label_distribution'].values())
for label, count in sorted(stats['label_distribution'].items(), key=lambda x: x[1], reverse=True):
percentage = (count / total_labels) * 100 if total_labels > 0 else 0
label_table.add_row(
label.title(),
str(count),
f"{percentage:.1f}%"
)
console.print(label_table)
# Save detections if requested
if args.save_detections:
output_path = Path(args.save_detections)
output_path.mkdir(parents=True, exist_ok=True)
session_file = output_path / f"session_{int(time.time())}.json"
detector.save_session(session_file)
console.print(f"πΎ Session data saved to: {session_file}")
if __name__ == "__main__":
main()