Skip to content

Repository files navigation

purecv-esp32-examples

ESP32 examples that use the pure-Rust purecv computer-vision library under no_std.

Each example is its own crate in this Cargo workspace and shares the esp toolchain and flashing setup in .cargo/config.toml.

Examples

Crate What it shows
matrix-demo Builds purecv matrices on the heap, adds them, and logs the contents over serial (ESP32-S3).
gaussian-blur-demo Embeds a grayscale image, runs purecv::imgproc::gaussian_blur under no_std, and streams the blurred result back over serial as base64 (ESP32-S3).
calib3d-demo Camera pose estimation: projects known 3D points through a known pose, then recovers it with purecv::calib3d::solve_pnp (rodrigues + PnP) and logs true vs recovered (ESP32-S3).

Dependency on purecv

The examples depend on the published purecv crate from crates.io, built with default features disabled for no_std. It's declared once in the workspace [workspace.dependencies], and each example opts in with purecv.workspace = true:

# Cargo.toml (workspace root)
[workspace.dependencies]
purecv = { version = "0.7", default-features = false }

This repo is standalone — just clone it and build; Cargo fetches purecv from crates.io. No sibling checkout is required.

To test the examples against a local, unreleased purecv (e.g. while working on a new module), temporarily point the workspace dependency at a path: purecv = { path = "../purecv", default-features = false }.

Prerequisites

  • The Espressif Rust toolchain (espup), with the environment sourced so the Xtensa linker is on PATH:

    . $HOME\export-esp.ps1   # Windows PowerShell
  • espflash for flashing and the serial monitor.

Running an example

From the workspace root, with a board connected over USB:

cargo run -p matrix-demo --release

This builds, flashes, and opens the serial monitor.

gaussian-blur-demo: image in, image out

An ESP32 has no filesystem, so the input image is embedded into the firmware at build time and the output is streamed back over serial as base64 for the host to reconstruct.

1. Prepare the input (AR.data)

Convert an image to headerless 8-bit grayscale. With GIMP: open the image → Image → Mode → GrayscaleImage → Scale Image to 96×96Image → Flatten ImageFile → Export As AR.data (choose "Raw image data"). The file must be exactly W×H bytes (9216 for 96×96). If you change the size, update the W/H constants in gaussian-blur-demo/src/bin/main.rs.

2. Run it

cargo run -p gaussian-blur-demo --release *>&1 | Tee-Object run.log

The blurred image is printed between ---BEGIN OUTPUT 96x96--- and ---END OUTPUT--- markers as base64. Let it finish, then Ctrl+C.

3. Reconstruct the output (Windows PowerShell)

$b64 = ((Get-Content run.log) | ForEach-Object {
    if ($_ -match '[A-Za-z0-9+/=]{40,}') { $matches[0] }
}) -join ''
$bytes = [Convert]::FromBase64String($b64)
[IO.File]::WriteAllBytes((Join-Path $PWD 'output.data'), $bytes)   # relative paths go to the process CWD, not $PWD — always qualify
"$($bytes.Length) bytes"                                            # expect 9216

Open output.data in GIMP (File → Open → Raw image data, Grayscale, 96×96, offset 0) to view the blurred result.

Adding a new example

Each example is a workspace member and an ESP binary crate, so it needs three files — copying only two silently breaks the build:

  1. Cargo.toml — with purecv.workspace = true and the esp-hal deps.
  2. build.rs — copy it from an existing example. It emits the -Tlinkall.x linker argument; without it the app descriptor is mislinked and espflash fails with "appdesc segment not found".
  3. src/bin/main.rs — the example code.

Then add the crate name to members in the workspace Cargo.toml.

Image-processing examples also need a larger heap: gaussian_blur allocates a W×H×8-byte f64 working buffer, so bump esp_alloc::heap_allocator! accordingly (the blur demo uses 200 KB).

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages