app
AI Flow: Reverse Engineering
Public Made by Adomby adom
Photos of a PCB to a tagged KiCad copy: parts placed, copper and nets with their evidence, a schematic, a measured confidence score, bench tests and a video of the run.
main
Caleb
Add the Rust source, flow definition, assets and install scripts
cf9809b
//! Overlays drawn onto evidence images, so every measurement can be checked by eye.
use image::{Rgb, RgbImage};
pub fn px(img: &mut RgbImage, x: i64, y: i64, c: [u8; 3]) {
if x >= 0 && y >= 0 && (x as u32) < img.width() && (y as u32) < img.height() { img.put_pixel(x as u32, y as u32, Rgb(c)); }
}
pub fn line(img: &mut RgbImage, a: (f64, f64), b: (f64, f64), c: [u8; 3], th: i64) {
let n = ((b.0 - a.0).abs().max((b.1 - a.1).abs()) as i64).max(1);
for i in 0..=n {
let t = i as f64 / n as f64;
let (x, y) = ((a.0 + (b.0 - a.0) * t) as i64, (a.1 + (b.1 - a.1) * t) as i64);
for dy in -th / 2..=th / 2 { for dx in -th / 2..=th / 2 { px(img, x + dx, y + dy, c); } }
}
}
pub fn poly(img: &mut RgbImage, p: &[(f64, f64)], c: [u8; 3], th: i64) {
for i in 0..p.len() { line(img, p[i], p[(i + 1) % p.len()], c, th); }
}
pub fn circle(img: &mut RgbImage, ctr: (f64, f64), r: f64, c: [u8; 3], th: i64) {
let n = ((r * 6.3) as usize).max(16);
let pts: Vec<(f64, f64)> = (0..n).map(|i| { let a = i as f64 / n as f64 * std::f64::consts::TAU; (ctr.0 + r * a.cos(), ctr.1 + r * a.sin()) }).collect();
poly(img, &pts, c, th);
}
/// Tint the pixels of a mask.
pub fn tint(img: &mut RgbImage, m: &crate::raster::Mask, c: [u8; 3], a: f32) {
for (i, p) in img.pixels_mut().enumerate() {
if m.d[i] { for k in 0..3 { p[k] = (p[k] as f32 * (1.0 - a) + c[k] as f32 * a) as u8; } }
}
}
/// A tiny 3x5 digit font for labels (ids are letters + digits; letters map to a block).
const DIG: [[u8; 5]; 10] = [[7, 5, 5, 5, 7], [2, 6, 2, 2, 7], [7, 1, 7, 4, 7], [7, 1, 7, 1, 7], [5, 5, 7, 1, 1], [7, 4, 7, 1, 7], [7, 4, 7, 5, 7], [7, 1, 1, 1, 1], [7, 5, 7, 5, 7], [7, 5, 7, 1, 7]];
pub fn label(img: &mut RgbImage, at: (f64, f64), text: &str, c: [u8; 3], scale: i64) {
let (mut x, y) = (at.0 as i64, at.1 as i64);
for ch in text.chars() {
let g = ch.to_digit(10).map(|d| DIG[d as usize]).unwrap_or([7, 7, 7, 7, 7]);
if ch.is_ascii_digit() || ch.is_ascii_alphabetic() {
for (r, bits) in g.iter().enumerate() { for col in 0..3 {
if bits >> (2 - col) & 1 == 1 && (ch.is_ascii_digit() || r == 0 || r == 4 || col == 0) {
for dy in 0..scale { for dx in 0..scale { px(img, x + col * scale + dx, y + r as i64 * scale + dy, c); } }
}
} }
}
x += 4 * scale;
}
}