programextensions/image/demos/photo-lab.xtl

The photo lab: a photo is an array. Buzz Aldrin on the Moon (Apollo 11, NASA, public domain: demos/data/PROVENANCE.txt) read as numbers; filters and edges by rotating the array (the Life idiom), a color toning by an inner product, and the SVD compressing it at several ranks -- the native code reads, writes and decomposes, X_eTaL does the rest. Pictures go to work/photo-lab/. Run: just demo image photo-lab

source · imports im: extensions/image/lib/Image.xtl; la: extensions/linalg/lib/Linalg.xtl

src : Char

value · line 12
src ← "demos/data/aldrin.jpg"

out : Char

value · line 13
out ← "work/photo-lab/"
Used in: n

ᵘr̲ound : Float -> Float

function · line 14
ᵘr̲ound ← { v → (f̲loat f̲loor 0.5 + 1000.0 × v) ÷ 1000.0 }

ᵘm̲ean : Num a => a -> Float

function · line 15
ᵘm̲ean ← { v → ('+ r̲/ f̲loat r̲avel v) ÷ f̲loat t̲ally r̲avel v }

1. the photo as numbers: 240 by 246, gray from 0 (black) to 1

p : Float

value · line 21
p ← 240 246 ⁱᵐr̲esize ⁱᵐg̲ray src

2. filters by rotation: each pixel and its 8 neighbors, as Life

box : Float

value · line 29

counts neighbors (the edges wrap around, as rotations do)

box ← ('+ r̲/₁₂ -1 0 1 o̲-₁₂ p) ÷ 9.0
Used in: sharp, n

sharp : Float

value · line 30
sharp ← 0.0 m̲ax 1.0 m̲in p + 1.5 × p − box
Used in: n

sx : Float

value · line 33

edges: Sobel, horizontal and vertical differences of the blurred rows and columns, and their length

sx ← ((-1 o̲-₂ p) − 1 o̲-₂ p)
Used in: gx

sy : Float

value · line 34
sy ← ((-1 o̲-₁ p) − 1 o̲-₁ p)
Used in: gy

gx : Float

value · line 35
gx ← sx + (1 o̲-₁ sx) + -1 o̲-₁ sx
Used in: edge

gy : Float

value · line 36
gy ← sy + (1 o̲-₂ sy) + -1 o̲-₂ sy
Used in: edge

edge : Float

value · line 37
edge ← 1.0 m̲in 0.5 × ((gx ^ 2.0) + gy ^ 2.0) ^ 0.5

n : Int

value · line 40
n ← (out c̲at "filters.png") ⁱᵐw̲rite! p c̲at₂ box c̲at₂ sharp c̲at₂ edge

3. color: a sepia toning, every pixel's red, green and blue times

c : Float

value · line 45

one 3 by 3 matrix (an inner product over the last axis)

c ← 240 246 ⁱᵐr̲esize ⁱᵐr̲ead src
Used in: toned, n

sepia : Float

value · line 46
sepia ← 3 3 r̲eshape 0.393 0.349 0.272 0.769 0.686 0.534 0.189 0.168 0.131
Used in: toned

toned : Float

value · line 47
toned ← 1.0 m̲in c '+ '× i̲nner sepia
Used in: n

n : Int

value · line 48
n ← (out c̲at "sepia.png") ⁱᵐw̲rite! c c̲at₂ toned

4. the SVD: the photo as a sum of rank-1 pictures, largest first;

u : Float

value · line 53

keeping k of 240 stores k times (240 + 246 + 1) numbers

u ← ˡᵃs̲vdU p
Used in: ᵘr̲ank

s : Float

value · line 54
s ← ˡᵃs̲vdS p

v : Float

value · line 55
v ← ˡᵃs̲vdV p
Used in: ᵘr̲ank

e : Float

value · line 58
e ← '+ s̲\ s ^ 2.0

ᵘr̲ank : Int -> Float

function · line 60
ᵘr̲ank ← { k → ((k t̲ake₂ u) × (s̲hape k t̲ake₂ u) r̲eshape k t̲ake s) '+ '× i̲nner 2 1 t̲ranspose k t̲ake₂ v }
Used in: r5, r20, r50

r5 : Float

value · line 61
r5 ← ᵘr̲ank 5

r20 : Float

value · line 62
r20 ← ᵘr̲ank 20

r50 : Float

value · line 63
r50 ← ᵘr̲ank 50

ᵘe̲rr : Float -> Float

function · line 65
ᵘe̲rr ← { r → (ᵘm̲ean (r − p) ^ 2.0) ^ 0.5 }

n : Int

value · line 67
n ← (out c̲at "svd.png") ⁱᵐw̲rite! p c̲at₂ r50 c̲at₂ r20 c̲at₂ r5