Better eye debuging visualisation (zoom)
This commit is contained in:
parent
b3883bd45c
commit
853ec49d35
2 changed files with 187 additions and 51 deletions
|
|
@ -105,11 +105,116 @@ fn get_char_pattern(ch: char) -> [u8; 7] {
|
|||
'°' => [
|
||||
0b00110, 0b01001, 0b01001, 0b00110, 0b00000, 0b00000, 0b00000,
|
||||
],
|
||||
'C' => [
|
||||
0b01110, 0b10001, 0b10000, 0b10000, 0b10000, 0b10001, 0b01110,
|
||||
],
|
||||
'D' => [
|
||||
0b11100, 0b10010, 0b10001, 0b10001, 0b10001, 0b10010, 0b11100,
|
||||
],
|
||||
'F' => [
|
||||
0b11111, 0b10000, 0b10000, 0b11110, 0b10000, 0b10000, 0b10000,
|
||||
],
|
||||
'G' => [
|
||||
0b01110, 0b10001, 0b10000, 0b10111, 0b10001, 0b10001, 0b01110,
|
||||
],
|
||||
'I' => [
|
||||
0b01110, 0b00100, 0b00100, 0b00100, 0b00100, 0b00100, 0b01110,
|
||||
],
|
||||
'M' => [
|
||||
0b10001, 0b11011, 0b10101, 0b10101, 0b10001, 0b10001, 0b10001,
|
||||
],
|
||||
'N' => [
|
||||
0b10001, 0b11001, 0b10101, 0b10011, 0b10001, 0b10001, 0b10001,
|
||||
],
|
||||
'O' => [
|
||||
0b01110, 0b10001, 0b10001, 0b10001, 0b10001, 0b10001, 0b01110,
|
||||
],
|
||||
'S' => [
|
||||
0b01110, 0b10001, 0b10000, 0b01110, 0b00001, 0b10001, 0b01110,
|
||||
],
|
||||
'T' => [
|
||||
0b11111, 0b00100, 0b00100, 0b00100, 0b00100, 0b00100, 0b00100,
|
||||
],
|
||||
'a' => [
|
||||
0b00000, 0b00000, 0b01110, 0b00001, 0b01111, 0b10001, 0b01111,
|
||||
],
|
||||
'b' => [
|
||||
0b10000, 0b10000, 0b10110, 0b11001, 0b10001, 0b10001, 0b11110,
|
||||
],
|
||||
'c' => [
|
||||
0b00000, 0b00000, 0b01110, 0b10000, 0b10000, 0b10001, 0b01110,
|
||||
],
|
||||
'd' => [
|
||||
0b00001, 0b00001, 0b01101, 0b10011, 0b10001, 0b10001, 0b01111,
|
||||
],
|
||||
'e' => [
|
||||
0b00000, 0b00000, 0b01110, 0b10001, 0b11111, 0b10000, 0b01110,
|
||||
],
|
||||
'f' => [
|
||||
0b00110, 0b01001, 0b01000, 0b11100, 0b01000, 0b01000, 0b01000,
|
||||
],
|
||||
'g' => [
|
||||
0b00000, 0b01111, 0b10001, 0b10001, 0b01111, 0b00001, 0b01110,
|
||||
],
|
||||
'h' => [
|
||||
0b10000, 0b10000, 0b10110, 0b11001, 0b10001, 0b10001, 0b10001,
|
||||
],
|
||||
'i' => [
|
||||
0b00100, 0b00000, 0b01100, 0b00100, 0b00100, 0b00100, 0b01110,
|
||||
],
|
||||
'k' => [
|
||||
0b10000, 0b10000, 0b10010, 0b10100, 0b11000, 0b10100, 0b10010,
|
||||
],
|
||||
'l' => [
|
||||
0b01100, 0b00100, 0b00100, 0b00100, 0b00100, 0b00100, 0b01110,
|
||||
],
|
||||
'm' => [
|
||||
0b00000, 0b00000, 0b11010, 0b10101, 0b10101, 0b10001, 0b10001,
|
||||
],
|
||||
'n' => [
|
||||
0b00000, 0b00000, 0b10110, 0b11001, 0b10001, 0b10001, 0b10001,
|
||||
],
|
||||
'o' => [
|
||||
0b00000, 0b00000, 0b01110, 0b10001, 0b10001, 0b10001, 0b01110,
|
||||
],
|
||||
'p' => [
|
||||
0b00000, 0b00000, 0b11110, 0b10001, 0b11110, 0b10000, 0b10000,
|
||||
],
|
||||
'r' => [
|
||||
0b00000, 0b00000, 0b10110, 0b11001, 0b10000, 0b10000, 0b10000,
|
||||
],
|
||||
's' => [
|
||||
0b00000, 0b00000, 0b01110, 0b10000, 0b01110, 0b00001, 0b11110,
|
||||
],
|
||||
't' => [
|
||||
0b01000, 0b01000, 0b11100, 0b01000, 0b01000, 0b01001, 0b00110,
|
||||
],
|
||||
'u' => [
|
||||
0b00000, 0b00000, 0b10001, 0b10001, 0b10001, 0b10011, 0b01101,
|
||||
],
|
||||
'v' => [
|
||||
0b00000, 0b00000, 0b10001, 0b10001, 0b10001, 0b01010, 0b00100,
|
||||
],
|
||||
'w' => [
|
||||
0b00000, 0b00000, 0b10001, 0b10001, 0b10101, 0b10101, 0b01010,
|
||||
],
|
||||
'x' => [
|
||||
0b00000, 0b00000, 0b10001, 0b01010, 0b00100, 0b01010, 0b10001,
|
||||
],
|
||||
'y' => [
|
||||
0b00000, 0b00000, 0b10001, 0b10001, 0b01111, 0b00001, 0b01110,
|
||||
],
|
||||
'z' => [
|
||||
0b00000, 0b00000, 0b11111, 0b00010, 0b00100, 0b01000, 0b11111,
|
||||
],
|
||||
'+' => [
|
||||
0b00000, 0b00100, 0b00100, 0b11111, 0b00100, 0b00100, 0b00000,
|
||||
],
|
||||
' ' => [
|
||||
0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000,
|
||||
],
|
||||
_ => [
|
||||
0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000,
|
||||
0b01010, 0b00000, 0b01010, 0b00000, 0b01010, 0b00000, 0b01010,
|
||||
],
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -81,68 +81,99 @@ impl ProcessingStep for EyeFilterStep {
|
|||
// Get the current image to draw on
|
||||
let image = ctx.image.as_ref()?;
|
||||
let rgb = image.to_rgb8();
|
||||
let (width, height) = (rgb.width(), rgb.height());
|
||||
let (img_w, img_h) = (rgb.width(), rgb.height());
|
||||
|
||||
// Create a copy for visualization
|
||||
let mut debug_img = rgb.clone();
|
||||
|
||||
// Draw eye landmarks (points 36-47)
|
||||
let points = landmarks.points();
|
||||
|
||||
// Left eye (points 36-41) - yellow or red depending on EAR
|
||||
let left_color = if ear.left >= 0.2 {
|
||||
Rgb([0, 255, 0]) // Green - open
|
||||
} else {
|
||||
Rgb([255, 0, 0]) // Red - closed
|
||||
};
|
||||
|
||||
for point in points.iter().skip(36).take(6) {
|
||||
draw_cross(&mut debug_img, point.x as u32, point.y as u32, left_color);
|
||||
}
|
||||
|
||||
// Right eye (points 42-47)
|
||||
let right_color = if ear.right >= 0.2 {
|
||||
Rgb([0, 255, 0]) // Green - open
|
||||
} else {
|
||||
Rgb([255, 0, 0]) // Red - closed
|
||||
};
|
||||
|
||||
for point in points.iter().skip(42).take(6) {
|
||||
draw_cross(&mut debug_img, point.x as u32, point.y as u32, right_color);
|
||||
}
|
||||
|
||||
// Draw eye centers
|
||||
// Compute eye centers and bounding box for cropping
|
||||
let left_eye = landmarks.left_eye_center();
|
||||
let right_eye = landmarks.right_eye_center();
|
||||
draw_marker(
|
||||
&mut debug_img,
|
||||
left_eye.x as u32,
|
||||
left_eye.y as u32,
|
||||
Rgb([0, 255, 255]),
|
||||
);
|
||||
draw_marker(
|
||||
&mut debug_img,
|
||||
right_eye.x as u32,
|
||||
right_eye.y as u32,
|
||||
Rgb([0, 255, 255]),
|
||||
);
|
||||
let eye_dist =
|
||||
((right_eye.x - left_eye.x).powi(2) + (right_eye.y - left_eye.y).powi(2)).sqrt();
|
||||
let padding = eye_dist * 0.8;
|
||||
let center_x = (left_eye.x + right_eye.x) / 2.0;
|
||||
let center_y = (left_eye.y + right_eye.y) / 2.0;
|
||||
|
||||
let crop_x = (center_x - eye_dist / 2.0 - padding).max(0.0) as u32;
|
||||
let crop_y = (center_y - padding).max(0.0) as u32;
|
||||
let crop_w = ((eye_dist + padding * 2.0) as u32).min(img_w.saturating_sub(crop_x));
|
||||
let crop_h = ((padding * 2.0) as u32).min(img_h.saturating_sub(crop_y));
|
||||
|
||||
if crop_w == 0 || crop_h == 0 {
|
||||
return Some(DynamicImage::ImageRgb8(rgb));
|
||||
}
|
||||
|
||||
// Crop first, then scale up
|
||||
let cropped = DynamicImage::ImageRgb8(rgb).crop_imm(crop_x, crop_y, crop_w, crop_h);
|
||||
|
||||
let scale = img_w as f64 / crop_w as f64;
|
||||
let scaled_w = img_w;
|
||||
let scaled_h = (crop_h as f64 * scale) as u32;
|
||||
let mut zoomed = cropped
|
||||
.resize_exact(scaled_w, scaled_h, image::imageops::FilterType::Lanczos3)
|
||||
.to_rgb8();
|
||||
|
||||
// Draw landmarks on the zoomed image (coordinates transformed to zoomed space)
|
||||
let points = landmarks.points();
|
||||
|
||||
let left_color = if ear.left >= 0.2 {
|
||||
Rgb([0, 255, 0])
|
||||
} else {
|
||||
Rgb([255, 0, 0])
|
||||
};
|
||||
let right_color = if ear.right >= 0.2 {
|
||||
Rgb([0, 255, 0])
|
||||
} else {
|
||||
Rgb([255, 0, 0])
|
||||
};
|
||||
|
||||
// Left eye landmarks (points 36-41)
|
||||
for point in points.iter().skip(36).take(6) {
|
||||
let x = ((point.x as f64 - crop_x as f64) * scale) as u32;
|
||||
let y = ((point.y as f64 - crop_y as f64) * scale) as u32;
|
||||
draw_cross(&mut zoomed, x, y, left_color);
|
||||
}
|
||||
|
||||
// Right eye landmarks (points 42-47)
|
||||
for point in points.iter().skip(42).take(6) {
|
||||
let x = ((point.x as f64 - crop_x as f64) * scale) as u32;
|
||||
let y = ((point.y as f64 - crop_y as f64) * scale) as u32;
|
||||
draw_cross(&mut zoomed, x, y, right_color);
|
||||
}
|
||||
|
||||
// Eye centers
|
||||
let lx = ((left_eye.x as f64 - crop_x as f64) * scale) as u32;
|
||||
let ly = ((left_eye.y as f64 - crop_y as f64) * scale) as u32;
|
||||
let rx = ((right_eye.x as f64 - crop_x as f64) * scale) as u32;
|
||||
let ry = ((right_eye.y as f64 - crop_y as f64) * scale) as u32;
|
||||
draw_marker(&mut zoomed, lx, ly, Rgb([0, 255, 255]));
|
||||
draw_marker(&mut zoomed, rx, ry, Rgb([0, 255, 255]));
|
||||
|
||||
// Draw info bar at bottom
|
||||
let bar_height = 20u32;
|
||||
let bar_y = height.saturating_sub(bar_height);
|
||||
let total_h = scaled_h + bar_height;
|
||||
let mut final_img = RgbImage::new(scaled_w, total_h);
|
||||
|
||||
// Draw background
|
||||
for y in bar_y..height {
|
||||
for x in 0..width {
|
||||
debug_img.put_pixel(x, y, Rgb([0, 0, 0]));
|
||||
// Copy zoomed image
|
||||
for y in 0..scaled_h {
|
||||
for x in 0..scaled_w {
|
||||
final_img.put_pixel(x, y, *zoomed.get_pixel(x, y));
|
||||
}
|
||||
}
|
||||
|
||||
// Draw black bar
|
||||
for y in scaled_h..total_h {
|
||||
for x in 0..scaled_w {
|
||||
final_img.put_pixel(x, y, Rgb([0, 0, 0]));
|
||||
}
|
||||
}
|
||||
|
||||
// Draw EAR values
|
||||
let text = format!("L:{:.2} R:{:.2} Avg:{:.2}", ear.left, ear.right, avg_ear);
|
||||
draw_simple_text(&mut debug_img, 5, bar_y + 6, &text, Rgb([255, 255, 255]));
|
||||
let text = format!(
|
||||
"Left:{:.2} Right:{:.2} Average:{:.2}",
|
||||
ear.left, ear.right, avg_ear
|
||||
);
|
||||
draw_simple_text(&mut final_img, 5, scaled_h + 6, &text, Rgb([255, 255, 255]));
|
||||
|
||||
Some(DynamicImage::ImageRgb8(debug_img))
|
||||
Some(DynamicImage::ImageRgb8(final_img))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue