1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
| import scipy.misc
import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import interp1d
from PIL import Image
import time
factor=2 #facteur de correction pour retrouver les corrections de photoshop
def make_bezier(xys):
# xys should be a sequence of 2-tuples (Bezier control points)
n = len(xys)
combinations = pascal_row(n-1)
def bezier(ts):
# This uses the generalized formula for bezier curves
# http://en.wikipedia.org/wiki/B%C3%A9zier_curve#Generalization
result = []
for t in ts:
tpowers = (t**i for i in range(n))
upowers = reversed([(1-t)**i for i in range(n)])
coefs = [c*a*b for c, a, b in zip(combinations, tpowers, upowers)]
result.append(
tuple(sum([coef*p for coef, p in zip(coefs, ps)]) for ps in zip(*xys)))
return result
return bezier
def pascal_row(n):
# This returns the nth row of Pascal's Triangle
result = [1]
x, numerator = 1, n
for denominator in range(1, n//2+1):
# print(numerator,denominator,x)
x *= numerator
x /= denominator
result.append(x)
numerator -= 1
if n&1 == 0:
# n is even
result.extend(reversed(result[:-1]))
else:
result.extend(reversed(result))
return result
def bezierRGB(r,g,b):
ts = [t/100.0 for t in range(101)]
dcouches={}
dcorr={'R':r,'G':g,'B':b}
for c in dcorr :
xys = [(0, 0), (128,128+(dcorr[c]*factor)), (255, 255)]
bezier = make_bezier(xys)
points = bezier(ts)
dcouches[c]=points
return [dcouches['R'],dcouches['G'],dcouches['B']]
def splitBezier(bezier):
"""retourne un tuple de liste (x,y) des points contenu dans make_bezier"""
x,y=[],[]
for p in bezier :
x.append(p[0])
y.append(p[1])
return (x,y)
"""
Small utility which is dealing with rgbv curves
to do some color corrections on a coloured image
"""
def color_curve(x, y, kind):
"""
Create a color curve given a set of points and a kind of interpolation
Parameters
----------
x : numpy 1d array
The x-coordinates of your points (must be between 0 and 255
included and stored in increasing order).
y : numpy 1d array
The y-coordinates of your points (values ranging from 0 to 255).
kind: string
The kind of interpolation : linear, cubic (for at least 4 points),
quadratic (for at least 3 points).
Returns
-------
out : numpy 1d array
The y-coordinates of the curve, the indices being their x-coords.
Beware: All negative values are set to zero !
Examples
--------
>>> x = np.array([0, 50, 128, 200, 255])
>>> y = np.array([255, 0, 125, 0, 255])
>>> plt.plot(np.arange(256), color_curve(x, y, 'quadratic'))
>>> plt.show()
"""
return interp1d(x, y, kind)(np.arange(256)).clip(min=0)
def adjust_colors_contrast(image, red, green, blue, contrast):
"""
Apply color curves on the color channels of an image
Parameters
----------
image : numpy array of shape (width, height, 3)
A coloured image.
red, green, blue, contrast : numpy 1d arrays (256 values
ranging from 0 to 255)
The color curves that are applied on the color channels.
Returns
-------
out : numpy array of shape (width, height, 3)
The resulting image.
"""
image[:, :, 0] = red[image[:, :, 0]]
image[:, :, 1] = green[image[:, :, 1]]
image[:, :, 2] = blue[image[:, :, 2]]
# Apply the color curves on each channels
for i in xrange(image.shape[2]):
image[:, :, i] = contrast[image[:, :, i]]
# Apply the contrast curve on each channels
def adjust_colors(image, red, green, blue):
"""
Apply color curves on the color channels of an image
Parameters
----------
image : numpy array of shape (width, height, 3)
A coloured image.
red, green, blue, contrast : numpy 1d arrays (256 values
ranging from 0 to 255)
The color curves that are applied on the color channels.
Returns
-------
out : numpy array of shape (width, height, 3)
The resulting image.
"""
image[:, :, 0] = red[image[:, :, 0]]
image[:, :, 1] = green[image[:, :, 1]]
image[:, :, 2] = blue[image[:, :, 2]]
# Apply the color curves on each channels
def ajustColorImage(im,r,g,b):
image=scipy.misc.fromimage(im)
beziers=bezierRGB(r,g,b)
rbezier=splitBezier(beziers[0])
r = color_curve(rbezier[0], rbezier[1], 'quadratic')
# The color curve which correspond to the quadratic interpolation of points
# (0, 255), (128, 0), (255, 255) is applied on the red color channel.
gbezier=splitBezier(beziers[1])
g = color_curve(gbezier[0], gbezier[1], 'quadratic')
# The color curve which correspond to the straight line passing through
# the points (0, 255), (255, 0) is applied on the green color channel.
bbezier=splitBezier(beziers[2])
b = color_curve(bbezier[0], bbezier[1], 'quadratic')
# The color curve which correspond to the straight line passing through
# the points (0, 0), (255, 255) is applied on the blue color channel.
# Doing this will not apply a color correction on this channel
adjust_colors(image, r, g, b)
return image
if __name__ == '__main__':
a=time.time()
im=Image.open("0002.JPG")
im=Image.fromarray( ajustColorImage(im,30,10,0))
print time.time() - a
im.save('0002_colorCorrectionScipy.JPG') |
Partager