Skip to content

Instantly share code, notes, and snippets.

@built
Created January 31, 2016 07:26
Show Gist options
  • Save built/a8954193c8986cab7f3b to your computer and use it in GitHub Desktop.
Save built/a8954193c8986cab7f3b to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
# A riff on https://gist.github.com/celoyd/dddc2f9e0ad7217a13e5
from skimage import io
from skimage.transform import resize
import numpy as np
from sys import argv
MAXINT = np.iinfo(np.uint8).max
# We'll use floats as an intermediate type, and
# skimage likes them always in the range -1..1:
def byte_to_unit(n):
return n/MAXINT
def unit_to_byte(n):
return np.clip(
n * MAXINT,
0,
MAXINT
).astype(np.uint8)
src = io.imread(argv[1]) # Load our input image as 2D greyscale.
# Ensure we are working with the kind of image we think we're working with.
if src.ndim != 2:
print "Input file isn't 2D. Can't work with this, sorry."
exit(1)
# The major filter in the image forms a green checkerboard pattern, so create a mask to match.
green_mask = np.tile( np.array([[False,True],[True,False]]), (src.shape[0]/2, src.shape[1]/2))
# While green-filtered pixels exist on each row, red and blue pixels alternate rows.
# This means we can reuse the green mask but we must invert it.
# Blue will get one set of alternating rows, red the other.
# Zero out the masks
blue_mask = np.zeros(green_mask.shape, dtype=bool)
red_mask = np.zeros(green_mask.shape, dtype=bool)
# Project alternating rows from the inverted green mask
blue_mask[::2] = ~green_mask[::2]
red_mask[::-2] = ~green_mask[::-2]
# Initialize our image layers and then copy the masked data from the source image to each.
green_layer = np.zeros_like(src)
green_layer[green_mask] = src[green_mask]
blue_layer = np.zeros_like(src)
blue_layer[blue_mask] = src[blue_mask]
red_layer = np.zeros_like(src)
red_layer[red_mask] = src[red_mask]
# Assemble our layers into something we can work with.
dst = np.dstack([
red_layer,
green_layer,
blue_layer
])
RED, GREEN, BLUE = (0, 1, 2)
# Tone down the green a bit.
dst[:,:,GREEN] /= 2
dst = byte_to_unit(dst.astype(np.float32))
input_width, input_height = src.shape # Expecting a 2D array here!
dst = resize(dst, (input_width/2, input_height/2))
dst *= 4
dst[:,:,BLUE] *= 1.75 # Totally arbitrary but seems to fix the blue!
dst = unit_to_byte(dst)
io.imsave(argv[2], dst)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment