If you have been on the internet for a bit, you might have seen the collection of photos of one Sergey Prokudin-Gorsky.
His mesmerising colour photographies documenting Russia from the early 1900's through 3 colour filters inspired me to give it a try of my own.
As a first experiment, I decided to start with a really cheap film, and 3 filters. I actually took 4 photo's, as I wanted to make sure at least some of them were usuable.
From left to right: No filter, Red filter (actually orange), green filter, blue filter.
Note I stopped the filtered images down two stops, but I should only have done one (they are overexposed).
I made a small script to combine them. Note this is not very accurate as it was scanned through my DSLR, and slightly compensated for position but not for rotation (my PC is not a powerhouse, it does not like rotating images very much).
The way I encoded it is that I first constructed the RGB object from the red, green, and blue images, then used it's hue and saturation (the latter boosted 4 times because it was kinda weak) with the luminance of the proper black and white image.
I hoped that might avoid some colour shifts, no idea if it helped.
The resulting image is very lo-fi just as it's source images (for starters: it was shot on Fomapan on a cheap russian rangefinder's crusty lens). I still got futher than I though.
For comparaison I have put a photo taken with my cheap phone's camera, to see how close the colours got. At least I did not mix up the channels!
This should have been done through pillow or through magick, but I got lazy and used the tools I know. Hence pygame.
Image should be pre-inverted, as there are far more clever programs at doing a negative inversion than what I can pull up in 5 minutes.
import pygame,sys
def load(path,x=0,y=0):
image = pygame.image.load(path)
out = pygame.Surface(image.get_size())
out.blit(image,(x,y))
return pygame.transform.smoothscale(out,(640,480))
def clip(value, minval=0, maxval=255):
return min(maxval, max(minval, int(value)))
grey = load("/home/mii/Pictures/Photo's/112_2008/export/IMGP2397.jpg")
red = load("/home/mii/Pictures/Photo's/112_2008/export/IMGP2398.jpg", 560-534, 1623-1644)
blue = load("/home/mii/Pictures/Photo's/112_2008/export/IMGP2399.jpg", 560-480, 1623-1640)
green = load("/home/mii/Pictures/Photo's/112_2008/export/IMGP2400.jpg", 560-550, 1623-1680)
def combine(output,grey,red,green,blue):
for y in range(output.get_height()):
for x in range(output.get_width()):
Y = grey.get_at((x,y)).g
R = red.get_at((x,y)).g
G = green.get_at((x,y)).g
B = blue.get_at((x,y)).g
color = pygame.Color(R,G,B)
h,s,v,a = color.hsva
color.hsva = (h,clip(s*4,0,100), Y*100/256, a)
output.set_at((x,y),color)
pygame.display.flip()
for event in pygame.event.get():
if event.type==pygame.QUIT:
pygame.quit()
sys.exit()
if __name__=="__main__":
surface = pygame.display.set_mode(grey.get_size(), pygame.SCALED)
combine(surface,grey,red,green,blue)
pygame.image.save(surface,"out.png")