Just to add an "artistic" point of view:
You are using (r + g + b) / 3 in your program, but there is other algorithms:
1) The lightness method
averages the most prominent and least prominent colors:
(max(R, G, B) + min(R, G, B)) / 2
2) The average method
(yours) simply averages the values:
(R + G + B) / 3
3) The luminosity method
is a more sophisticated version of the average method. It also averages the values, but it forms a weighted average to account for human perception. We’re more sensitive to green than other colors, so green is weighted most heavily. The formula for luminosity is:
0.21 R + 0.71 G + 0.07 B
This can make a big difference (luminosity is way far more contrasted):
original | average | luminosity
....................................................
Code :
px = getPixels(pic)
level = int(0.21 * getRed(px) + 0.71 * getGreen(px) + 0.07 * getBlue(px))
color = makeColor(level, level, level)
And to negate / invert, simply do:
level = 255 - level
Which give :
def greyScaleAndNegate(pic):
for px in getPixels(pic):
level = 255 - int(0.21*getRed(px) + 0.71*getGreen(px) +0.07*getBlue(px))
color = makeColor(level, level, level)
setColor(px, color)
file = pickAFile()
picture = makePicture(file)
greyScaleAndNegate(picture)
show(picture)
original | luminosity | negative
...................................................................
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…