Skip to content

Commit 955f4e3

Browse files
author
richardson
committed
可以控制舵机,可以控制摄像头,但是无法在主界面显示摄像头画面
1 parent 4723315 commit 955f4e3

File tree

5 files changed

+66
-310
lines changed

5 files changed

+66
-310
lines changed

src-tauri/Cargo.lock

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src-tauri/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ tokio = { version = "1.12", features = ["macros", "rt-multi-thread"] }
2121
serialport = "4.2.0"
2222
nokhwa = { version = "0.10.5", features = ["input-avfoundation"] }
2323
rustface = "0.1"
24+
parking_lot = "0.12"
2425

2526
[features]
2627
# This feature is used for production builds or when a dev server is not specified, DO NOT REMOVE!!

src-tauri/src/camera_controller.rs

+21-215
Original file line numberDiff line numberDiff line change
@@ -1,230 +1,36 @@
1-
use nokhwa::{Camera, utils::{CameraInfo, CameraIndex, CameraFormat, FrameFormat, RequestedFormat, RequestedFormatType, ApiBackend}, pixel_format::RgbFormat};
2-
use rustface::{ImageData, Detector, FaceInfo};
3-
use std::sync::{Arc, Mutex};
4-
use tokio::time::{interval, Duration};
1+
use nokhwa::{Camera, utils::{CameraInfo, ApiBackend}};
2+
use std::sync::{Arc};
53
use crate::commands::log_message;
6-
7-
pub struct ThreadSafeCamera(Arc<Mutex<Camera>>);
8-
9-
impl ThreadSafeCamera {
10-
pub fn new(index: CameraIndex, format: RequestedFormat) -> Result<Self, nokhwa::NokhwaError> {
11-
let camera = Camera::new(index, format)?;
12-
Ok(ThreadSafeCamera(Arc::new(Mutex::new(camera))))
13-
}
14-
15-
pub fn frame(&self) -> Result<nokhwa::Buffer, nokhwa::NokhwaError> {
16-
let mut camera = self.0.lock().unwrap();
17-
camera.frame()
18-
}
19-
20-
pub fn open_stream(&self) -> Result<(), nokhwa::NokhwaError> {
21-
let mut camera = self.0.lock().unwrap();
22-
camera.open_stream()
23-
}
24-
}
25-
26-
unsafe impl Send for ThreadSafeCamera {}
27-
unsafe impl Sync for ThreadSafeCamera {}
28-
29-
pub struct ThreadSafeDetector(Arc<Mutex<Box<dyn Detector + Send>>>);
30-
31-
impl ThreadSafeDetector {
32-
pub fn new(detector: Box<dyn Detector + Send>) -> Self {
33-
ThreadSafeDetector(Arc::new(Mutex::new(detector)))
34-
}
35-
36-
pub fn detect(&self, image: &ImageData) -> Vec<FaceInfo> {
37-
let mut detector = self.0.lock().unwrap();
38-
detector.detect(image)
39-
}
40-
}
41-
42-
unsafe impl Send for ThreadSafeDetector {}
43-
unsafe impl Sync for ThreadSafeDetector {}
4+
use parking_lot::Mutex as PLMutex;
445

456
pub struct CameraController {
46-
camera: ThreadSafeCamera,
47-
camera_active: Arc<Mutex<bool>>,
48-
face_position: Arc<Mutex<Option<(f64, f64)>>>,
49-
selected_camera_index: Arc<Mutex<Option<usize>>>,
50-
detector: ThreadSafeDetector,
7+
camera: Arc<PLMutex<Option<Camera>>>,
8+
selected_camera_index: Arc<PLMutex<Option<usize>>>,
519
}
5210

11+
// 实现 Send 和 Sync
12+
unsafe impl Send for CameraController {}
13+
unsafe impl Sync for CameraController {}
14+
5315
impl CameraController {
54-
pub fn new() -> Result<Self, Box<dyn std::error::Error>> {
55-
log_message("Creating new CameraController instance".to_string(), "INFO".to_string(), "CameraController".to_string());
56-
57-
let detector = rustface::create_detector("model/seeta_fd_frontal_v1.0.bin")
58-
.map_err(|e| Box::new(e) as Box<dyn std::error::Error>)?;
59-
60-
let detector = ThreadSafeDetector::new(Box::new(SendableDetector(detector)));
61-
62-
let camera = ThreadSafeCamera::new(
63-
CameraIndex::Index(0),
64-
RequestedFormat::new::<RgbFormat>(RequestedFormatType::Exact(
65-
CameraFormat::new_from(640, 480, FrameFormat::MJPEG, 30)
66-
))
67-
)?;
68-
69-
Ok(CameraController {
70-
camera,
71-
camera_active: Arc::new(Mutex::new(false)),
72-
face_position: Arc::new(Mutex::new(None)),
73-
selected_camera_index: Arc::new(Mutex::new(Some(0))),
74-
detector,
75-
})
16+
pub fn new() -> Self {
17+
log_message("Creating new CameraController instance".to_string(), "INFO".to_string(), "CameraController".to_string());
18+
19+
CameraController {
20+
camera: Arc::new(PLMutex::new(None)),
21+
selected_camera_index: Arc::new(PLMutex::new(None)),
7622
}
77-
23+
}
7824

7925
pub fn get_available_cameras() -> Vec<CameraInfo> {
80-
log_message("Querying available cameras...".to_string(), "INFO".to_string(), "CameraController.get_available_cameras".to_string());
81-
26+
log_message("Querying available cameras...".to_string(), "INFO".to_string(), "get_available_cameras".to_string());
27+
8228
let backends = vec![ApiBackend::AVFoundation, ApiBackend::Auto];
83-
8429
for backend in backends {
85-
log_message(format!("Trying backend: {:?}", backend), "INFO".to_string(), "CameraController.get_available_cameras".to_string());
86-
match nokhwa::query(backend) {
87-
Ok(cameras) => {
88-
log_message(format!("Found {} cameras using {:?} backend", cameras.len(), backend), "INFO".to_string(), "CameraController.get_available_cameras".to_string());
89-
for (i, camera) in cameras.iter().enumerate() {
90-
log_message(format!("Camera {}: {:?}", i, camera), "INFO".to_string(), "CameraController.get_available_cameras".to_string());
91-
}
92-
return cameras;
93-
},
94-
Err(e) => {
95-
log_message(format!("Failed to query cameras with {:?} backend: {}", backend, e), "WARN".to_string(), "CameraController.get_available_cameras".to_string());
96-
}
30+
if let Ok(cameras) = nokhwa::query(backend) {
31+
return cameras;
9732
}
9833
}
99-
100-
log_message("No cameras found with any backend".to_string(), "ERROR".to_string(), "CameraController".to_string());
10134
Vec::new()
10235
}
103-
104-
pub fn select_camera(&mut self, index: usize) -> Result<(), nokhwa::NokhwaError> {
105-
let mut selected_camera = self.selected_camera_index.lock().unwrap();
106-
*selected_camera = Some(index);
107-
log_message(format!("Selected camera with index: {}", index), "INFO".to_string(), "CameraController".to_string());
108-
109-
// Reinitialize the camera with the new index
110-
self.camera = ThreadSafeCamera::new(
111-
CameraIndex::Index(index as u32),
112-
RequestedFormat::new::<RgbFormat>(RequestedFormatType::Exact(
113-
CameraFormat::new_from(640, 480, FrameFormat::MJPEG, 30)
114-
))
115-
)?;
116-
117-
Ok(())
118-
}
119-
120-
pub async fn toggle_camera(&mut self, active: bool) -> Result<()> {
121-
{
122-
let mut camera_active = self.camera_active.lock().unwrap();
123-
*camera_active = active;
124-
}
125-
log_message(format!("Camera toggled to {}", active), "INFO".to_string(), "CameraController.toggle_camera".to_string());
126-
127-
if active {
128-
self.run().await;
129-
}
130-
}
131-
132-
pub fn get_face_position(&self) -> Option<(f64, f64)> {
133-
let face_position = self.face_position.lock().unwrap();
134-
*face_position
135-
}
136-
137-
pub async fn run(&self) {
138-
log_message("Starting camera controller".to_string(), "INFO".to_string(), "CameraController.run".to_string());
139-
140-
if let Err(e) = self.camera.open_stream() {
141-
log_message(format!("Failed to open camera stream: {}", e), "ERROR".to_string(), "CameraController.run".to_string());
142-
return;
143-
}
144-
145-
let mut interval = interval(Duration::from_millis(33)); // ~30 fps
146-
147-
loop {
148-
interval.tick().await;
149-
150-
if !*self.camera_active.lock().unwrap() {
151-
continue;
152-
}
153-
154-
let frame = match self.camera.frame() {
155-
Ok(f) => f,
156-
Err(e) => {
157-
log_message(format!("Failed to capture frame: {}", e), "ERROR".to_string(), "CameraController.run".to_string());
158-
continue;
159-
}
160-
};
161-
162-
let image = frame.buffer();
163-
let width = frame.resolution().width() as i32;
164-
let height = frame.resolution().height() as i32;
165-
let image_data = ImageData::new(image, width as u32, height as u32);
166-
167-
if let Some(face) = self.detector.detect(&image_data).into_iter().next() {
168-
let center_x = (face.bbox().x() + face.bbox().width() as i32 / 2) as f64 / width as f64;
169-
let center_y = (face.bbox().y() + face.bbox().height() as i32 / 2) as f64 / height as f64;
170-
171-
let mut face_position = self.face_position.lock().unwrap();
172-
*face_position = Some((center_x, center_y));
173-
log_message(format!("Face detected at position: ({:.2}, {:.2})", center_x, center_y), "INFO".to_string(), "CameraController.run".to_string());
174-
} else {
175-
let mut face_position = self.face_position.lock().unwrap();
176-
if face_position.is_some() {
177-
*face_position = None;
178-
log_message("Face lost".to_string(), "INFO".to_string(), "CameraController.run".to_string());
179-
}
180-
}
181-
}
182-
}
183-
}
184-
185-
impl Clone for CameraController {
186-
fn clone(&self) -> Self {
187-
CameraController {
188-
camera: ThreadSafeCamera(Arc::clone(&self.camera.0)),
189-
camera_active: Arc::clone(&self.camera_active),
190-
face_position: Arc::clone(&self.face_position),
191-
selected_camera_index: Arc::clone(&self.selected_camera_index),
192-
detector: ThreadSafeDetector(Arc::clone(&self.detector.0)),
193-
}
194-
}
195-
}
196-
197-
198-
struct SendableDetector(Box<dyn Detector>);
199-
200-
impl Detector for SendableDetector {
201-
fn detect(&mut self, image: &ImageData) -> Vec<FaceInfo> {
202-
self.0.detect(image)
203-
}
204-
205-
fn set_window_size(&mut self, size: u32) {
206-
self.0.set_window_size(size)
207-
}
208-
209-
fn set_slide_window_step(&mut self, step_x: u32, step_y: u32) {
210-
self.0.set_slide_window_step(step_x, step_y)
211-
}
212-
213-
fn set_min_face_size(&mut self, size: u32) {
214-
self.0.set_min_face_size(size)
215-
}
216-
217-
fn set_max_face_size(&mut self, size: u32) {
218-
self.0.set_max_face_size(size)
219-
}
220-
221-
fn set_pyramid_scale_factor(&mut self, factor: f32) {
222-
self.0.set_pyramid_scale_factor(factor)
223-
}
224-
225-
fn set_score_thresh(&mut self, thresh: f64) {
226-
self.0.set_score_thresh(thresh)
227-
}
228-
}
229-
230-
unsafe impl Send for SendableDetector {}
36+
}

0 commit comments

Comments
 (0)