1 // This file is part of OpenCV project.
2 // It is subject to the license terms in the LICENSE file found in the top-level directory
3 // of this distribution and at http://opencv.org/license.html.
4 
5 /*
6 This file was part of GSoC Project: Facemark API for OpenCV
7 Final report: https://gist.github.com/kurnianggoro/74de9121e122ad0bd825176751d47ecc
8 Student: Laksono Kurnianggoro
9 Mentor: Delia Passalacqua
10 */
11 
12 #ifndef __OPENCV_FACELANDMARKTRAIN_HPP__
13 #define __OPENCV_FACELANDMARKTRAIN_HPP__
14 
15 /**
16 @defgroup face Face Analysis
17 - @ref tutorial_table_of_content_facemark
18 - The Facemark API
19 */
20 
21 #include "opencv2/face/facemark.hpp"
22 #include "opencv2/objdetect.hpp"
23 #include <vector>
24 #include <string>
25 
26 
27 namespace cv {
28 namespace face {
29 
30 //! @addtogroup face
31 //! @{
32 
33 typedef bool(*FN_FaceDetector)(InputArray, OutputArray, void* userData);
34 
35 struct CParams{
36     String cascade; //!<  the face detector
37     double scaleFactor; //!< Parameter specifying how much the image size is reduced at each image scale.
38     int minNeighbors; //!< Parameter specifying how many neighbors each candidate rectangle should have to retain it.
39     Size minSize; //!< Minimum possible object size.
40     Size maxSize; //!< Maximum possible object size.
41 
42     CV_EXPORTS CParams(
43         String cascade_model,
44         double sf = 1.1,
45         int minN = 3,
46         Size minSz = Size(30, 30),
47         Size maxSz = Size()
48     );
49 
50     CascadeClassifier face_cascade;
51 };
52 
53 /** @brief Default face detector
54 This function is mainly utilized by the implementation of a Facemark Algorithm.
55 End users are advised to use function Facemark::getFaces which can be manually defined
56 and circumvented to the algorithm by Facemark::setFaceDetector.
57 
58 @param image The input image to be processed.
59 @param faces Output of the function which represent region of interest of the detected faces.
60 Each face is stored in cv::Rect container.
61 @param params detector parameters
62 
63 <B>Example of usage</B>
64 @code
65 std::vector<cv::Rect> faces;
66 CParams params("haarcascade_frontalface_alt.xml");
67 cv::face::getFaces(frame, faces, &params);
68 for(int j=0;j<faces.size();j++){
69     cv::rectangle(frame, faces[j], cv::Scalar(255,0,255));
70 }
71 cv::imshow("detection", frame);
72 @endcode
73 */
74 CV_EXPORTS bool getFaces(InputArray image, OutputArray faces, CParams* params);
75 
76 CV_EXPORTS_W bool getFacesHAAR(InputArray image, OutputArray faces, const String& face_cascade_name);
77 
78 /** @brief A utility to load list of paths to training image and annotation file.
79 @param imageList The specified file contains paths to the training images.
80 @param annotationList The specified file contains paths to the training annotations.
81 @param images The loaded paths of training images.
82 @param annotations The loaded paths of annotation files.
83 
84 Example of usage:
85 @code
86 String imageFiles = "images_path.txt";
87 String ptsFiles = "annotations_path.txt";
88 std::vector<String> images_train;
89 std::vector<String> landmarks_train;
90 loadDatasetList(imageFiles,ptsFiles,images_train,landmarks_train);
91 @endcode
92 */
93 CV_EXPORTS_W bool loadDatasetList(String imageList,
94                                   String annotationList,
95                                   std::vector<String> & images,
96                                   std::vector<String> & annotations);
97 
98 /** @brief A utility to load facial landmark dataset from a single file.
99 
100 @param filename The filename of a file that contains the dataset information.
101 Each line contains the filename of an image followed by
102 pairs of x and y values of facial landmarks points separated by a space.
103 Example
104 @code
105 /home/user/ibug/image_003_1.jpg 336.820955 240.864510 334.238298 260.922709 335.266918 ...
106 /home/user/ibug/image_005_1.jpg 376.158428 230.845712 376.736984 254.924635 383.265403 ...
107 @endcode
108 @param images A vector where each element represent the filename of image in the dataset.
109 Images are not loaded by default to save the memory.
110 @param facePoints The loaded landmark points for all training data.
111 @param delim Delimiter between each element, the default value is a whitespace.
112 @param offset An offset value to adjust the loaded points.
113 
114 <B>Example of usage</B>
115 @code
116 cv::String imageFiles = "../data/images_train.txt";
117 cv::String ptsFiles = "../data/points_train.txt";
118 std::vector<String> images;
119 std::vector<std::vector<Point2f> > facePoints;
120 loadTrainingData(imageFiles, ptsFiles, images, facePoints, 0.0f);
121 @endcode
122 */
123 CV_EXPORTS_W bool loadTrainingData( String filename , std::vector<String> & images,
124                                     OutputArray facePoints,
125                                     char delim = ' ', float offset = 0.0f);
126 
127 /** @brief A utility to load facial landmark information from the dataset.
128 
129 @param imageList A file contains the list of image filenames in the training dataset.
130 @param groundTruth A file contains the list of filenames
131 where the landmarks points information are stored.
132 The content in each file should follow the standard format (see face::loadFacePoints).
133 @param images A vector where each element represent the filename of image in the dataset.
134 Images are not loaded by default to save the memory.
135 @param facePoints The loaded landmark points for all training data.
136 @param offset An offset value to adjust the loaded points.
137 
138 <B>Example of usage</B>
139 @code
140 cv::String imageFiles = "../data/images_train.txt";
141 cv::String ptsFiles = "../data/points_train.txt";
142 std::vector<String> images;
143 std::vector<std::vector<Point2f> > facePoints;
144 loadTrainingData(imageFiles, ptsFiles, images, facePoints, 0.0f);
145 @endcode
146 
147 example of content in the images_train.txt
148 @code
149 /home/user/ibug/image_003_1.jpg
150 /home/user/ibug/image_004_1.jpg
151 /home/user/ibug/image_005_1.jpg
152 /home/user/ibug/image_006.jpg
153 @endcode
154 
155 example of content in the points_train.txt
156 @code
157 /home/user/ibug/image_003_1.pts
158 /home/user/ibug/image_004_1.pts
159 /home/user/ibug/image_005_1.pts
160 /home/user/ibug/image_006.pts
161 @endcode
162 */
163 CV_EXPORTS_W bool loadTrainingData( String imageList, String groundTruth,
164                                     std::vector<String> & images,
165                                     OutputArray facePoints,
166                                     float offset = 0.0f);
167 
168 /** @brief This function extracts the data for training from .txt files which contains the corresponding image name and landmarks.
169 *The first file in each file should give the path of the image whose
170 *landmarks are being described in the file. Then in the subsequent
171 *lines there should be coordinates of the landmarks in the image
172 *i.e each line should be of the form x,y
173 *where x represents the x coordinate of the landmark and y represents
174 *the y coordinate of the landmark.
175 *
176 *For reference you can see the files as provided in the
177 *<a href="http://www.ifp.illinois.edu/~vuongle2/helen/">HELEN dataset</a>
178 *
179 * @param filename A vector of type cv::String containing name of the .txt files.
180 * @param trainlandmarks A vector of type cv::Point2f that would store shape or landmarks of all images.
181 * @param trainimages A vector of type cv::String which stores the name of images whose landmarks are tracked
182 * @returns A boolean value. It returns true when it reads the data successfully and false otherwise
183 */
184 CV_EXPORTS_W bool loadTrainingData(std::vector<String> filename,std::vector< std::vector<Point2f> >
185                           &trainlandmarks,std::vector<String> & trainimages);
186 
187 /** @brief A utility to load facial landmark information from a given file.
188 
189 @param filename The filename of file contains the facial landmarks data.
190 @param points The loaded facial landmark points.
191 @param offset An offset value to adjust the loaded points.
192 
193 <B>Example of usage</B>
194 @code
195 std::vector<Point2f> points;
196 face::loadFacePoints("filename.txt", points, 0.0f);
197 @endcode
198 
199 The annotation file should follow the default format which is
200 @code
201 version: 1
202 n_points:  68
203 {
204 212.716603 499.771793
205 230.232816 566.290071
206 ...
207 }
208 @endcode
209 where n_points is the number of points considered
210 and each point is represented as its position in x and y.
211 */
212 CV_EXPORTS_W bool loadFacePoints( String filename, OutputArray points,
213                                   float offset = 0.0f);
214 
215 /** @brief Utility to draw the detected facial landmark points
216 
217 @param image The input image to be processed.
218 @param points Contains the data of points which will be drawn.
219 @param color The color of points in BGR format represented by cv::Scalar.
220 
221 <B>Example of usage</B>
222 @code
223 std::vector<Rect> faces;
224 std::vector<std::vector<Point2f> > landmarks;
225 facemark->getFaces(img, faces);
226 facemark->fit(img, faces, landmarks);
227 for(int j=0;j<rects.size();j++){
228     face::drawFacemarks(frame, landmarks[j], Scalar(0,0,255));
229 }
230 @endcode
231 */
232 CV_EXPORTS_W void drawFacemarks( InputOutputArray image, InputArray points,
233                                  Scalar color = Scalar(255,0,0));
234 
235 /** @brief Abstract base class for trainable facemark models
236 
237 To utilize this API in your program, please take a look at the @ref tutorial_table_of_content_facemark
238 ### Description
239 
240 The AAM and LBF facemark models in OpenCV are derived from the abstract base class FacemarkTrain, which
241 provides a unified access to those facemark algorithms in OpenCV.
242 
243 Here is an example on how to declare facemark algorithm:
244 @code
245 // Using Facemark in your code:
246 Ptr<Facemark> facemark = FacemarkLBF::create();
247 @endcode
248 
249 
250 The typical pipeline for facemark detection is listed as follows:
251 - (Non-mandatory) Set a user defined face detection using FacemarkTrain::setFaceDetector.
252   The facemark algorithms are designed to fit the facial points into a face.
253   Therefore, the face information should be provided to the facemark algorithm.
254   Some algorithms might provides a default face recognition function.
255   However, the users might prefer to use their own face detector to obtains the best possible detection result.
256 - (Non-mandatory) Training the model for a specific algorithm using FacemarkTrain::training.
257   In this case, the model should be automatically saved by the algorithm.
258   If the user already have a trained model, then this part can be omitted.
259 - Load the trained model using Facemark::loadModel.
260 - Perform the fitting via the Facemark::fit.
261 */
262 class CV_EXPORTS_W FacemarkTrain : public Facemark
263 {
264 public:
265     /** @brief Add one training sample to the trainer.
266 
267     @param image Input image.
268     @param landmarks The ground-truth of facial landmarks points corresponds to the image.
269 
270     <B>Example of usage</B>
271     @code
272     String imageFiles = "../data/images_train.txt";
273     String ptsFiles = "../data/points_train.txt";
274     std::vector<String> images_train;
275     std::vector<String> landmarks_train;
276 
277     // load the list of dataset: image paths and landmark file paths
278     loadDatasetList(imageFiles,ptsFiles,images_train,landmarks_train);
279 
280     Mat image;
281     std::vector<Point2f> facial_points;
282     for(size_t i=0;i<images_train.size();i++){
283         image = imread(images_train[i].c_str());
284         loadFacePoints(landmarks_train[i],facial_points);
285         facemark->addTrainingSample(image, facial_points);
286     }
287     @endcode
288 
289     The contents in the training files should follows the standard format.
290     Here are examples for the contents in these files.
291     example of content in the images_train.txt
292     @code
293     /home/user/ibug/image_003_1.jpg
294     /home/user/ibug/image_004_1.jpg
295     /home/user/ibug/image_005_1.jpg
296     /home/user/ibug/image_006.jpg
297     @endcode
298 
299     example of content in the points_train.txt
300     @code
301     /home/user/ibug/image_003_1.pts
302     /home/user/ibug/image_004_1.pts
303     /home/user/ibug/image_005_1.pts
304     /home/user/ibug/image_006.pts
305     @endcode
306 
307     */
308     virtual bool addTrainingSample(InputArray image, InputArray landmarks)=0;
309 
310     /** @brief Trains a Facemark algorithm using the given dataset.
311     Before the training process, training samples should be added to the trainer
312     using face::addTrainingSample function.
313 
314     @param parameters Optional extra parameters (algorithm dependent).
315 
316     <B>Example of usage</B>
317     @code
318     FacemarkLBF::Params params;
319     params.model_filename = "ibug68.model"; // filename to save the trained model
320     Ptr<Facemark> facemark = FacemarkLBF::create(params);
321 
322     // add training samples (see Facemark::addTrainingSample)
323 
324     facemark->training();
325     @endcode
326     */
327 
328     virtual void training(void* parameters=0)=0;
329 
330     /** @brief Set a user defined face detector for the Facemark algorithm.
331     @param detector The user defined face detector function
332     @param userData Detector parameters
333 
334     <B>Example of usage</B>
335     @code
336     MyDetectorParameters detectorParameters(...);
337     facemark->setFaceDetector(myDetector, &detectorParameters);
338     @endcode
339 
340     Example of a user defined face detector
341     @code
342     bool myDetector( InputArray image, OutputArray faces, void* userData)
343     {
344         MyDetectorParameters* params = (MyDetectorParameters*)userData;
345         // -------- do something --------
346     }
347     @endcode
348 
349     TODO Lifetime of detector parameters is uncontrolled. Rework interface design to "Ptr<FaceDetector>".
350     */
351     virtual bool setFaceDetector(FN_FaceDetector detector, void* userData = 0)=0;
352 
353     /** @brief Detect faces from a given image using default or user defined face detector.
354     Some Algorithm might not provide a default face detector.
355 
356     @param image Input image.
357     @param faces Output of the function which represent region of interest of the detected faces. Each face is stored in cv::Rect container.
358 
359     <B>Example of usage</B>
360     @code
361     std::vector<cv::Rect> faces;
362     facemark->getFaces(img, faces);
363     for(int j=0;j<faces.size();j++){
364         cv::rectangle(img, faces[j], cv::Scalar(255,0,255));
365     }
366     @endcode
367     */
368     virtual bool getFaces(InputArray image, OutputArray faces)=0;
369 
370     /** @brief Get data from an algorithm
371 
372     @param items The obtained data, algorithm dependent.
373 
374     <B>Example of usage</B>
375     @code
376     Ptr<FacemarkAAM> facemark = FacemarkAAM::create();
377     facemark->loadModel("AAM.yml");
378 
379     FacemarkAAM::Data data;
380     facemark->getData(&data);
381     std::vector<Point2f> s0 = data.s0;
382 
383     cout<<s0<<endl;
384     @endcode
385     */
386     virtual bool getData(void * items=0)=0; // FIXIT
387 }; /* Facemark*/
388 
389 //! @}
390 } /* namespace face */
391 } /* namespace cv */
392 #endif //__OPENCV_FACELANDMARKTRAIN_HPP__
393