|
|
|
@ -34,15 +34,8 @@ |
|
|
|
|
|
|
|
|
|
import os |
|
|
|
|
import sys |
|
|
|
|
|
|
|
|
|
import PIL.Image as Image |
|
|
|
|
|
|
|
|
|
import numpy as np |
|
|
|
|
|
|
|
|
|
import matplotlib.pyplot as plt |
|
|
|
|
import matplotlib.cm as cm |
|
|
|
|
|
|
|
|
|
import cv2 |
|
|
|
|
import numpy as np |
|
|
|
|
|
|
|
|
|
def normalize(X, low, high, dtype=None): |
|
|
|
|
"""Normalizes a given array in X to a value between low and high.""" |
|
|
|
@ -58,6 +51,7 @@ def normalize(X, low, high, dtype=None): |
|
|
|
|
return np.asarray(X) |
|
|
|
|
return np.asarray(X, dtype=dtype) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def read_images(path, sz=None): |
|
|
|
|
"""Reads the images in a given folder, resizes images on the fly if size is given. |
|
|
|
|
|
|
|
|
@ -78,11 +72,10 @@ def read_images(path, sz=None): |
|
|
|
|
subject_path = os.path.join(dirname, subdirname) |
|
|
|
|
for filename in os.listdir(subject_path): |
|
|
|
|
try: |
|
|
|
|
im = Image.open(os.path.join(subject_path, filename)) |
|
|
|
|
im = im.convert("L") |
|
|
|
|
im = cv2.imread(os.path.join(subject_path, filename), cv2.IMREAD_GRAYSCALE) |
|
|
|
|
# resize to given size (if given) |
|
|
|
|
if (sz is not None): |
|
|
|
|
im = im.resize(sz, Image.ANTIALIAS) |
|
|
|
|
im = cv2.resize(im, sz) |
|
|
|
|
X.append(np.asarray(im, dtype=np.uint8)) |
|
|
|
|
y.append(c) |
|
|
|
|
except IOError, (errno, strerror): |
|
|
|
@ -92,49 +85,21 @@ def read_images(path, sz=None): |
|
|
|
|
raise |
|
|
|
|
c = c+1 |
|
|
|
|
return [X,y] |
|
|
|
|
|
|
|
|
|
def create_font(fontname='Tahoma', fontsize=10): |
|
|
|
|
"""Creates a font for the subplot.""" |
|
|
|
|
return { 'fontname': fontname, 'fontsize':fontsize } |
|
|
|
|
|
|
|
|
|
def subplot(title, images, rows, cols, sptitle="subplot", sptitles=[], colormap=cm.gray, ticks_visible=True, filename=None): |
|
|
|
|
"""This will ease creating a subplot with matplotlib a lot for us.""" |
|
|
|
|
fig = plt.figure() |
|
|
|
|
# main title |
|
|
|
|
fig.text(.5, .95, title, horizontalalignment='center') |
|
|
|
|
for i in xrange(len(images)): |
|
|
|
|
ax0 = fig.add_subplot(rows,cols,(i+1)) |
|
|
|
|
plt.setp(ax0.get_xticklabels(), visible=False) |
|
|
|
|
plt.setp(ax0.get_yticklabels(), visible=False) |
|
|
|
|
if len(sptitles) == len(images): |
|
|
|
|
plt.title("%s #%s" % (sptitle, str(sptitles[i])), create_font('Tahoma',10)) |
|
|
|
|
else: |
|
|
|
|
plt.title("%s #%d" % (sptitle, (i+1)), create_font('Tahoma',10)) |
|
|
|
|
plt.imshow(np.asarray(images[i]), cmap=colormap) |
|
|
|
|
if filename is None: |
|
|
|
|
plt.show() |
|
|
|
|
else: |
|
|
|
|
fig.savefig(filename) |
|
|
|
|
|
|
|
|
|
def imsave(image, title="", filename=None): |
|
|
|
|
"""Saves or shows (if no filename is given) an image.""" |
|
|
|
|
fig = plt.figure() |
|
|
|
|
plt.imshow(np.asarray(image)) |
|
|
|
|
plt.title(title, create_font('Tahoma',10)) |
|
|
|
|
if filename is None: |
|
|
|
|
plt.show() |
|
|
|
|
else: |
|
|
|
|
fig.savefig(filename) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__": |
|
|
|
|
# This is where we write the images, if an output_dir is given |
|
|
|
|
# in command line: |
|
|
|
|
out_dir = None |
|
|
|
|
# You'll need at least a path to your image data, please see |
|
|
|
|
# the tutorial coming with this source code on how to prepare |
|
|
|
|
# your image data: |
|
|
|
|
if len(sys.argv) != 2: |
|
|
|
|
print "USAGE: facerec_demo.py </path/to/images>" |
|
|
|
|
if len(sys.argv) < 2: |
|
|
|
|
print "USAGE: facerec_demo.py </path/to/images> [</path/to/store/images/at>]" |
|
|
|
|
sys.exit() |
|
|
|
|
# Now read in the image data. This must be a valid path! |
|
|
|
|
[X,y] = read_images(sys.argv[1]) |
|
|
|
|
if len(sys.argv) == 3: |
|
|
|
|
out_dir = sys.argv[2] |
|
|
|
|
# Create the Eigenfaces model. We are going to use the default |
|
|
|
|
# parameters for this simple example, please read the documentation |
|
|
|
|
# for thresholding: |
|
|
|
@ -166,17 +131,26 @@ if __name__ == "__main__": |
|
|
|
|
# Now let's get some data: |
|
|
|
|
mean = model.getMat("mean") |
|
|
|
|
eigenvectors = model.getMat("eigenvectors") |
|
|
|
|
cv2.imwrite("test.png", X[0]) |
|
|
|
|
# We'll save the mean, by first normalizing it: |
|
|
|
|
mean_norm = normalize(mean, 0, 255) |
|
|
|
|
mean_resized = mean_norm.reshape(X[0].shape) |
|
|
|
|
imsave(mean_resized, "Mean Face", "mean.png") |
|
|
|
|
if out_dir is None: |
|
|
|
|
cv2.imshow("mean", np.asarray(mean_resized, dtype=np.uint8)) |
|
|
|
|
else: |
|
|
|
|
cv2.imwrite("%s/mean.png" % (out_dir), np.asarray(mean_resized, dtype=np.uint8)) |
|
|
|
|
# Turn the first (at most) 16 eigenvectors into grayscale |
|
|
|
|
# images. You could also use cv::normalize here, but sticking |
|
|
|
|
# to NumPy is much easier for now. |
|
|
|
|
# Note: eigenvectors are stored by column: |
|
|
|
|
SubplotData = [] |
|
|
|
|
for i in xrange(min(len(X), 16)): |
|
|
|
|
eigenvector_i = eigenvectors[:,i].reshape(X[0].shape) |
|
|
|
|
SubplotData.append(normalize(eigenvector_i, 0, 255)) |
|
|
|
|
# Plot them and store the plot to "python_eigenfaces.png" |
|
|
|
|
subplot(title="Eigenfaces AT&T Facedatabase", images=SubplotData, rows=4, cols=4, sptitle="Eigenface", colormap=cm.jet, filename="eigenfaces.png") |
|
|
|
|
eigenvector_i_norm = normalize(eigenvector_i, 0, 255) |
|
|
|
|
# Show or save the images: |
|
|
|
|
if out_dir is None: |
|
|
|
|
cv2.imshow("%s/eigenvector_%d" % (out_dir,i), np.asarray(eigenvector_i_norm, dtype=np.uint8)) |
|
|
|
|
else: |
|
|
|
|
cv2.imwrite("%s/eigenvector_%d.png" % (out_dir,i), np.asarray(eigenvector_i_norm, dtype=np.uint8)) |
|
|
|
|
# Show the images: |
|
|
|
|
if out_dir is None: |
|
|
|
|
cv2.waitKey(0) |
|
|
|
|