yard sale

ColorBlindr.com

(AKA: colorblindsimulator.com)

ColorBlindr was intended to be an extension of iCapture. Basically, a mathematical transformation was applied to the original screenshot that simulated each of the 3 major color vision deficiencies; protanopia, deuteranopia, tritanopia. This concept was later mutated into a flickr proxy site that allowed you to browse your own photos simulating color vision deficiencies. (hence the 'r')

Much of this code was derived from the following resource http://www.stanford.edu/~ofidaner/psych221_proj/colorblindness_project.htm (Dead link)

In the years that have past since this project went dormant, it appears Oliver Siemoneit has also developed a python utility from the aforementioned research project. (http://moinmo.in/AccessibleMoin)

Looking for more, looking for current information on colorblindness? Checkout what people are bookmarking on del.icio.us colorblind, color vision deficiencies, daltonism

Nothing too advanced here, never made it past the proof of concept phase.

Orion Parrot worked his math magic on this in the wee hours of the morning during a visit with him in Pickering UK, I don't claim to be a mathematician.

colorblindr.py
#!/usr/bin/env python

import os
import Image

import scipy

from numpy import *
import numpy

from numpy.linalg import inv

def image2array(image):
    """PIL Image to NumPy array"""
    assert image.mode in ('L', 'RGB', 'CMYK')
    arr = numpy.fromstring(image.tostring(), numpy.uint8)
    arr.shape = (image.size[1], image.size[0], len(image.getbands()))
    #return arr.swapaxes(0,2).swapaxes(1,2)
    return arr

def array2image(arr, mode):
    """NumPy array to PIL Image"""
    #arr = arr.swapaxes(1,2).swapaxes(0,2)
    arr[arr < 0] = 0
    arr[arr > 255] = 255
    arr = numpy.fix(arr).astype(numpy.uint8)
    return Image.fromstring(mode, arr.shape[1::-1], arr.tostring())


file_name = '/home/dvine/projects/colorblindr/test.jpg' 

# transorm matrices
lms2lmsp = array([[0, 2.02344, -2.52581], [0, 1, 0], [0, 0, 1]])
lms2lmsd = array([[1, 0, 0], [0.494207, 0, 1.24827], [0, 0, 1]])
lms2lmst = array([[1, 0, 0], [0, 1, 0], [-0.395913, 0.801109, 0]])

rgb2lms = array([[17.8824, 43.5161, 4.11935], [3.45565, 27.1554, 3.86714], [0.0299566, 0.184309, 1.46709]])

lms2rgb = inv(rgb2lms)

# read picture into RGB value
im = Image.open('/home/dvine/projects/colorblindr/test.jpg')
RGB = image2array(im)
sizeRGB = RGB.shape

LMS = numpy.zeros( (sizeRGB[0],sizeRGB[1],3) )

LMSp = numpy.zeros( (sizeRGB[0],sizeRGB[1],3) )
LMSd = numpy.zeros( (sizeRGB[0],sizeRGB[1],3) )
LMSt = numpy.zeros( (sizeRGB[0],sizeRGB[1],3) )

RGBp = numpy.zeros( (sizeRGB[0],sizeRGB[1],3) )
RGBd = numpy.zeros( (sizeRGB[0],sizeRGB[1],3) )
RGBt = numpy.zeros( (sizeRGB[0],sizeRGB[1],3) )

# transform to LMS space
for i in range(sizeRGB[0]):
    for j in range(sizeRGB[1]):
        rgb = RGB[i,j, [0, 1, 2]]
        LMS[i,j,:] = numpy.dot(rgb2lms,rgb)

# transform to colorblind LMS values
for i in range(sizeRGB[0]):
    for j in range(sizeRGB[1]):
        lms = LMS[i,j,:]
        LMSp[i,j,:] = numpy.dot(lms2lmsp,lms)
        LMSd[i,j,:] = numpy.dot(lms2lmsd,lms)
        LMSt[i,j,:] = numpy.dot(lms2lmst,lms)


# transform new LMS value to RGB values
for i in range(sizeRGB[0]):
   for j in range(sizeRGB[1]):
        lmsp = LMSp[i,j,:]
        lmsd = LMSd[i,j,:]
        lmst = LMSt[i,j,:]
        RGBp[i,j,:] = numpy.dot(lms2rgb, lmsp)
        RGBd[i,j,:] = numpy.dot(lms2rgb, lmsd)
        RGBt[i,j,:] = numpy.dot(lms2rgb, lmst)

array2image(RGB, 'RGB').save('/home/dvine/projects/colorblindr/output/original.jpg')
array2image(RGBd, 'RGB').save('/home/dvine/projects/colorblindr/output/d.jpg')
array2image(RGBp, 'RGB').save('/home/dvine/projects/colorblindr/output/p.jpg')
array2image(RGBt, 'RGB').save('/home/dvine/projects/colorblindr/output/t.jpg')

Your probably looking for the end results if you've made it this far down the page. Well, I'll dig those up soon. Never quite perfected the output, this is why the project died.