average of PIL images

V

vaneric

hi
i have a set of RGB images of diff faces (of people )as a 2 dim
numpyarray
...something like
threefaces=array([[xa1,xa2,xa3],
[xb1,xb2,xb3],
[xc1,xc2,xc3]])
where xa1,xa2,xa3 are tuples each representing rgb values of a pixel
of first image ..

i need to create the average face image and display it.problem is i
need to calculate (xa1+xb1+xc1)/3 etc to calculate avearge value of
each pixel.how can i do this calculation.do i need to convert the
r,g,b in to a single value for each pixel? the average value of a
pixel will be a float isn't it? how can i create a PIL image from
this?
any help,directive greatly appreciated
eric
 
R

Robert Kern

vaneric said:
hi
i have a set of RGB images of diff faces (of people )as a 2 dim
numpyarray
..something like
threefaces=array([[xa1,xa2,xa3],
[xb1,xb2,xb3],
[xc1,xc2,xc3]])
where xa1,xa2,xa3 are tuples each representing rgb values of a pixel
of first image ..

i need to create the average face image and display it.problem is i
need to calculate (xa1+xb1+xc1)/3 etc to calculate avearge value of
each pixel.how can i do this calculation.
threefaces.mean(axis=0)

do i need to convert the
r,g,b in to a single value for each pixel?

It depends on the problem that you are trying to solve. If monochrome images are
acceptable for your problem, then it is probably best to convert all your images
to monochrome to do the averaging. At least for a first cut. Averaging color
images is tricky; you really shouldn't do it in the RGB colorspace. There are a
couple of colorspaces which you could choose; different problems require
different colorspaces.
the average value of a
pixel will be a float isn't it?
Yes.

how can i create a PIL image from
this?

# Cast the floating point data to bytes.
avgface = avgface.astype(numpy.uint8)

# Create the PIL image from the numpy data.
img = Image.fromstring('L', (width, height), avgface.tostring())

--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco
 
L

Larry Bates

vaneric said:
hi
i have a set of RGB images of diff faces (of people )as a 2 dim
numpyarray
..something like
threefaces=array([[xa1,xa2,xa3],
[xb1,xb2,xb3],
[xc1,xc2,xc3]])
where xa1,xa2,xa3 are tuples each representing rgb values of a pixel
of first image ..

i need to create the average face image and display it.problem is i
need to calculate (xa1+xb1+xc1)/3 etc to calculate avearge value of
each pixel.how can i do this calculation.do i need to convert the
r,g,b in to a single value for each pixel? the average value of a
pixel will be a float isn't it? how can i create a PIL image from
this?
any help,directive greatly appreciated
eric

Take a look at ImageChops.difference. I've used it to calculate a
difference value as follows:

diff=ImageChops.difference(im1, im2)
totaldiff=sum(ImageStat.Stat(diff)._getmedian())

Maybe at least this will point you in the right direction.

-Larry Bates
 
7

7stud

hi
i have a set of RGB images of diff faces (of people )as a 2 dim
numpyarray
..something like
threefaces=array([[xa1,xa2,xa3],
       [xb1,xb2,xb3],
       [xc1,xc2,xc3]])
where xa1,xa2,xa3 are  tuples each representing rgb values of a pixel
of first image ..

i need to create the average face image and display it.problem is i
need to calculate (xa1+xb1+xc1)/3  etc to calculate avearge value of
each pixel.how can i do this calculation.do i need to convert the
r,g,b in to a single value for each pixel? the average value of a
pixel will be a float isn't it? how can i create a PIL image from
this?
any help,directive greatly appreciated
eric

import Numeric

arr = Numeric.array([
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
[10, 11, 12]
])

col1 = arr[0:,0]
print col1

sum = 0
count = 0
for num in col1:
sum += num
count += 1

avg = (sum * 1.0)/count #convert one term to a float to get float
result
print avg
print round(avg)
print int(round(avg))


print arr[0]

size = len(arr[0])
for i in range(size):
col = arr[0:, i]
sum = 0
count = 0

for num in col:
sum += num
count += 1

result = (sum * 1.0) /count
print result,
result = int(round(result))
print result

--output:--
[ 1 4 7 10]
5.5
6.0
6
[1 2 3]
5.5 6
6.5 7
7.5 8
 
7

7stud

hi
i have a set of RGB images of diff faces (of people )as a 2 dim
numpyarray
..something like
threefaces=array([[xa1,xa2,xa3],
       [xb1,xb2,xb3],
       [xc1,xc2,xc3]])
where xa1,xa2,xa3 are  tuples each representing rgb values of a pixel
of first image ..
i need to create the average face image and display it.problem is i
need to calculate (xa1+xb1+xc1)/3  etc to calculate avearge value of
each pixel.how can i do this calculation.do i need to convert the
r,g,b in to a single value for each pixel? the average value of a
pixel will be a float isn't it? how can i create a PIL image from
this?
any help,directive greatly appreciated
eric

import Numeric

arr = Numeric.array([
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9],
    [10, 11, 12]
])

col1 = arr[0:,0]
print col1

sum = 0
count = 0
for num in col1:
    sum += num
    count += 1

avg = (sum * 1.0)/count   #convert one term to a float to get float
result
print avg
print round(avg)
print int(round(avg))

print arr[0]

size = len(arr[0])
for i in range(size):
    col = arr[0:, i]
    sum = 0
    count = 0

    for num in col:
        sum += num
        count += 1

    result = (sum * 1.0) /count
    print result,
    result = int(round(result))
    print result

--output:--
[ 1  4  7 10]
5.5
6.0
6
[1 2 3]
5.5 6
6.5 7
7.5 8

In this statement:
col1 = arr[0:,0]

the first term is the row or row range, and the second term is the
column or column range. If you write this:

num = arr[0,0]

you get the element in row 0, column 0. But you can also specify
ranges for each col or row:

num = arr[1:, 2:]

That says to get all elements from row 1 to the bottom that are in
from column 2 to the end of the row.
 
7

7stud

num = arr[1:, 2:]

That says to get all elements from row 1 to the bottom that are in
from column 2 to the end of the row.

err..

That says to get all elements from row 1 to the last row which are in
column 2, column 3, etc. to the end of the row.
 
V

vaneric

Averaging color
images is tricky; you really shouldn't do it in the RGB colorspace.
hi,
thanx for the guidance and detailed replies..I tried to pack the
r,g,b into a single value like below(something a member posted in the
past)

def rgbTopixelvalue((r,g,b)):
alpha=255
return unpack("l", pack("BBBB", b, g, r, alpha))[0]


if i apply this for all images i can represent each image as an array
of longs instead of tuples.then for a pixel i can calculate the
average value
after this if i do the casting as you advised and create the avg
image
avgface = avgface.astype(numpy.uint8)
img = Image.fromstring('L', (width, height), avgface.tostring())

is there something wrong with my approach? I am a newbie in PIL/
imageprocessing ..so i would greately appreciate feedback
eric
 
V

vaneric

Averaging color
images is tricky; you really shouldn't do it in the RGB colorspace.

hi,
thanx for the guidance and detailed replies..I tried to pack the
r,g,b into a single value like below(something a member posted in the
past)

def rgbTopixelvalue((r,g,b)):
alpha=255
return unpack("l", pack("BBBB", b, g, r, alpha))[0]

if i apply this for all images i can represent each image as an array
of longs instead of tuples.then for a pixel i can calculate the
average value
after this if i do the casting as you advised and create the avg
image
avgface = avgface.astype(numpy.uint8)

here if i use these pixelvalues to create an imag
img =Image.fromstring('RGB', (width, height), avgface.tostring())
it will fail because of -'not enough image data'..is there an
alternative to create average rgb color image ?(i want to keep the rgb
so can't convert to greyscale)

is there something wrong with my approach? I am a newbie in PIL/
imageprocessing ..so i would greately appreciate feedback
eric
 
G

Gabriel Genellina

Averaging color
images is tricky; you really shouldn't do it in the RGB colorspace.

hi,
thanx for the guidance and detailed replies..I tried to pack the
r,g,b into a single value like below(something a member posted in the
past)

def rgbTopixelvalue((r,g,b)):
alpha=255
return unpack("l", pack("BBBB", b, g, r, alpha))[0]

That's much worse than averaging the R,G,B components. First, you have to
omit the alfa value (or set it at the end). Then, consider this example:
(0,0,0)=black and (0,1,0)=almost black, average = (0,0,128) = dark blue, a
total nonsense.

As said above, try to compute using another color space, try HSL. The
colorsys module can transform from/to RGB.
 
V

vaneric

def rgbTopixelvalue((r,g,b)):
alpha=255
return unpack("l", pack("BBBB", b, g, r, alpha))[0]

That's much worse than averaging the R,G,B components.

oops!
the intention was to pack r,g,b components into a single value sothat
calculations like finding covariant matrix of a set of images etc can
be done..(i need to represent each image as an array of values(either
long or float)..i can't work with an array of tuples of ints..
As said above, try to compute using another color space, try HSL. The
colorsys module can transform from/to RGB.

even if i convert from rgb to hsl i will have a tuple(h,s,l) for each
pixel and again i will have to convert it into a single value which i
can use in matrix multipln etc

is there a workaround sothat rgb color images can be worked on? any
advice most welcome..
 
7

7stud

hi,
thanx for the guidance and detailed replies..I  tried  to pack the
r,g,b into a single value like below(something a member posted in the
past)
def rgbTopixelvalue((r,g,b)):
   alpha=255
   return unpack("l", pack("BBBB", b, g, r, alpha))[0]

That's much worse than averaging the R,G,B components. First, you have to  
omit the alfa value (or set it at the end). Then, consider this example:  
(0,0,0)=black and (0,1,0)=almost black, average = (0,0,128)

How do you arrive at that average?
 
G

Gabriel Genellina

Averaging color
images is tricky; you really shouldn't do it in the RGB colorspace.
thanx for the guidance and detailed replies..I  tried  to pack the
r,g,b into a single value like below(something a member posted in the
past)
def rgbTopixelvalue((r,g,b)):
   alpha=255
   return unpack("l", pack("BBBB", b, g, r, alpha))[0]
That's much worse than averaging the R,G,B components. First, you have to  
omit the alfa value (or set it at the end). Then, consider this example:  
(0,0,0)=black and (0,1,0)=almost black, average = (0,0,128)

How do you arrive at that average?

(0,0,0) -> 0, (0,1,0) -> 256, (0+256)/2=128, 128 -> (0,0,128)
(ignoring alpha, or using alpha=0)
 
G

Gabriel Genellina

def rgbTopixelvalue((r,g,b)):
   alpha=255
   return unpack("l", pack("BBBB", b, g, r, alpha))[0]
That's much worse than averaging the R,G,B components.

oops!
the intention was to pack r,g,b components into a single value sothat
calculations like finding covariant matrix of a set of images etc can
be done..(i need to represent each image as an array of  values(either
long or float)..i can't work with an array of tuples of ints..
As said above, try to compute using another color space, try HSL. The
colorsys module can transform from/to RGB.

even if i convert from rgb to hsl i will have a tuple(h,s,l) for each
pixel and again i will have to convert it into a single value which i
can use in matrix multipln etc

is there a workaround sothat rgb color images can be worked on? any
advice most welcome..

a) Work with the 3 components in parallel (that is, use 3 separate
matrices, one for each component, and regenerate the image at the
end).

b) Convert to grayscale (and lose the color information)
 
V

vaneric

a) Work with the 3 components in parallel (that is, use 3 separate
matrices, one for each component, and regenerate the image at the
end).

that wd be ok for image generation ..but to calculate covariance
matrix from the set of images i don't know if it wd work

eric
 
D

Dennis Lee Bieber

hi,
thanx for the guidance and detailed replies..I tried to pack the
r,g,b into a single value like below(something a member posted in the
past)

def rgbTopixelvalue((r,g,b)):
alpha=255
return unpack("l", pack("BBBB", b, g, r, alpha))[0]

if i apply this for all images i can represent each image as an array
of longs instead of tuples.then for a pixel i can calculate the
average value

That's a rather meaningless average. Pure white and pure black
encode (is alpha x00 or xFF opaque; assume x00 is opaque):

xFFFFFF00 white
x00000000 black

x7FFFFF80 "average"

7F = half blue
FF = full green
FF = full red
80 = half transparent

But the "color" halfway between white and black should be:

x7F7F7F00

For white/black, this works as it is essentially a luminosity
rating. But what is the "average" of red and blue?

xFF000000
x0000FF00

x7F007F00 ?

That's a half intensity magenta, but wouldn't full intensity be more
appropriate given the inputs were full intensity?

If you convert to an HLS style, red is 0deg, green is 120deg, blue
is 240deg (and L/S is something like 100% for both samples)

SIMPLE average 0deg + 240deg would give 120deg... Whoa -- the average of
red and blue is green? If you take into account the shorter path
distance, 0deg + (-120deg) give -60deg, or 300deg -- magenta again.

--
Wulfraed Dennis Lee Bieber KD6MOG
(e-mail address removed) (e-mail address removed)
HTTP://wlfraed.home.netcom.com/
(Bestiaria Support Staff: (e-mail address removed))
HTTP://www.bestiaria.com/
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,226
Members
46,815
Latest member
treekmostly22

Latest Threads

Top