RAPP Platform  v0.6.0
RAPP Platform is a collection of ROS nodes and back-end processes that aim to deliver ready-to-use generic services to robots
 All Classes Namespaces Files Functions Variables Macros
face_detector.cpp
Go to the documentation of this file.
1 /******************************************************************************
2 Copyright 2015 RAPP
3 
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7 
8  http://www.apache.org/licenses/LICENSE-2.0
9 
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15 
16  Authors: Aris Thallas, Manos Tsardoulias
17  contact: aris.thallas@{iti.gr, gmail.com}, etsardou@iti.gr
18 
19 ******************************************************************************/
20 
22 
27 {
28 }
29 
35 cv::Mat FaceDetector::loadImage(std::string file_name)
36 {
37  cv::Mat input_img;
38  // Must check if file exists
39  input_img = cv::imread(file_name);
40  return input_img;
41 }
42 
50 std::vector<cv::Rect> FaceDetector::detectFaces(
51  const cv::Mat& input_img, bool fast)
52 {
53  std::vector<cv::Rect> front_faces, profile_faces, final_faces;
54  cv::Mat grayscale_img;
55  if( input_img.empty() )
56  {
57  return final_faces;
58  }
59  cv::cvtColor(input_img, grayscale_img, CV_BGR2GRAY);
60  cv::equalizeHist(grayscale_img, grayscale_img);
61 
62  // Detect Front Faces
63  std::string haar_file_path =
64  "/usr/share/opencv/haarcascades/haarcascade_frontalface_alt.xml";
65  front_faces = detectFaces( grayscale_img, haar_file_path );
66 
67  if(fast)
68  {
69  return front_faces;
70  }
71 
72  // Detect Profile Faces
73  haar_file_path = "/usr/share/opencv/haarcascades/haarcascade_profileface.xml";
74  profile_faces = detectFaces( grayscale_img, haar_file_path );
75 
76  // Identify unique faces
77  final_faces = identifyUniqueFaces( front_faces, profile_faces );
78 
79  return final_faces;
80 }
81 
89 std::vector<cv::Rect> FaceDetector::detectFaces(const cv::Mat& input_img,
90  const std::string& haar_path)
91 {
92  std::vector<cv::Rect> faces, final_faces;
93 
94  // The Haar cascade classifier
95  cv::CascadeClassifier face_cascade;
96  // Create the classifier
97  face_cascade.load(haar_path);
98 
99  face_cascade.detectMultiScale(input_img, faces, 1.1, 4);
100 
101  // If no faces were found make the algorithm less strict
102  if(faces.size() == 0)
103  {
104  face_cascade.detectMultiScale(input_img, faces, 1.1, 3);
105  }
106 
107  // Check the faces again to eliminate false positives
108  for(unsigned int i = 0 ; i < faces.size() ; i++)
109  {
110  cv::Rect tmp_rect = faces[i];
111  tmp_rect.x -= 10;
112  tmp_rect.y -= 10;
113  tmp_rect.width += 20;
114  tmp_rect.height += 20;
115  if(tmp_rect.x < 0 || tmp_rect.y < 0 ||
116  (tmp_rect.x + tmp_rect.width) > input_img.size().width ||
117  (tmp_rect.y + tmp_rect.height) > input_img.size().height)
118  {
119  continue;
120  }
121  cv::Mat temp_map = input_img(faces[i]);
122  std::vector<cv::Rect> tmp_faces;
123  face_cascade.detectMultiScale(temp_map, tmp_faces, 1.1, 3);
124  if(tmp_faces.size() == 0)
125  {
126  continue;
127  }
128  final_faces.push_back(faces[i]);
129  }
130  return final_faces;
131 }
132 
140 std::vector<cv::Rect> FaceDetector::identifyUniqueFaces(
141  const std::vector<cv::Rect> firstFaceVector,
142  const std::vector<cv::Rect> secondFaceVector)
143 {
144  std::vector<cv::Rect> final_faces;
145 
146  final_faces = firstFaceVector;
147 
148  final_faces.insert( final_faces.end(), secondFaceVector.begin(),
149  secondFaceVector.end() );
150 
151  int size = final_faces.size();
152  for( unsigned int i = 0; i < size; i++ )
153  {
154  final_faces.push_back( final_faces[i] );
155  }
156  groupRectangles( final_faces, 1, 0.2 );
157 
158  return final_faces;
159 }
160 
168 std::vector<cv::Rect> FaceDetector::findFaces(std::string file_name, bool fast)
169 {
170  cv::Mat input_img;
171  input_img = loadImage(file_name);
172  return detectFaces(input_img, fast);
173 }
std::vector< cv::Rect > detectFaces(const cv::Mat &input_img, bool fast=false)
Detects faces from a cv::Mat.
std::vector< cv::Rect > identifyUniqueFaces(const std::vector< cv::Rect > firstFaceVector, const std::vector< cv::Rect > secondFaceVector)
Identify unique faces from two sets of faces.
std::vector< cv::Rect > findFaces(std::string file_name, bool fast=false)
Finds faces in an image retrieved from a file URL.
cv::Mat loadImage(std::string file_name)
Loads an image from a file URL.
FaceDetector(void)
Default constructor.