Reputation: 2217
Im trying to use a specific gamma corrected grayscale implementation - Gleam to convert an images pixels to grayscale. How can i do this manually with PIL python?
def tau_gamma_correct(pixel_channel):
pixel_channel = pixel_channel**(1/2.2)
return pixel_channel
#@param: rgb
#@result: returns grayscale value
def gleam(rgb):
#convert rgb tuple to list
rgblist = list(rgb)
#gamma correct each rgb channel
rgblist[0] = tau_gamma_correct(rgblist[0])
rgblist[1] = tau_gamma_correct(rgblist[1])
rgblist[2] = tau_gamma_correct(rgblist[2])
grayscale = 1/3*(rgblist[0] + rgblist[1] + rgblist[2])
return grayscale
# get a glob list of jpg filenames
files = glob.glob('*.jpg')
for file in files:
file = open(file)
filename = file.name
image = Image.open(file)
pix = image.load()
width, height = image.size
#print(width,height)
for x in range(0, width):
for y in range(0, height):
rgb = pix[x,y]
#print(rgb)
# calc new pixel value and set to pixel
image.mode = 'L'
pix[x,y] = gleam(rgb)
image.save(filename + 'gray.gleam'+'.jpg')
file.close()
SystemError: new style getargs format but argument is not a tuple
It is still expecting the rgb tuple i think.
Upvotes: 3
Views: 2825
Reputation: 308166
The problem is that image.mode = 'L'
doesn't actually change the type of the image, it just changes the attribute so it's no longer accurate. To change the mode of the image you need to make a new copy with image.convert('L')
.
Once you have an image in grayscale mode, it won't require a tuple for a pixel value anymore.
Upvotes: 1
Reputation: 2217
I found that i could just build another image:
import sys
import os
import glob
import numpy
from PIL import Image
def tau_gamma_correct(pixel_channel):
pixel_channel = pixel_channel**(1/2.2)
return pixel_channel
#@param: rgb
#@result: returns grayscale value
def gleam(rgb):
#convert rgb tuple to list
rgblist = list(rgb)
#gamma correct each rgb channel
rgblist[0] = tau_gamma_correct(rgblist[0])
print('gleamed red ' + str(rgblist[0]))
rgblist[1] = tau_gamma_correct(rgblist[1])
print('gleamed green ' + str(rgblist[1]))
rgblist[2] = tau_gamma_correct(rgblist[2])
print('gleamed blue ' + str(rgblist[0]))
grayscale = (rgblist[0] + rgblist[1] + rgblist[2])/3
print('grayscale '+ str(grayscale))
return grayscale
# get a glob list of jpg filenames
files = glob.glob('*.jpg')
for file in files:
file = open(file)
filename = file.name
image = Image.open(file)
pix = image.load()
width, height = image.size
new_image = Image.new('L', image.size)
#pixelmatrix = [width][height]
pixelmatrix = numpy.zeros((width, height))
#print(width,height)
for x in range(0, width):
for y in range(0, height):
rgb = pix[x,y]
print('current pixel value: '+str(rgb))
# calc new pixel value and set to pixel
#print(gleam(rgb))
gray = gleam(rgb)
print('changing to pixel value: '+str(gray))
pixelmatrix[x,y] = gray
new_image.save(filename + 'gray.gleam'+'.jpg')
new_image.putdata(pixelmatrix)
file.close()
Upvotes: 1
Reputation: 22954
Seeing the SystemError: new style getargs format but argument is not a tuple
error it seems that you need to return a tuple, which is represented as :
sample_tuple = (1, 2, 3, 4)
So we edit the gleam()
function as:
def gleam(rgb):
#convert rgb tuple to list
rgblist = list(rgb)
#gamma correct each rgb channel
rgblist[0] = tau_gamma_correct(rgblist[0])
rgblist[1] = tau_gamma_correct(rgblist[1])
rgblist[2] = tau_gamma_correct(rgblist[2])
grayscale = 1/3*(rgblist[0] + rgblist[1] + rgblist[2])
return (grayscale, )
Keep in mind that while returning a single element tuple you need to represent as :
sample_tuple = (1, )
This is due to the fact that (4) == 4
but (4, ) != 4
Upvotes: 0