Project 16

Build an Image Transformation Toolkit

Load small supplied PNG images into arrays with named axes, apply exact transformations, and verify each result with pixels, counts, saved images, and replay.

  • 8 milestones
  • Optional
  • Browser workspace

Project question: Can you load small images into clearly shaped arrays, transform them without losing pixels, and prove what changed?

What makes this a project

An image can look simple on screen while its array representation carries several decisions: which axis is a row, which is a channel, what a value means, and what happens at an edge. In this project you will make those decisions explicit, implement a small set of exact transformations, check pixels and counts, and save a transformation record another program can inspect.

This is a dependable image-array toolkit. It is not a lesson in computer vision and it does not claim that a transformation improves an image or a model. A small synthetic pattern is often more useful here than a beautiful photograph, because you can predict its output by hand.

You will produce:

  • a checked inventory of supplied PNG fixtures;
  • independent uint8 arrays with named height, width, and channel axes;
  • pure crop, flip, channel, brightness, mask, and local-mean operations;
  • an ordered transformation plan with stage records and pixel checks;
  • numerical summaries and exact value-count evidence;
  • PNG save/reload equality checks and a separate replay; and
  • a concise toolkit card with bounded claims.

What you should know first

The project follows the Python path through Chapter 13. You should be able to check file identity, construct and inspect NumPy arrays, name axes, slice and copy arrays, apply masks, calculate whole-array operations, plot counts, work across files, and test deterministic programs. DATA-01 and DATA-03 are useful but optional. The supplied fixtures provide the image and mode boundary if you skipped them.

Supplied images

Use the versioned manifest and its repository-owned PNG files. It records unique image_id, safe relative path, byte count, SHA-256 digest, width, height, and declared mode. The set includes grayscale and RGB images, tiny synthetic patterns, and failure fixtures for corrupted input and unsupported modes. Do not replace a fixture with a different image because it is easier to display.

The array contract

Supported Pillow modes are L and RGB. Convert every image to an independent NumPy array with:

grayscale: shape (height, width, 1), dtype uint8
RGB:       shape (height, width, 3), dtype uint8
axis 0 = rows from top to bottom
axis 1 = columns from left to right
axis 2 = channels in declared order
value range = 0 through 255

The length-one grayscale axis is a toolkit representation. It does not add a pixel channel to the stored image.

The project workspace

project/
  README.md
  data/                              # supplied, read only
  plans/transform_plan.json          # supplied starting plan
  src/config.py                      # reader implementation
  src/load.py                        # reader implementation
  src/operations.py                  # reader implementation
  src/pipeline.py                    # reader implementation
  src/verify.py                      # reader implementation
  src/report.py                      # reader implementation
  src/main.py                        # reader implementation
  output/                            # generated artifacts
  tests/public_cases.py              # supplied, read only

Keep loading, each operation, plan execution, verification, and serialization independently inspectable. Keep one workspace through every milestone.

Project milestones

Work through these in order. Each milestone produces evidence used by the next one, while project completion remains separate from lesson progress.

  1. 1Verify and load supplied images

    Check safe manifest identity and supported PNG metadata, then load independent uint8 arrays with explicit row, column, and channel axes.

  2. 2Implement coordinate-safe crop and flips

    Apply half-open row and column bounds, reverse one named axis at a time, predict corners and shapes, and prove every returned array is independent.

  3. 3Select one channel without losing axis meaning

    Select a valid channel while keeping a length-one channel axis and rejecting boolean, negative, and out-of-range indexes.

  4. 4Implement brightness and masks safely

    Use wider signed arithmetic and clipping for brightness, validate boolean mask and fill shapes, and preserve every unmasked pixel exactly.

  5. 5Implement and hand-check the 3 × 3 mean rule

    Repeat nearest edge values, accumulate each channel in a wider integer dtype, divide by nine with floor division, and check center, edge, and corner pixels.

  6. 6Execute an ordered transformation plan

    Validate every named operation and argument before execution, then retain source and stage identity, shapes, pixel checks, and output digests.

  7. 7Save, reload, inspect, and replay

    Save supported PNG stages without overwrite, reload exact arrays, conserve per-channel counts, read artifacts back, and reproduce them in a separate replay.

  8. 8Write and audit the toolkit card

    State supported modes, axes, coordinates, operations, edge rules, plans, numerical and visual evidence, reload, replay, and unsupported claims.

Required evidence

Save the image inventory and plan identity, selected stage arrays or exact pixel tables, PNG stages, stage_records.jsonl, pixel_checks.csv, per-channel summaries, 256-bin value-count tables, source/stage comparison figures and their exact plot data, PNG reload equality records, image_toolkit_manifest.json, a replay agreement or mismatch record, and report.md as the toolkit card.

Limits

This project does not teach JPEG, animation, alpha or CMYK modes, EXIF orientation, color profiles, gamma correction, resizing, interpolation, rotation, geometric warps, random augmentation, annotation, convolution theory, learned filters, feature extraction, classification, segmentation, OpenCV, GPU execution, large-image tiling, or performance benchmarking. It does not claim perceptual quality or model improvement.

Review

The final review asks whether every source is identified, arrays have the stated axes and dtype, every operation is pure and bounded, edge behavior is explicit, pixels and counts agree, invalid plans fail honestly, saved images reload exactly, replay is separate, and the card distinguishes observations from claims.