Project 10: Payload Image Compressor (Space JPEG)

Build a lightweight image compressor using DCT + quantization, packetize the result for downlink, and measure quality with PSNR.

Quick Reference

Attribute Value
Difficulty Level 3: Advanced
Time Estimate 1-2 weeks
Main Programming Language C
Alternative Programming Languages Python
Coolness Level Level 3: Bandwidth Magician
Business Potential Level 3: Payload Pipeline Tooling
Prerequisites Linear algebra basics, image formats, bitwise ops
Key Topics DCT, quantization, packetization, PSNR

1. Learning Objectives

By completing this project, you will:

  1. Implement block-based DCT compression for grayscale images.
  2. Design quantization tables to trade quality vs size.
  3. Packetize compressed output for downlink constraints.
  4. Measure compression quality using PSNR.
  5. Understand how payload data is adapted to tiny bandwidths.

2. All Theory Needed (Per-Concept Breakdown)

DCT and Quantization for Image Compression

Fundamentals The Discrete Cosine Transform (DCT) converts image blocks from spatial domain to frequency domain. Most image energy is in low-frequency components; high-frequency components can be quantized more aggressively or discarded. Quantization reduces precision to achieve compression but introduces loss. By adjusting quantization tables, you control the tradeoff between image quality and compressed size. This is the core of JPEG-like compression.

Deep Dive into the concept The DCT operates on small blocks, typically 8x8 pixels. For each block, you compute 64 DCT coefficients. The DC coefficient represents the average intensity, while AC coefficients represent higher frequency variations. Natural images tend to have most energy in low-frequency components; therefore you can quantize higher-frequency coefficients more aggressively with minimal perceptual loss.

Quantization is performed by dividing each coefficient by a quantization table and rounding. Larger quantization values reduce precision and lead to more zeros in high-frequency coefficients. These zeros are then easy to compress with run-length encoding. The quantization table is the most powerful control knob for compression ratio. In space systems, you might accept higher loss to reduce downlink time. You should design a simple quantization table and allow a “quality factor” to scale it.

Implementing DCT efficiently is challenging in C, but for this project you can use a straightforward matrix-based implementation. Focus on correctness first; optimize later. Ensure that your pixel values are centered (e.g., subtract 128) before DCT to match JPEG conventions. After inverse DCT, add 128 back and clamp values to [0,255].

Quality assessment requires a metric. PSNR (Peak Signal-to-Noise Ratio) is commonly used. It is derived from mean squared error (MSE) between original and reconstructed images. PSNR in dB gives a quantitative measure of quality; values above ~30 dB are typically acceptable for many applications. In a payload context, PSNR is a way to justify a compression ratio.

How this fit on projects This concept drives Section 3.2 compression requirements and Section 6 testing (PSNR evaluation). It connects to P07 downlink scheduling.

Definitions & key terms

  • DCT -> Frequency transform for block-based compression.
  • Quantization -> Reducing coefficient precision to compress.
  • PSNR -> Quality metric derived from MSE.

Mental model diagram (ASCII)

Image Block -> DCT -> Quantize -> (zeros) -> Encode

How it works (step-by-step, with invariants and failure modes)

  1. Split image into 8x8 blocks.
  2. Subtract 128 and compute DCT.
  3. Divide by quantization table and round.
  4. Encode coefficients.
  5. Decode and inverse DCT to reconstruct.

Invariants: block size fixed; coefficients computed consistently; quantization reversible.

Failure modes: incorrect centering, wrong quantization scaling, overflow.

Minimal concrete example

coeff[i][j] = round(dct[i][j] / qtable[i][j]);

Common misconceptions

  • “Lossless compression is enough” -> Downlink constraints require lossy.
  • “Quantization only affects size” -> It directly affects image quality.

Check-your-understanding questions

  1. Why does DCT concentrate energy in low frequencies?
  2. How does quantization affect PSNR?
  3. Why subtract 128 before DCT?

Check-your-understanding answers

  1. Natural images vary slowly; low frequencies dominate.
  2. Larger quantization lowers PSNR (more error).
  3. Centers data around zero to reduce DC bias.

Real-world applications

  • Earth observation payload data compression.
  • Bandwidth-limited image transmission.

Where you’ll apply it

References

  • Gonzalez & Woods, Digital Image Processing
  • Wallace, The JPEG Still Picture Compression Standard

Key insights Most of an image is low-frequency; compress where it hurts least.

Summary DCT + quantization is the practical core of space-friendly image compression.

Homework/Exercises to practice the concept

  • Compute DCT of a simple 8x8 block by hand for a constant image.

Solutions to the homework/exercises

  • Only the DC coefficient is non-zero.

Packetization and Error Resilience

Fundamentals Compressed images must be packetized for downlink. Packetization splits a compressed bitstream into fixed-size chunks with headers and sequence numbers. This allows loss detection and partial reconstruction if packets are lost. Packetization is not just a transport detail; it shapes how much data you can recover when packets drop.

Deep Dive into the concept A compressed image bitstream is typically a sequence of variable-length codes. If you lose a portion of the stream, the decoder may lose synchronization. Therefore packetization should include resynchronization markers or structure. In JPEG, restart markers allow the decoder to resynchronize after loss. For this project, you can implement a simple packetization scheme where each packet carries a block index and payload length. This allows you to drop or reorder blocks without breaking the entire image. The tradeoff is overhead: each packet header consumes bytes, reducing net payload.

Sequence numbers are essential. They allow the ground system to detect missing packets and request retransmission (if possible) or accept partial reconstructions. In many CubeSats, retransmission is not feasible, so you design the packetization to maximize useful data even with loss. A block-based scheme works well: each packet contains a full 8x8 block of quantized coefficients. If you lose a packet, only that block is missing. You can fill missing blocks with zeros or interpolate.

Packet size choice matters. Larger packets are more efficient but risk losing more data if a packet is corrupted. Smaller packets increase overhead but reduce loss impact. In a low-power downlink, you might choose a moderate size (e.g., 256 bytes) to balance these tradeoffs. Your scheduler from P07 can use packet sizes to plan downlink bandwidth.

Determinism requires fixed packetization rules and consistent block ordering. When reconstructing, you should produce the same image given the same packet set. Include a packet header with fields: image_id, block_index, total_blocks, payload_length, checksum. The checksum helps detect corruption. If a checksum fails, mark the block as missing and log the error.

How this fit on projects This concept drives Section 3.5 data formats and Section 6 testing (packet loss scenarios) and ties to P07 scheduling.

Definitions & key terms

  • Packetization -> Splitting data into packets with headers.
  • Restart marker -> Resynchronization point for compressed streams.
  • Checksum -> Data integrity check.

Mental model diagram (ASCII)

Compressed Stream -> Packets -> Downlink -> Reassemble -> Image

How it works (step-by-step, with invariants and failure modes)

  1. Split compressed data into packets.
  2. Add headers with block index and checksum.
  3. Transmit packets; record sequence numbers.
  4. Reassemble at ground; fill missing blocks.

Invariants: packet headers consistent; block indices unique.

Failure modes: mis-ordered packets, checksum failure, missing blocks.

Minimal concrete example

struct pkt { uint16_t img_id; uint16_t block; uint16_t len; uint16_t crc; };

Common misconceptions

  • “Compression is independent of packetization” -> Packetization affects recoverability.
  • “Losing a packet just reduces quality” -> It can corrupt the entire stream if not structured.

Check-your-understanding questions

  1. Why include block indices in packets?
  2. What is the cost of smaller packets?
  3. How do you reconstruct missing blocks?

Check-your-understanding answers

  1. To place blocks correctly and detect loss.
  2. Higher overhead per payload byte.
  3. Fill with zeros or interpolate neighboring blocks.

Real-world applications

  • Downlink of Earth observation imagery.
  • Deep-space imaging with limited bandwidth.

Where you’ll apply it

References

  • CCSDS Image Data Compression recommendations
  • Gonzalez & Woods, Digital Image Processing

Key insights Packetization is part of compression; it determines what survives loss.

Summary Good packetization preserves partial images even under packet loss.

Homework/Exercises to practice the concept

  • Design a packet header for 256-byte payloads and estimate overhead.

Solutions to the homework/exercises

  • Example header 8 bytes -> overhead 3.1%.

3. Project Specification

3.1 What You Will Build

A CLI tool that compresses a grayscale image using DCT + quantization, packetizes the compressed output, reconstructs the image, and reports PSNR.

3.2 Functional Requirements

  1. DCT compression: 8x8 block transform and quantization.
  2. Packetization: block-based packets with headers.
  3. Reconstruction: inverse DCT to rebuild image.
  4. Quality metrics: PSNR and compression ratio.

3.3 Non-Functional Requirements

  • Determinism: fixed quantization tables and block ordering.
  • Efficiency: process 1024x1024 images in < 5s.
  • Robustness: handle packet loss by reconstructing partial images.

3.4 Example Usage / Output

$ ./img_compress input.pgm output.bin
[OK] Original: 1024x1024 (1.0 MB)
[OK] Compressed: 120 KB (8.3x reduction)
[PSNR] 34.2 dB

3.5 Data Formats / Schemas / Protocols

Packet header format:

img_id (2B) | block_index (2B) | payload_len (2B) | crc16 (2B)

3.6 Edge Cases

  • Image dimensions not divisible by 8.
  • Large quantization factors causing banding.
  • Packet loss during reconstruction.

3.7 Real World Outcome

A compressed payload file and reconstructed image with PSNR report.

3.7.1 How to Run (Copy/Paste)

./img_compress input.pgm out.bin --quality 50 --packet 256

3.7.2 Golden Path Demo (Deterministic)

  • Use samples/lena.pgm with quality 50.
  • Compare output to golden_psnr.txt.

3.7.3 Failure Demo (Deterministic)

./img_compress missing.pgm out.bin

Expected: error message and exit code 2.

3.7.4 If CLI: Exact Terminal Transcript

$ ./img_compress samples/lena.pgm out.bin --quality 50
[OK] Original: 512x512
[OK] Compressed: 62 KB
[PSNR] 33.1 dB
ExitCode=0

4. Solution Architecture

4.1 High-Level Design

Input Image -> DCT+Quantize -> Packetize -> Output
                               |
                               +-> Reconstruct + PSNR

4.2 Key Components

Component Responsibility Key Decisions
DCT Engine Transform blocks 8x8 block size
Quantizer Apply quant tables Quality scaling
Packetizer Build packets Packet size
Evaluator PSNR computation Metric choices

4.3 Data Structures (No Full Code)

typedef struct { uint16_t img_id; uint16_t block; uint16_t len; uint16_t crc; } pkt_hdr_t;

4.4 Algorithm Overview

Key Algorithm: Compression pipeline

  1. Split image into blocks.
  2. Apply DCT and quantization.
  3. Encode coefficients and packetize.
  4. Reconstruct and compute PSNR.

Complexity Analysis:

  • Time: O(N) blocks.
  • Space: O(block_size).

5. Implementation Guide

5.1 Development Environment Setup

cc -O2 -Wall -Wextra -o img_compress src/*.c

5.2 Project Structure

project-root/
+-- src/
+-- samples/
+-- README.md

5.3 The Core Question You’re Answering

“How do you send useful images over tiny bandwidth?”

5.4 Concepts You Must Understand First

  1. DCT and quantization.
  2. Packetization and loss recovery.
  3. PSNR evaluation.

5.5 Questions to Guide Your Design

  1. What quality factor yields acceptable PSNR?
  2. What packet size balances overhead and loss impact?
  3. How do you handle non-multiple-of-8 images?

5.6 Thinking Exercise

Compute PSNR for a 1-bit error in a 256x256 image.

5.7 The Interview Questions They’ll Ask

  1. “Why use DCT for compression?”
  2. “How do you recover from packet loss?”
  3. “What does PSNR measure?”

5.8 Hints in Layers

Hint 1: Start with DCT and inverse DCT on a single block.

Hint 2: Add quantization and verify reconstruction.

Hint 3: Implement packet headers and block indexing.

Hint 4: Add PSNR calculation and quality reporting.


5.9 Books That Will Help

Topic Book Chapter
Image compression Gonzalez & Woods DCT/Compression
JPEG standard Wallace, JPEG Standard Core algorithms
Data formats CCSDS image compression Overview

5.10 Implementation Phases

Phase 1: DCT + IDCT (4-5 days)

Goals: correct transform and reconstruction. Tasks: implement 8x8 DCT/IDCT; test with simple blocks. Checkpoint: reconstruction error small with no quantization.

Phase 2: Quantization (3-4 days)

Goals: reduce size with acceptable quality. Tasks: add quant tables and quality factor. Checkpoint: PSNR within target range.

Phase 3: Packetization (3-4 days)

Goals: structure data for downlink. Tasks: design packet header, block indexing, CRC. Checkpoint: packet loss simulation yields partial image.

5.11 Key Implementation Decisions

Decision Options Recommendation Rationale
Block size 8x8 / 16x16 8x8 JPEG standard
Packet size 128 / 256 / 512 256 Balanced overhead
Quality control fixed / scalable scalable Adjustable tradeoff

6. Testing Strategy

6.1 Test Categories

Category Purpose Examples
Unit Tests DCT correctness known blocks
Integration Tests Compression pipeline lena.pgm
Edge Case Tests Packet loss drop 10% packets

6.2 Critical Test Cases

  1. No quantization: reconstruction nearly identical.
  2. Quality 50: PSNR > 30 dB.
  3. Packet loss: image reconstructed with missing blocks.

6.3 Test Data

samples/lena.pgm

7. Common Pitfalls & Debugging

7.1 Frequent Mistakes

Pitfall Symptom Solution
Missing centering DC bias in output Subtract/add 128
Overflow artifacts clamp to [0,255]
Wrong block ordering scrambled image consistent indexing

7.2 Debugging Strategies

  • Visualize reconstructed images at different quality factors.
  • Print coefficient histograms to verify zeros increase.

7.3 Performance Traps

Naive DCT is slow; keep images small for tests.


8. Extensions & Challenges

8.1 Beginner Extensions

  • Add run-length encoding for zeros.

8.2 Intermediate Extensions

  • Add Huffman coding for entropy compression.

8.3 Advanced Extensions

  • Implement restart markers for resync.

9. Real-World Connections

9.1 Industry Applications

  • Earth observation payload compression.
  • Remote sensing imaging pipelines.
  • libjpeg (reference JPEG implementation).
  • CCSDS image compression reference code.

9.3 Interview Relevance

  • Shows applied signal processing and systems thinking.

10. Resources

10.1 Essential Reading

  • Gonzalez & Woods, Digital Image Processing.
  • Wallace, JPEG Standard.

10.2 Video Resources

  • Image compression lectures.

10.3 Tools & Documentation

  • PGM image format docs.

11. Self-Assessment Checklist

11.1 Understanding

  • I can explain DCT and quantization.
  • I can compute PSNR from MSE.
  • I can describe packetization tradeoffs.

11.2 Implementation

  • Compression ratio and PSNR reported.
  • Packet loss simulation works.
  • Deterministic output with fixed parameters.

11.3 Growth

  • I can implement entropy coding.

12. Submission / Completion Criteria

Minimum Viable Completion:

  • DCT-based compression and reconstruction.

Full Completion:

  • Packetization and PSNR reporting.

Excellence (Going Above & Beyond):

  • Add entropy coding and restart markers.