Created
January 31, 2012 16:31
-
-
Save astanin/1711451 to your computer and use it in GitHub Desktop.
Colour-match two sets of images pairwise, adjust colour bqlance in the first set of images.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python2 | |
# requires PIL (python-imaging) | |
import Image | |
import ImageStat | |
from sys import argv, exit | |
from os.path import basename, splitext | |
MODIFIED_SUFFIX = "_mod.jpg" | |
def match_colours(source_image, target_image): | |
""" | |
Calculate per-channel amplification to match colours of the target_file. | |
Return (x_red, x_green, x_blue). | |
""" | |
s = ImageStat.Stat(source_image) | |
t = ImageStat.Stat(target_image) | |
k_chans = [ (tc/sc if sc else 1.0) for sc, tc in zip(s.mean, t.mean) ] | |
return tuple(k_chans) | |
def amplify_channels(image, factors): | |
""" | |
Apply per-channel amplification to the image. | |
image PIL image | |
factors a tuple of amplification coefficients, one per channel | |
Return a new PIL image. | |
""" | |
chans = image.split() | |
chans2 = [ Image.eval(c, lambda x: x*f) for c,f in zip(chans, factors)] | |
image2 = Image.merge(image.mode, chans2) | |
return image2 | |
def main(source_images, target_images): | |
# calculate average transform coefficients using all image pairs | |
avg_multipliers = [] | |
n = len(zip(source_images, target_images)) # number of pairs | |
for s, t in zip(source_images, target_images): | |
simg = Image.open(s) | |
simg.load() # workaround for http://bugs.debian.org/561965 | |
timg = Image.open(t) | |
multipliers = match_colours(simg, timg) | |
ms = [ float(m)/n for m in multipliers ] | |
if not avg_multipliers: | |
avg_multipliers = [ float(m)/n for m in multipliers ] | |
else: | |
avg_multipliers = [ old_avg+float(m)/n | |
for old_avg, m | |
in zip(avg_multipliers, multipliers)] | |
# transform and save every source image | |
for s in source_images: | |
simg = Image.open(s) | |
simg.load() # workaround for http://bugs.debian.org/561965 | |
modified = amplify_channels(simg, avg_multipliers) | |
out_filename = splitext(s)[0] + MODIFIED_SUFFIX | |
modified.save(out_filename) | |
def usage(): | |
help = \ | |
"""%s bad_image_1 bad_image_2 ... good_image_1 good_image_2 ... | |
Compare bad and good images pairwise, calculate per-channel | |
amplification coefficients to match colours in average, adjust bad | |
images and save them to new files appending "%s" to the filename. | |
""" | |
print help % (basename(argv[0]), MODIFIED_SUFFIX) | |
if __name__ == "__main__": | |
args = argv[1:] | |
if not args or "-h" in args or "--help" in args: | |
usage() | |
exit(0) | |
else: | |
n = len(args) | |
bad_imgs = args[0:n//2] | |
good_imgs = args[n//2:] | |
main(bad_imgs, good_imgs) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment