Skip to content

Add a luma-only mode (--color-space yiq) - #64

Merged
joeljose merged 1 commit into
mainfrom
feature/37-luma-mode
Sep 28, 2026
Merged

joeljose merged 1 commit into
mainfrom
feature/37-luma-mode

Conversation

@joeljose

Copy link
Copy Markdown
Owner

Closes #37

What changed

  • --color-space {rgb,yiq} (default rgb, so existing output is unchanged). In yiq mode, magnify_luma() computes BT.601 luma, magnifies it once, and adds the luma change to R, G and B. That is exactly "convert to YIQ, replace Y, convert back", because the Y column of the inverse YIQ matrix is all ones, so I and Q stay as in the input. YCrCb uses the same luma and would give identical results, so only yiq is offered.
  • Works with --gpu too. The Parameters block prints the colour space.
  • main()'s per-channel loop was folded into one magnify() helper shared by both modes.
  • README: option, example, and a Tips entry with a side-by-side crop (.github/images/luma_vs_rgb.png, 156 KB): input vs k=5 rgb (magenta fringes on the glasses frame) vs k=5 yiq.

Measurements (face.mp4, k=5, CPU, default --jobs 2)

time cgroup peak mean chroma change p99.9 chroma change
rgb 55.7 s 2.29 GiB 2.35 28.0
yiq 16.2 s 2.66 GiB 0.012 3.4

GPU: --gpu --color-space yiq on face.mp4 takes 15.3 s and passes verify_output.py.

Peak memory is a bit higher in yiq mode (the float32 luma and the magnified result coexist), not lower as the issue expected; the issue's ~3x memory saving doesn't apply because channels were already processed one at a time. The remaining chroma change in yiq mode comes only from clipping: in saturated areas (the red shirt) adding brightness clips one channel and shifts the pixel toward grey. The README mentions this.

Tests

  • Magnification property in luma mode: output luma moves 0.8–1.2x k for k = 2, 4 (acceptance criterion).
  • I and Q unchanged (< 1 level) on an unclipped clip; luma weights sum to 1; CLI run with --color-space yiq.
  • CPU image 77 passed, 3 skipped; GPU image on an RTX 4050 99 passed, 1 skipped.

Magnifying R, G and B separately triples the work and lets the channel
phases drift apart, which shows as colour fringing at higher k. With
--color-space yiq only the BT.601 luma is magnified; because the Y column
of the inverse YIQ matrix is all ones, the luma change is added to each
of R, G and B, which keeps the input's chroma. On face.mp4 at k=5 the CPU
run takes 16 s instead of 56 s and the mean chroma change drops from 2.35
to 0.01. The default stays rgb so existing output doesn't change.

Closes #37
@joeljose
joeljose merged commit 7e63eb8 into main Sep 28, 2026
2 checks passed
@joeljose
joeljose deleted the feature/37-luma-mode branch September 28, 2026 05:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add a luma-only mode: magnify Y in YIQ/YCrCb instead of R, G and B separately (~3× faster, no colour fringing)

1 participant