Skip to content
This repository was archived by the owner on Apr 26, 2019. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .DS_Store
Binary file not shown.
Binary file added brian.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions faces/.picasa.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[Picasa]
P2category=Exported Pictures
date=41320.767708
Binary file added faces/face_2012-09-26T11-00-00Z-0700.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added faces/face_2012-09-26T11-30-00Z-0700.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added faces/face_2012-09-26T19-30-00Z-0700.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added faces/face_2012-09-27T10-02-02Z-0700.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added faces/face_2012-09-27T11-00-00Z-0700.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added faces/face_2012-09-27T11-30-00Z-0700.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added faces/face_2012-09-27T12-00-00Z-0700.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added faces/face_2012-09-27T13-30-00Z-0700.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added faces/face_2012-09-27T16-00-00Z-0700.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added faces/face_2012-09-27T21-00-01Z-0700.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added faces/face_2012-09-27T21-30-00Z-0700.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added faces/face_2012-09-28T10-30-00Z-0700.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added faces/face_2012-09-28T11-00-00Z-0700.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added faces/face_2012-09-28T11-30-00Z-0700.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added faces/face_2012-09-28T12-30-01Z-0700.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added faces/face_2012-09-28T15-30-00Z-0700.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added faces/face_2012-09-28T16-00-00Z-0700.jpg
Binary file added faces/face_2012-09-28T16-30-00Z-0700.jpg
Binary file added faces/face_2012-09-29T21-30-00Z-0700.jpg
Binary file added find-face
Binary file not shown.
136 changes: 86 additions & 50 deletions find-face.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,25 @@

using namespace cv;

#define USAGE "USAGE: find-face --cascade=PATH.xml [ --scale=SCALE ] IMAGE"
#define USAGE "USAGE: find-face --cascade=PATH.xml [ --scale=SCALE ] [ --magickcenter ] IMAGE"

// int face_area_compare(Rect *face1, Rect *face2)
// {
// return ((face1.width * face1->.height) < (face2.width * face2.height));
// }

int main(int argc, const char** argv)
{
std::string cascade_name;
std::string input_name;
CascadeClassifier cascade;
double scale = 1;
bool do_magick_center=false;

const std::string help_opt = "--help";
const std::string scale_opt = "--scale=";
const std::string cascade_opt = "--cascade=";
const std::string magickcenter = "--magickcenter";

for (int i = 1; i < argc; i++) {
if (cascade_opt.compare(0, cascade_opt.length(), argv[i], cascade_opt.length()) == 0) {
Expand All @@ -39,64 +46,93 @@ int main(int argc, const char** argv)
} else if (help_opt == argv[i]) {
std::cout << USAGE << std::endl;
return 0;
} else if (magickcenter == argv[i]) {
do_magick_center=true;
} else {
input_name.assign(argv[i]);
}
}

if (cascade_name.empty()) {
std::cerr << "ERROR: --cascade=PATH argument required" << std::endl;
return -1;
}
if (cascade_name.empty()) {
std::cerr << "ERROR: --cascade=PATH argument required" << std::endl;
return -1;
}

if (!cascade.load(cascade_name)) {
std::cerr << "ERROR: could not load classifier cascade: " << cascade_name << std::endl;
return -1;
}
if (!cascade.load(cascade_name)) {
std::cerr << "ERROR: could not load classifier cascade: " << cascade_name << std::endl;
return -1;
}

if (input_name.empty()) {
std::cerr << "ERROR: image name required" << std::endl;
return -1;
}
if (input_name.empty()) {
std::cerr << "ERROR: image name required" << std::endl;
return -1;
}

std::ifstream file(input_name.c_str());
if (!file.good()) {
std::cerr << "file not found or not readable: " << input_name << std::endl;
return -1;
}
std::ifstream file(input_name.c_str());
if (!file.good()) {
std::cerr << "file not found or not readable: " << input_name << std::endl;
return -1;
}

Mat image = imread(input_name, 1);
if (!image.empty()) {
Mat gray, small_image(cvRound(image.rows/scale), cvRound(image.cols/scale), CV_8UC1);
cvtColor(image, gray, CV_BGR2GRAY);
resize(gray, small_image, small_image.size(), 0, 0, INTER_LINEAR);
equalizeHist(small_image, small_image);

std::vector<Rect> faces;
cascade.detectMultiScale(small_image, faces, 1.1, 2, 0, Size(30, 30));
if (!faces.empty()) {
unsigned int max_area = 0;
std::vector<Rect>::const_iterator max_region = faces.end();
for (std::vector<Rect>::const_iterator r = faces.begin(); r != faces.end(); r++) {
float area = r->width * r->height;
if (area > max_area) {
max_area = area;
max_region = r;
Mat image = imread(input_name, 1);
if (!image.empty()) {
Mat gray, small_image(cvRound(image.rows/scale), cvRound(image.cols/scale), CV_8UC1);
cvtColor(image, gray, CV_BGR2GRAY);
resize(gray, small_image, small_image.size(), 0, 0, INTER_LINEAR);
equalizeHist(small_image, small_image);

std::vector<Rect> faces;
cascade.detectMultiScale(small_image, faces, 1.1, 2, 0, Size(30, 30));

//std::sort (faces.begin(),faces.end(),face_area_compare);

float image_width = static_cast<float>(image.size().width);
float image_height = static_cast<float>(image.size().height);
float total_area = image_width * image_height;

if (!faces.empty()) {
unsigned int face_count = 0;
//std::vector<Rect>::const_iterator max_region = faces.end();
for (std::vector<Rect>::const_iterator r = faces.begin(); r != faces.end(); r++) {
float area = r->width * r->height;
if ((area / total_area)<0.05) {
// face is too small
continue;
}

face_count++;

// calculate offset to center face in the image
// Want to enable: http://www.imagemagick.org/discourse-server/viewtopic.php?f=1&t=20823
float center_face_offset_x = (image_width/ 2.0)-(r->x+(static_cast<float>(r->width)/2.0));
float center_face_offset_y = (image_height/2.0)-(r->y+(static_cast<float>(r->height)/2.0));

if (do_magick_center) {
// imagemagick centering output
std::cout
<< "convert "
<< "'" << input_name << "'"
<< " -page "
<< (center_face_offset_x>0 ? "+" : "")
<< static_cast<int>(center_face_offset_x)
<< (center_face_offset_y>0 ? "+" : "")
<< static_cast<int>(center_face_offset_y) << " "
<< "-background none -flatten "
<< "'" << input_name << ".centered.jpg" << "'"
<< std::endl;
} else {
// normal output
std::cout
<< input_name << "\t"
<< face_count << "\t"
<< area / total_area << "\t"
<< r->x / image_width << "\t"
<< r->y / image_height << "\t"
<< r->width / image_width << "\t"
<< r->height / image_height << "\t"
<< std::endl;
}
}
}
}

float image_width = static_cast<float>(image.size().width);
float image_height = static_cast<float>(image.size().height);

/* These shouldn't happen, but guard for stability. */
if (max_region == faces.end() || image_width == 0 || image_height == 0)
return 0;

std::cout
<< max_region->x / image_width << " "
<< max_region->y / image_height << " "
<< max_region->width / image_width << " "
<< max_region->height / image_height << std::endl;
}
}

Expand Down
Loading