Average face - algorithm


Quesion and code is at the end I hope this question belongs here and not to the TCS's stack. I am trying to go through algorithms in Turk and Pentland's "Eigenfaces for Recognition".

On page 74 one can read (last paragraph of left column):

Let the training (...) The average face of the set is defined by [*]

Where [*] is an equation saying that average face is equal to sum of images divided by it's count. In order to use this equantion I created python script using OpenCV and numpy.

On page 75 there is Figure 1. which should represent average face from Figure 1. (pg. 74) and this is what I am trying to achieve.

As a face set I am using all faces from Faces94. When I calculate traditionall average (1/M*sum) the result looks like this:

enter image description here

which is far away from expected, mostly because of those wierd 'spots'. However, when I calculate average like there was more faces than actually is (e.g. 1/(2*M) * sum) result looks more accurate:

enter image description here

I think there is some problem in converting int8<->int but I cannot prove it. If anyone can spot any problem with the code please let me know even if it is not solution.

Question: what am I doing wrong / what to do to get better results. Here is the code:

import numpy as np
import glob
import cv2
from cv2 import imread

dir = "../images/faces94/**/**.jpg"

files = list(glob.iglob(dir, recursive=True))
img = np.zeros(imread(files[0],0).shape)
img = img.astype('int')
for i in range(len(files)):
    img += imread(files[i],0).astype('int')

img = np.divide(img,len(files)*2) # HERE you can change it to np.divide(img,len(files)) in order to see bad result
img = np.mod(img,128)
img = img.astype(np.int8)

cv2.imshow("image", img)

Show source
| python   | opencv   | algorithm   | numpy   2017-01-03 22:01 1 Answers

Answers ( 1 )

  1. 2017-01-03 22:01

    Thanks to @Divakar I found two problems in my code.

    1. Image arrays in opencv are based on uint8 not int8
    2. I was doing modulo (np.mod(img,128)) and because of it my image was ranged from 0 to 127 and should be from 0 to 255.
◀ Go back