facerec_demo.py: Reworked demo to remove all matplotlib dependencies.
authorPhilipp Wagner <bytefish@gmx.de>
Mon, 30 Jul 2012 00:18:27 +0000 (02:18 +0200)
committerPhilipp Wagner <bytefish@gmx.de>
Mon, 30 Jul 2012 00:18:27 +0000 (02:18 +0200)
samples/python2/facerec_demo.py

index 1220acf..9fc2258 100644 (file)
 
 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)