mirror of
https://github.com/jlengrand/Ivolution.git
synced 2026-03-10 08:21:18 +00:00
Adds Documentation for the code. Trying to include Sphinx auto generated doc
This commit is contained in:
@@ -10,7 +10,7 @@ The main difference with everyday is that Facemovie searches automatically for f
|
||||
|
||||
Due to its general implementation, FaceMovie may be used for faces, but also profiles (for projects showing [women along pregnancy for example](http://www.youtube.com/watch?v=CG_KArKYTq4) or full body([for people workouting](http://www.youtube.com/watch?v=02Pzfv7JV48)). The only limitation comes from you !
|
||||
|
||||
**[You can check out an example of video here.](http://www.youtube.com/watch?v=2pUHK7Sf23I)**
|
||||
**[You can check out an example of video here.](http://www.youtube.com/watch?v=2pUHK7Sf23I)**.
|
||||
|
||||
|
||||
## Getting started
|
||||
@@ -24,7 +24,7 @@ Please not that you best pick as this stage would be to choose the executable.
|
||||
This is the current safest and easiest solution for you.
|
||||
|
||||
Download the archive available [here](). By default, choose the full archive.
|
||||
The light archive is intended for users having Python2.7 already installed on their system.
|
||||
The light archive is intended for users having Python2.7 already installed on their system. In this case, a python.dll is given with the executable.
|
||||
|
||||
Uncompress the archive. It contains three elements :
|
||||
- The executable itself, called Facemovifier.exe.
|
||||
@@ -195,4 +195,6 @@ I never experienced any problem using the software, but you should always back u
|
||||
I would enjoy having feedback if you like this idea, or even used it. Send me a link to your creations so that I can put them here !
|
||||
Feel free to mail me for any comment or request.
|
||||
|
||||
You can contact me at julien at lengrand dot fr, or on my [current website](http://www.lengrand.fr).
|
||||
You can contact me at julien at lengrand dot fr, or on my [current website](http://www.lengrand.fr).
|
||||
|
||||
Version : 0.8.1
|
||||
143
README.rst
143
README.rst
@@ -1,143 +0,0 @@
|
||||
Take one picture of yourself a day, simply get the results!
|
||||
===========================================================
|
||||
|
||||
**`FaceMovie <http://www.youtube.com/watch?v=JueOY7EtXrQ>`_** is a
|
||||
simple project that aims at helping you create videos of yourself over
|
||||
time, using photos as input. I see a growing interest for this kind of
|
||||
projects, where people take one picture of themselves a day for several
|
||||
months (years ?) and compile it into a
|
||||
`video <http://www.youtube.com/watch?v=6B26asyGKDo>`_. I started this
|
||||
project for a friend currently `travelling around the
|
||||
world <http://http://ungrandtour.blogspot.com/>`_. He wanted to create a
|
||||
video of his face changes along the trip.
|
||||
|
||||
The main idea is simple. The software takes a batch of images as input.
|
||||
The images are assumed to be named by date (so that an alphabetical
|
||||
order is also the chronological order). The output is a video containing
|
||||
each image, where the face is always placed in the same position. This
|
||||
way, people can actually see the face change over time.
|
||||
|
||||
**`You can check out the last results in video here
|
||||
! <http://www.youtube.com/watch?v=JueOY7EtXrQ>`_**
|
||||
|
||||
\*\*In progress: \*\*
|
||||
|
||||
- The very central part of the code is finished.
|
||||
- I currently work on video quality enhancement (compression, speed,
|
||||
fade effects, ...)
|
||||
- I plan to include a GUI to help people use the software, and later
|
||||
add support for a broader type of input images (profiles, eyes,
|
||||
glasses, . . .)
|
||||
- I also think about a way for user to help the software in case it
|
||||
struggles with images (by manually pointing face on problematic
|
||||
images?).
|
||||
- Any other idea is welcome
|
||||
|
||||
Getting started
|
||||
---------------
|
||||
|
||||
I have just started searching for a nice way to package the application
|
||||
in a single executable, which means if you want to test Facemovie you
|
||||
will have to directly run the code in the development branch.
|
||||
|
||||
In this part, I will thus consider that you have Python 2.7 and OpenCV
|
||||
(and of course its Python bindings) installed on your machine. To get
|
||||
the last version of Facemovie, simply clone the project from Github
|
||||
``git clone git://github.com/jlengrand/FaceMovie.git``
|
||||
|
||||
You will also need to have a bunch of photos of your face stored in a
|
||||
folder. Those images should contain only one person; and you should try
|
||||
to always keep the same angle with the camera. If you dont, some samples
|
||||
are included in the project (placed in data/input/Axel)
|
||||
|
||||
Since version 0.4, Facemovie supports user interaction through the
|
||||
Facemovifier. That means that you should be able to run the application
|
||||
without modifying it. If you are like me, you ight want to start by
|
||||
calling the helper : ``$ python Facemoviefier -h`` which will list the
|
||||
available parameters in the application.
|
||||
|
||||
The simplest example you can run would be :
|
||||
``$ python Facemoviefier -i input_folder -o output_folder`` , where
|
||||
input\_folder and output\_folder are strings. If you place yourself in
|
||||
the facemovie folder and run the application from here, this line should
|
||||
work :
|
||||
``$ python Facemoviefier -i "../data/input/Axel" -o "../data/output"``
|
||||
|
||||
If you decide to run the Facemovifier from another location, you should
|
||||
update the folders accordingly, and use the root\_folder option:
|
||||
``$ python Facemoviefier -i input_folder -o output_folder -r facemovie_folder_location``
|
||||
|
||||
You might want to save images instead of a movie as output:
|
||||
``$ python Facemoviefier -i "../data/input/Axel" -o "../data/output" -t i``
|
||||
|
||||
And if you have profile images, you can (must) also decide to change the
|
||||
file used for training the classifier:
|
||||
``$ python Facemoviefier -i "../data/input/Axel" -o "../data/output" -p "profile face"``
|
||||
An extensive list of training files is available while calling the
|
||||
helper.
|
||||
|
||||
Options available in the Facemoviefier
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
**Required :**
|
||||
|
||||
- -i, --input : Input folder of the images to be processed
|
||||
- -o, --output : Output folder where the final results will be saved
|
||||
|
||||
**Optional :**
|
||||
|
||||
- -h, --help : Shows help message and exits
|
||||
- -r, --root : Location of the facemovie folder. Required if you run
|
||||
the Facemovifier from an external location
|
||||
- -e, --equalize : If this option is activated, images will NOT be
|
||||
resized so that all faces have the same size.
|
||||
- -p, --param: Used to change the file used to train the classifier.
|
||||
Useful you want to detect something else than front faces.
|
||||
- -t, --type : The type of output to be created. Can be either images,
|
||||
video or simple display (nothing written on disc).
|
||||
|
||||
Libraries
|
||||
---------
|
||||
|
||||
This piece of code is developed in `Python <http://www.python.org/>`_,
|
||||
simply because I love it :P (and because it allows easy testing while
|
||||
developing Image Processing applications). I used Python 2.7 for
|
||||
development. The only library needed to run the code for now is
|
||||
`Opencv <http://opencv.willowgarage.com/wiki/>`_ (and by extension
|
||||
`Numpy <http://numpy.scipy.org/>`_). See `the
|
||||
documentation <http://opencv.willowgarage.com/wiki/InstallGuide>`_ for
|
||||
more information.
|
||||
|
||||
This project is developed on a Windows (7) platform, but there should
|
||||
(and, as a fanatic Linux User, will) be no compatibility problems with
|
||||
UNIX.
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
This project is released under the new BSD license (3 clauses version).
|
||||
You can read more about the license in the LICENSE file.
|
||||
|
||||
Acknowledgment
|
||||
--------------
|
||||
|
||||
This project comes from an idea of Axel Catoire, currently `travelling
|
||||
around the world <http://ungrandtour.blogspot.com/>`_ with his
|
||||
girlfriend. He also provides me with new pictures :).
|
||||
|
||||
As a starter for my code, I used an excellent example from JAPSKUA, that
|
||||
you can find
|
||||
`here <http://japskua.wordpress.com/2010/08/04/detecting-eyes-with-python-opencv/>`_
|
||||
|
||||
Contact
|
||||
-------
|
||||
|
||||
I would enjoy having feedback if you like this idea, or even used it
|
||||
(even though you should change the source code to run it for now :) ). I
|
||||
would also like to know if you have heard about any other solution to
|
||||
make this kind of stuff ! (Couldn't find any but this Iphone
|
||||
`app <http://everyday-app.com/>`_ on the internet !) Feel free to mail
|
||||
me for any comment or request.
|
||||
|
||||
You can contact me at julien at lengrand dot fr, or on my `current
|
||||
website <http://www.lengrand.fr>`_.
|
||||
@@ -1,17 +1,30 @@
|
||||
'''
|
||||
Created on 29 mars 2012
|
||||
"""
|
||||
.. module:: Eye
|
||||
:platform: Unix, Windows
|
||||
:synopsis: Class defining an Eye in the sense of the FaceMovie
|
||||
|
||||
@author: jll
|
||||
'''
|
||||
.. moduleauthor:: Julien Lengrand-Lambert <jlengrand@gmail.com>
|
||||
|
||||
"""
|
||||
|
||||
class Eye(object):
|
||||
'''
|
||||
Created is an Eye-like blob is found using the Face Detection algorithm.
|
||||
'''
|
||||
"""
|
||||
Eye-like blob used in the Face Detection algorithm.
|
||||
|
||||
.. note::
|
||||
|
||||
This class **is not used for now**, but should get useful when implementing
|
||||
the use interaction feature
|
||||
"""
|
||||
def __init__(self):
|
||||
'''
|
||||
Constructor
|
||||
'''
|
||||
"""A facemovie redefinition of the human eye
|
||||
Args:
|
||||
x_pos (int) : x position of the eye in the image (in pixels)
|
||||
y_pos (int) : y position of the eye in the image (in pixels)
|
||||
x_size (int) : x size of the blob (in pixels)
|
||||
y_size (int) : y size of the blob (in pixels)
|
||||
conf (float) : confidence indice, indicating the probability of the target to actually be an eye
|
||||
"""
|
||||
x_pos = None # x position of the eye in the image
|
||||
y_pos = None # y position of the eye in the image
|
||||
x_size = None # x size of the blob in pixel
|
||||
|
||||
@@ -1,17 +1,30 @@
|
||||
'''
|
||||
Created on 29 mars 2012
|
||||
"""
|
||||
.. module:: Face
|
||||
:platform: Unix, Windows
|
||||
:synopsis: Class defining a Face in the sense of the FaceMovie
|
||||
|
||||
@author: jll
|
||||
'''
|
||||
.. moduleauthor:: Julien Lengrand-Lambert <jlengrand@gmail.com>
|
||||
|
||||
"""
|
||||
|
||||
class Face(object):
|
||||
'''
|
||||
Created is an Face-like blob is found using the Face Detection algorithm.
|
||||
'''
|
||||
"""
|
||||
Face-like blob used in the Face Detection algorithm.
|
||||
|
||||
.. note::
|
||||
|
||||
This class is the very root of our detection part for now; as Eye is not yet used.
|
||||
We use Faces to store data while processing images
|
||||
"""
|
||||
def __init__(self):
|
||||
'''
|
||||
Constructor
|
||||
'''
|
||||
"""A facemovie redifinition of the human face.
|
||||
|
||||
x_pos (int) : x position of the face in the image (in pixels)
|
||||
y_pos (int) : y position of the face in the image (in pixels)
|
||||
x_size (int) : x size of the blob (in pixels)
|
||||
y_size (int) : y size of the blob (in pixels)
|
||||
conf (float) : confidence indice, indicating the probability of the target to actually be an face
|
||||
"""
|
||||
x_center = None # x position of the face in the image
|
||||
y_center = None # y position of the face in the image
|
||||
x_size = None # x size of the blob in pixel
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
'''
|
||||
Created on 30 mars 2012
|
||||
"""
|
||||
.. module:: FaceParams
|
||||
:platform: Unix, Windows
|
||||
:synopsis: Simple class used to store parameters used for Face detection.
|
||||
|
||||
@author: jll
|
||||
'''
|
||||
.. moduleauthor:: Julien Lengrand-Lambert <jlengrand@gmail.com>
|
||||
|
||||
"""
|
||||
import cv
|
||||
import os
|
||||
|
||||
@@ -13,12 +16,21 @@ class FaceParams(object):
|
||||
Simple class used to store parameters used for Face detection
|
||||
'''
|
||||
def __init__(self, xml_folder, training_type, i_scale=2, h_scale=1.2, h_flags=0, mn=2):
|
||||
'''
|
||||
Constructor
|
||||
'''
|
||||
# Creates dictionary for all types of training files
|
||||
# some of them shall never be used. Perhaps would it be good to lower the dict size, or hide some of them
|
||||
# postpend .xml
|
||||
"""
|
||||
Creates dictionary for all types of training files
|
||||
some of them shall never be used. Perhaps would it be good to lower the dict size, or hide some of them
|
||||
postpend .xml
|
||||
|
||||
Args:
|
||||
xml_folder (string) : the location where xml files are located
|
||||
training_type (string) : the type of profile we are going to use
|
||||
KArgs:
|
||||
i_scale (float) : Image scaling chosen for classification
|
||||
h_scale (float) : Haar scaling chosen for classification
|
||||
h_flags (int) : the chosen number of haar flags
|
||||
mn (int) : the Minimum number of neighbors to be defined
|
||||
"""
|
||||
|
||||
cascade_name = training_types.simple_set[training_type] + ".xml"
|
||||
# Setting up some default parameters for Face Detection
|
||||
print os.path.join(xml_folder, cascade_name)
|
||||
|
||||
@@ -1,27 +1,43 @@
|
||||
'''
|
||||
Created on 27 mars 2012
|
||||
"""
|
||||
.. module:: Facemovie
|
||||
:platform: Unix, Windows
|
||||
:synopsis: Main class of the application. Contains the core image processing
|
||||
functions.
|
||||
Plays the role of a controller for the application, as it supports the
|
||||
communication layer with the end user interface.
|
||||
|
||||
@author: jll
|
||||
'''
|
||||
.. moduleauthor:: Julien Lengrand-Lambert <jlengrand@gmail.com>
|
||||
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
|
||||
import cv
|
||||
|
||||
from facemovie.lib import exif
|
||||
|
||||
from facemovie import Guy
|
||||
|
||||
|
||||
class FaceMovie(object):
|
||||
'''
|
||||
Main class of the whole application.
|
||||
Contains the core image processing functions.
|
||||
Supports the communication layer with the end user interface.
|
||||
Takes a bunch of parameters and a list of images and tries to create a
|
||||
video out of it.
|
||||
Contains general methods, aimed at being used trough an interface.
|
||||
'''
|
||||
def __init__(self, in_folder, out_folder, face_params):
|
||||
'''
|
||||
Constructor
|
||||
'''
|
||||
"""
|
||||
Initializes all parameters of the application. Input and output folders
|
||||
are defined, together with the classifier profile.
|
||||
|
||||
Args:
|
||||
in_folder (string) : the location where input files will be
|
||||
searched
|
||||
out_folder (string) : the location where the outputs will be
|
||||
saved
|
||||
face_param (string) : the location of the profile file used
|
||||
to train the classifier
|
||||
"""
|
||||
self.source= in_folder # Source folder for pictures
|
||||
self.out = out_folder # Folder to save outputs
|
||||
|
||||
@@ -54,13 +70,19 @@ class FaceMovie(object):
|
||||
def set_crop_dims(self, crop_x, crop_y):
|
||||
"""
|
||||
Sets the cropping dimension in case they have been provided by the end user
|
||||
|
||||
Args:
|
||||
crop_x (int) : dimension of the desired cropping in x (in number of face size)
|
||||
crop_y (int) : dimension of the desired cropping in y (in number of face size)
|
||||
"""
|
||||
self.cropdims = [crop_x, crop_y]
|
||||
|
||||
def list_guys(self):
|
||||
"""
|
||||
Aims at populating the guys list, using the source folder as an input.
|
||||
Guys list shall be sorted by file name alphabetical order
|
||||
Guys list shall be sorted chronologically.
|
||||
In case no valid date is found, it is set to ''.
|
||||
|
||||
"""
|
||||
try:
|
||||
os.path.exists(self.source)
|
||||
@@ -100,6 +122,10 @@ class FaceMovie(object):
|
||||
"""
|
||||
Searches for all faces in the guys we have
|
||||
Results to be stored directly in guys
|
||||
|
||||
Takes each image one after the other, and create a guy out of it.
|
||||
The Face of each guy is searched.
|
||||
In case no face is found, a warning is returned and Guy is set to None
|
||||
"""
|
||||
for a_guy in self.guys:
|
||||
a_guy.search_face(self.face_params)
|
||||
@@ -111,6 +137,11 @@ class FaceMovie(object):
|
||||
def normalize_faces(self, reference=0):
|
||||
"""
|
||||
Creates new images, normalized by face size
|
||||
A reference is given in input. The idea is to get all images to have the
|
||||
same size in Guy.
|
||||
|
||||
KArgs:
|
||||
reference (int) : the reference size of the face that we want to have
|
||||
"""
|
||||
# FIXME: May be enhanced by choosing a more educated reference
|
||||
if reference == 0:
|
||||
@@ -125,6 +156,8 @@ class FaceMovie(object):
|
||||
"""
|
||||
Returns the mean size of all faces in input
|
||||
Used to correctly crop images
|
||||
|
||||
**Designed for internal use only**
|
||||
"""
|
||||
tot_x = 0
|
||||
tot_y = 0
|
||||
@@ -139,8 +172,10 @@ class FaceMovie(object):
|
||||
self.face_mean = [float(tot_x) / nb_face, float(tot_y) / nb_face]
|
||||
|
||||
def find_crop_dims(self):
|
||||
"""
|
||||
"""
|
||||
Calculates smallest output image that can be used to avoid adding black borders on image
|
||||
It will later be used to create the final image.
|
||||
The idea is the same as for :func:find_out_dims , but while avoiding black brders.
|
||||
"""
|
||||
ht = 1000000 # space left above eyes
|
||||
hb = 1000000 # space left beneath eyes
|
||||
@@ -184,6 +219,10 @@ class FaceMovie(object):
|
||||
"""
|
||||
Calculates best output image size and position depending on
|
||||
faces found in guys.
|
||||
The system is simple. The output image should be as big as possible,
|
||||
and faces are always placed in the same position. Depending on that,
|
||||
the image input image is placed in the output at the correct position.
|
||||
Black borders are set everywhere else.
|
||||
"""
|
||||
# FIXME: badly done !
|
||||
for a_guy in self.guys:
|
||||
@@ -213,6 +252,9 @@ class FaceMovie(object):
|
||||
def crop_im(self, image):
|
||||
"""
|
||||
If needed, crops the image to avoid having black borders.
|
||||
|
||||
Args:
|
||||
image (IplImage) : the image to be cropped
|
||||
"""
|
||||
# TODO : implement
|
||||
width = self.width#[0, 0]
|
||||
@@ -237,7 +279,9 @@ class FaceMovie(object):
|
||||
"""
|
||||
Show all faces that have been found for the guys.
|
||||
The time for which each image will be displayed can be chosen.
|
||||
Several modes can be chosen to adapt the result.
|
||||
|
||||
KArgs :
|
||||
mytime (int) : time for which the image should be displayed (in ms)
|
||||
"""
|
||||
for a_guy in self.guys:
|
||||
if a_guy.has_face():
|
||||
@@ -252,7 +296,12 @@ class FaceMovie(object):
|
||||
def save_faces(self, out_folder, im_format="png"):
|
||||
"""
|
||||
Save all faces into out_folder, in the given image format
|
||||
Debug is used to draw rectangles around found faces
|
||||
|
||||
Args:
|
||||
out_folder (string) : the location where to save the output image.
|
||||
|
||||
KArgs :
|
||||
mytime (int) : time for which the image should be displayed (in ms)
|
||||
"""
|
||||
for a_guy in self.guys:
|
||||
if a_guy.has_face():
|
||||
@@ -269,9 +318,11 @@ class FaceMovie(object):
|
||||
Creates a movie with all faces found in the inputs.
|
||||
Guy is skipped if no face is found.
|
||||
|
||||
TODO : No codec involved !
|
||||
TODO : Can FPS be changed?
|
||||
Resize should be done somewhere else !
|
||||
Args:
|
||||
out_folder (string) : the location where to save the output image.
|
||||
|
||||
KArgs :
|
||||
fps (int) : the number of frames per second to be displayed in final video
|
||||
"""
|
||||
filename = os.path.join(out_folder, "output.avi")
|
||||
fourcc = cv.CV_FOURCC('C', 'V', 'I', 'D')
|
||||
@@ -303,7 +354,8 @@ class FaceMovie(object):
|
||||
def number_guys(self):
|
||||
"""
|
||||
Simply returns the number of guys in the current to-be movie
|
||||
"""
|
||||
__Designed for interface use only__
|
||||
"""
|
||||
return len(self.guys)
|
||||
|
||||
def out_display(self, im, name, time=1000, im_x=640, im_y=480):
|
||||
@@ -311,6 +363,13 @@ class FaceMovie(object):
|
||||
Displays the output image, for time ms.
|
||||
Setting time to 0 causes the image to remains open.
|
||||
Window name slightly changed to match output
|
||||
Args:
|
||||
im (IplImage) : the image to be saved, formatted as an OpenCV Image
|
||||
name (string) : the name of the image to be saved
|
||||
KArgs :
|
||||
time (int) : time for which the image should be displayed (in ms)
|
||||
im_x (int) : output size of the displayed image (in pixels)
|
||||
im_y (int) : output size of the displayed image (in pixels)
|
||||
"""
|
||||
win_name = name + " - out"
|
||||
cv.NamedWindow(win_name, cv.CV_WINDOW_NORMAL)
|
||||
@@ -322,6 +381,12 @@ class FaceMovie(object):
|
||||
def save_result(self, im, name, out_folder, ext):
|
||||
"""
|
||||
Saves output image to the given format (given in extension)
|
||||
|
||||
Args:
|
||||
im (IplImage) : the image to be saved, formatted as an OpenCV Image
|
||||
name (string) : the name of the image to be saved
|
||||
out_folder (string) : the location where to save the image
|
||||
ext (string) : Format in which the image should be saved
|
||||
"""
|
||||
file_name = name + "." + ext
|
||||
out_name = os.path.join(out_folder, file_name)
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
'''
|
||||
Created on 29 mars 2012
|
||||
"""
|
||||
.. module:: FaceMovifier
|
||||
:platform: Unix, Windows
|
||||
:synopsis: Higher class of the application. Used to handle the command line interface.
|
||||
Direclty interfaces user commands with FaceMovie actions.
|
||||
|
||||
@author: jll
|
||||
'''
|
||||
.. moduleauthor:: Julien Lengrand-Lambert <jlengrand@gmail.com>
|
||||
|
||||
"""
|
||||
|
||||
# This file should never be imported anywhere
|
||||
import os
|
||||
@@ -18,12 +22,17 @@ class Facemoviefier():
|
||||
Class defining the interactions with the end user.
|
||||
Should be used as point of entry for all end users.
|
||||
"""
|
||||
def __init__(self):
|
||||
#inits Command Line Parser
|
||||
def __init__(self):
|
||||
"""
|
||||
Inits the Command Line Parser on Startup
|
||||
"""
|
||||
self.args = self.initCLParser()
|
||||
|
||||
def init_facemovie(self):
|
||||
# FIXME : par folder should be known (contained somewhere in the installation)
|
||||
"""
|
||||
Inits the Facemovie parameters, so that it can be run efficiently
|
||||
FIXME : par folder should be known (contained somewhere in the installation)
|
||||
"""
|
||||
par_fo = os.path.join(self.args['root'], "haarcascades")
|
||||
self.face_params = FaceParams.FaceParams(par_fo, self.args['param'])
|
||||
self.facemovie = Facemovie.FaceMovie(self.args['input'], self.args['output'], self.face_params)
|
||||
@@ -31,6 +40,7 @@ class Facemoviefier():
|
||||
def initCLParser(self):
|
||||
"""
|
||||
Inits and Configures the command line parser designed to help the user configure the application
|
||||
Defines all possible options, and also creats the Helper.
|
||||
"""
|
||||
parser = argparse.ArgumentParser(description="Creates a movie from a bunch of photos containing a Face.")
|
||||
|
||||
@@ -100,6 +110,7 @@ class Facemoviefier():
|
||||
def run(self):
|
||||
"""
|
||||
Runs all the steps needed to get the desired output
|
||||
Checks which parameters have been run, and runs the algorithm accordingly.
|
||||
"""
|
||||
# selects xml used to train the classifier
|
||||
if self.args['param'] == '?':
|
||||
|
||||
@@ -1,21 +1,29 @@
|
||||
'''
|
||||
Created on 29 mars 2012
|
||||
"""
|
||||
.. module:: Guy
|
||||
:platform: Unix, Windows
|
||||
:synopsis: Class defining a Guy in the sense of the FaceMovie. Corresponds
|
||||
to one input image. An input folder is transformed in fact to a list of guys.
|
||||
|
||||
@author: jll
|
||||
'''
|
||||
.. moduleauthor:: Julien Lengrand-Lambert <jlengrand@gmail.com>
|
||||
|
||||
"""
|
||||
import cv
|
||||
|
||||
import time
|
||||
|
||||
class Guy(object):
|
||||
'''
|
||||
Represents the user on the people at a fixed time.
|
||||
All data found for this time may be found here.
|
||||
'''
|
||||
"""
|
||||
A new Guy is declared for each input image.
|
||||
A Guy should have a face, and owns the input image.
|
||||
|
||||
"""
|
||||
def __init__(self, image, image_id, date):
|
||||
'''
|
||||
Constructor
|
||||
'''
|
||||
"""All data linked to an input image
|
||||
Args:
|
||||
image (IplImage) : the input image, formatted as an OpenCV Image
|
||||
image_id (string) : the name of the image, formatted as a string
|
||||
date (datetime) : the date where the input image was taken.
|
||||
"""
|
||||
self.in_x = None
|
||||
self.in_y = None
|
||||
|
||||
@@ -39,9 +47,16 @@ class Guy(object):
|
||||
cv.Copy(image, self.in_image)
|
||||
|
||||
def find_date(self, date):
|
||||
"""
|
||||
Transforms given string formatted date into proper date
|
||||
Used afterwards to sort images
|
||||
"""This function takes a date as a string, and returns a date object.
|
||||
Used afterwards to sort images chronologically
|
||||
|
||||
Args:
|
||||
date (str): The date where the image was taken
|
||||
|
||||
Returns:
|
||||
datetime. Returns a date object according to time library.
|
||||
|
||||
In case of error, set the date to be the current time.
|
||||
"""
|
||||
try:
|
||||
my_date = time.strptime(date, "%Y:%m:%d %H:%M:%S")
|
||||
@@ -54,6 +69,13 @@ class Guy(object):
|
||||
Search on the picture for a face.
|
||||
Populates faces list.
|
||||
This function is the only one containing scaling information
|
||||
|
||||
Set several Guy information, such as the face size, or the virtual center of the image
|
||||
|
||||
Args:
|
||||
face_params (str): The type of file to be used to train the classifier.
|
||||
|
||||
Once Faces have been found, they are listed and ordered
|
||||
"""
|
||||
# Allocate the temporary images
|
||||
gray = cv.CreateImage((self.in_x, self.in_y),
|
||||
@@ -99,7 +121,14 @@ class Guy(object):
|
||||
|
||||
def sort_faces(self):
|
||||
"""
|
||||
sort faces by number of neighbours found, most probable one first
|
||||
Sorts faces by number of neighbours found, most probable one first
|
||||
|
||||
Args:
|
||||
face_params (str): The type of file to be used to train the classifier.
|
||||
|
||||
Returns:
|
||||
A list of faces, ordered by probability
|
||||
If no faces is found, returns a void list.
|
||||
"""
|
||||
if self.has_face() : # needed ?
|
||||
self.faces.sort(key= lambda prob : prob[1], reverse=True)
|
||||
@@ -109,6 +138,9 @@ class Guy(object):
|
||||
def update_center(self):
|
||||
"""
|
||||
Using sorted faces, defines the new center of interest of the output image
|
||||
|
||||
Updates the center of the image, using the most probable face as reference.
|
||||
Íf no face was found, the center is not updated.
|
||||
"""
|
||||
if self.has_face():
|
||||
((x, y, w, h), n) = self.faces[0]
|
||||
@@ -117,7 +149,12 @@ class Guy(object):
|
||||
|
||||
def normalize_face(self, reference):
|
||||
"""
|
||||
Creates intermediate image, whose face fits reference size
|
||||
Creates intermediate image, whose face fits reference size.
|
||||
This method aloows faces to always keep the same size during all the video.
|
||||
Changes the center of the image and adds a new resized image.
|
||||
|
||||
Args:
|
||||
reference (int): The refence size of the face (in pixels). Defined as the first face size for now
|
||||
"""
|
||||
self.normalize = 1
|
||||
|
||||
@@ -140,6 +177,15 @@ class Guy(object):
|
||||
Creates image output, centering the face center with the required position
|
||||
If eq_ratio is set to something different than one, input image is scaled
|
||||
so that face/size = eq_ratio
|
||||
|
||||
Args:
|
||||
x_size (int): The size of the ouput image in x (in pixels)
|
||||
y_size (int): The size of the ouput image in y (in pixels)
|
||||
x_point (int): The center of the output image, where the Guy image has to fit in (in pixels)
|
||||
y_point (int): The center of the output image, where the Guy image has to fit in (in pixels)
|
||||
|
||||
Returns:
|
||||
The ouput image, centered to fit with all other images
|
||||
"""
|
||||
out_im = cv.CreateImage((x_size, y_size),cv.IPL_DEPTH_8U, self.in_channels)
|
||||
cv.Zero(out_im)
|
||||
@@ -160,7 +206,7 @@ class Guy(object):
|
||||
|
||||
def create_debug_output(self):
|
||||
"""
|
||||
NOT FUNCTIONAL ANY MORE
|
||||
**DEPRECATED**
|
||||
Creates output image
|
||||
If debug is set to true, output image is the input image with a red
|
||||
box around the most probable face.
|
||||
@@ -195,6 +241,11 @@ class Guy(object):
|
||||
"""
|
||||
Displays the input image, for time ms.
|
||||
Setting time to 0 causes the image to remains open.
|
||||
|
||||
Args:
|
||||
time (int): The time for which image stays diaplyed (in ms). 0 causes the frams to remain open
|
||||
im_x (int): The output of the display frame in x (in pixels)
|
||||
im_y (int): The output of the display frame in y (in pixels)
|
||||
"""
|
||||
cv.NamedWindow(self.name, cv.CV_WINDOW_NORMAL)
|
||||
cv.ResizeWindow(self.name, im_x, im_y)
|
||||
@@ -205,12 +256,18 @@ class Guy(object):
|
||||
def num_faces(self):
|
||||
"""
|
||||
Returns the number of faces found for this guy
|
||||
|
||||
Returns:
|
||||
int The number of faces found for the input image
|
||||
"""
|
||||
return len(self.faces)
|
||||
|
||||
def has_face(self):
|
||||
"""
|
||||
Returns True if at least one face has been found
|
||||
Returns True of False whether images have been found for the current image or not.
|
||||
|
||||
Returns:
|
||||
True if at least one face has been found
|
||||
"""
|
||||
return (len(self.faces) > 0)
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
"""
|
||||
Aims at helping you create videos of yourself over time, using photos as input.
|
||||
Take great pictures, FaceMovie will do the rest !
|
||||
|
||||
.. moduleauthor:: Julien Lengrand-Lambert <jlengrand@gmail.com>
|
||||
|
||||
"""
|
||||
7
facemovie/facemovie.rst
Normal file
7
facemovie/facemovie.rst
Normal file
@@ -0,0 +1,7 @@
|
||||
Documentation of the FaceMovie project
|
||||
**************************************
|
||||
|
||||
.. automodule:: facemovie
|
||||
|
||||
.. automodule:: facemovie.useful_1
|
||||
:members:
|
||||
@@ -0,0 +1,6 @@
|
||||
"""
|
||||
This package aims at containing all libraries or external elements needed to create the FaceMovie
|
||||
|
||||
.. moduleauthor:: Julien Lengrand-Lambert <jlengrand@gmail.com>
|
||||
|
||||
"""
|
||||
@@ -1,8 +1,12 @@
|
||||
'''
|
||||
Created on 25 avr. 2012
|
||||
"""
|
||||
.. module:: training_types
|
||||
:platform: Unix, Windows
|
||||
:synopsis: Dumb class aiming at regrouping all information concerning the trainers for classification.
|
||||
Each entry is linked to a label, corresponding to a different type of recognition (frontal, profile, . . . )
|
||||
|
||||
@author: jll
|
||||
'''
|
||||
.. moduleauthor:: Julien Lengrand-Lambert <jlengrand@gmail.com>
|
||||
|
||||
"""
|
||||
# File used only to store a dictionary off all xml files used to train the classifier
|
||||
complete_set = {#eyes
|
||||
'eyes':"haarcascade_eye",
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
import sys
|
||||
sys.path.append("../facemovie/lib")
|
||||
import exif
|
||||
import time
|
||||
|
||||
path = "../data/input/Axel/2012-01-15-06h13m41DSCN9849.JPG"
|
||||
|
||||
plop = exif.parse(path)['DateTime']
|
||||
print plop
|
||||
|
||||
my_date = time.strptime(plop, "%Y:%m:%d %H:%M:%S")
|
||||
print my_date
|
||||
@@ -1,33 +0,0 @@
|
||||
'''
|
||||
Created on 16 avr. 2012
|
||||
|
||||
@author: jll
|
||||
'''
|
||||
|
||||
import os
|
||||
from context import facemovie
|
||||
from facemovie.Facemovie import FaceMovie
|
||||
|
||||
import facemovie.training_types
|
||||
|
||||
if __name__ == '__main__':
|
||||
root_fo = "C:\Users\jll\perso\workspace\FaceMovie"
|
||||
in_fo = os.path.join(root_fo, "data/input\Axel")
|
||||
out_fo = os.path.join(root_fo, "data/output")
|
||||
par_fo = os.path.join(root_fo, "facemovie/haarcascades")
|
||||
|
||||
my_movie = FaceMovie(in_fo, out_fo, par_fo)
|
||||
my_movie.list_guys() # find images in input folder
|
||||
|
||||
#my_movie.search_faces() # search for images with faces
|
||||
# I want to change images so that all faces have the same size
|
||||
#my_movie.normalize_faces() # sets all faces to the same size
|
||||
# I want to know the size of the output frame, knowing initial conditions
|
||||
#my_movie.find_out_dims() # finds output minimal size to get all eyes in the same place
|
||||
|
||||
#choose your final step
|
||||
#my_movie.show_faces(1000)
|
||||
#my_movie.save_faces("output")
|
||||
#my_movie.save_movie("output")
|
||||
|
||||
print "Facemovie finished !"
|
||||
Reference in New Issue
Block a user