2

I am using Image.point and Image.fromarray to do exactly the same operation on an image, increase the value of all pixels together by the same value. The thing is that i get to absolutelly different images.

using point

def getValue(val):
    return math.floor(255*float(val)/100)

def func(i):
    return int(i+getValue(50))

out = img.point(func)

using array and numpy

arr = np.array(np.asarray(img).astype('float'))
value = math.floor(255*float(50)/100)
arr[...,0] += value
arr[...,1] += value
arr[...,2] += value

out = Image.fromarray(arr.astype('uint8'), 'RGB')

I am using the same image (a jpg).

the initial image initial image

the image with point using point

the image with arrays using arrays

How can they be so much different?

2
  • You have values greater than 255 in your array, which you then convert to uint8 ... what do you want those values to become in the image? Commented Nov 1, 2013 at 14:56
  • Actually your image looks right, but you've ruined palette (see previous comment). This link is relevant: stackoverflow.com/questions/2181292/… Commented Nov 1, 2013 at 14:58

2 Answers 2

4

You have values greater than 255 in your array, which you then convert to uint8 ... what do you want those values to become in the image? If you want them to be 255, clip them first:

out_arr_clip = Image.fromarray(arr.clip(0,255).astype('uint8'), 'RGB')

By the way, there's no need to add to each color band separately:

arr = np.asarray(img, dtype=float)   # also simplified
value = math.floor(255*float(50)/100)
arr += value                           # the same as doing this in three separate lines

If your value is different for each band, you can still do this because of broadcasting:

percentages = np.array([25., 50., 75.])
values = np.floor(255*percentages/100)
arr += values   # the first will be added to the first channel, etc.
Sign up to request clarification or add additional context in comments.

3 Comments

@Apostolos Yeah, clip is definitely easier, but kudos for solving it and posting your own solution :)
Thanks for helping me around...I am getting new to this image processing and its the first time i used numpy. Though arr contains alpha channel too and i don't want to alter it. So i have to do it to each band separately, i think i have to that is :)
@Apostolos Ah, I see; if you want to edit only channels 0,1,2, then you can still do it in one line! arr[...,:3] += value
1

Fixxed it :)

Didn't take under consideration getting out of bounds. So i did

for i in range(3):
    conditions = [arr[...,i] > 255, arr[...,i] < 0]
    choices = [255, 0]
    arr[...,i] = np.select(conditions, choices, default=arr[...,i]

Worked like a charm....:)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.