Project 4 - Eigenfaces
Peter Lincoln
Having read that normal eigenface calculation may take a long time, I decided to implement the speed up. As a result, it only took a second to calculate these eigenfaces. The eigenfaces produced appeared to be different than other compared eigenfaces; however, this is likely due to the fact that different matrices are processed. The eigenfaces it does produce seem reasonable though.
Below are the set of ten eigenfaces calculated for the ten-eigenface calculations (at 25x25 pixels).
| Average | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
![]() |
|
|
|
|
|
|
|
|
|
|
As I was testing this program prior to running the experiments, I found that it wasn't detecting very well. I have managed to trace this to the constructFace method, used by the isFace method, called by findFace; however, I was unable to determine exactly what was causing the problem. Essentially, the isFace function should project the image into face coefficients using the eigenfaces. It should then reproject it back into an image and compare the two images by producing a mse value. Small mse values suggest that the image looks like a face since it wasn't strongly distorted by the projection operations. Projecting the face should compute coefficients for application to the eigenfaces to determine what the face is in face-space. Reprojecting should take the coefficients and produce an image in image space similar to the original, if the original is a face.
Instead, this is what I got:
| Original: | ![]() |
| Reprojection: | ![]() |
There is obviously a problem here, but as far as I can tell, the program is being ordered to do the right thing. To construct the image:
In any case, the faulty results here skew the possible results of later experiments. The large error values caused by the black & white image may make it difficult to distinguish between real and false-positive faces.
Since my eigen analysis was able to run very quickly, I was able to produce results from 1 through 27 eigenfaces at a step of 1. I found the following results:
![]() |
| Raw Data (Plain Text) |
| Summary (Spreadsheet) |
While no set of eigenfaces produced a perfect result, simply having two eigenfaces, in addition to the average face, achieved half of the maximal result. Additionally, to acheive the maximal result, use of all of the possible eigenfaces would be recommended. However, with only a small loss, around 11 to 21 eigenfaces could be used.
Additionally, while coverting the raw data into the summary for the plot, I noticed that several faces were never recognized, and some were consistant misrecognized as a particular image. Here are some examples:
| Non-Smiling Image | Correct Smiling Image | Most often Preferred Smiling Image |
![]() 1 |
![]() 1 |
![]() 22 |
![]() 7 |
![]() 7 |
![]() ![]() 14, 27 |
![]() 18 |
![]() 18 |
![]() ![]() ![]() 14, 23, 27 |
The first case error likely resulted from the different mouth shape and eye-opening-state. The angle of the head likely threw off image #7. Also the difference in teeth-display for case #18 probably threw that one off. The nose shapes of 1NS (not smiling) and 22S (smiling) could have resulted in that match. Similarly, the mouth shape of 18NS with 23S and 27S could have produced that match.
I also noticed that for several of the images that didn't recognize exactly their coresponding picture, they often declared the coresponding picture to be the second or third choice. While this didn't always occur, it did often.
Using the set of 10 eigenfaces already calculated before, I proceeded to crop the elf image, shown below. This was computed using <.45, .55, .01>
| Original | Best 10 Marked | Best Cropped |
![]() |
![]() |
![]() |
I didn't quite get overlap implemented so that is it why there is a lot of overlap. In any case, it didn't find the actual face; likely a result of the faulty reprojection which broke isFace(...).
Not having a good image of me on hand, I used my CSE ID photo taken when I joined the program a couple years ago. Before processing, I cropped the web image to remove my name from the bottom of the image. I used the following parameters to find this one: <0.1, 0.3, 0.01>
| Original | Best 10 Marked | Best Cropped |
![]() |
![]() |
![]() |
This one at least found a big portion of my face; however, it isn't quite centered, also likely due to the same reprojection glitch.
Here are the results of using the parameters <0.45, 0.55, 0.01> and searching for 10 faces instead of 3 (since overlap isn't working):
| Original | ![]() |
| Best 10 Marked | ![]() |
I found this image via goolgle search at the following address: http://www.stanford.edu/group/sarg/group_photo.JPG. Using two sets of parameters <0.3, 0.4, 0.01> and <0.35, 0.45, 0.01>.
| Original | ![]() |
| Best 10 Marked Set #1 <0.3, 0.4, 0.01> |
![]() |
| Best 10 Marked Set #2 <0.35, 0.45, 0.01> |
![]() |
While the first set of parameters produced more distinct results, the second set of parameters were generally closer to their faces.
Overall, the resulting program seems ill suited for accurately finding faces. However, it does seem to be able to be generally accurate in identifying user's faces given a different version of their faces if one allows for manually considering the top few results. Considering only the top face, however, results in an accuracy of around 55-60%.
Searching for faces within a picture generally fails with this implementation. However, if the projection fuction were made to work properly, then better results would likely be found.
Peter Lincoln