diff options
Diffstat (limited to 'facedetect/shotwell-facedetect.cpp')
-rw-r--r-- | facedetect/shotwell-facedetect.cpp | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/facedetect/shotwell-facedetect.cpp b/facedetect/shotwell-facedetect.cpp new file mode 100644 index 0000000..1b09379 --- /dev/null +++ b/facedetect/shotwell-facedetect.cpp @@ -0,0 +1,134 @@ +/* Copyright 2016 Software Freedom Conservancy Inc. + * + * Copyright 2011 ValentÃn Barros Puertas <valentin(at)sanva(dot)net> + * Copyright 2018 Ricardo Fantin da Costa <ricardofantin(at)gmail(dot)com> + * + * This software is licensed under the GNU LGPL (version 2.1 or later). + * See the COPYING file in this distribution. + */ + +#include "opencv2/objdetect/objdetect.hpp" +#include "opencv2/highgui/highgui.hpp" +#include "opencv2/imgproc/imgproc.hpp" + +#include <iostream> +#include <stdio.h> + +using namespace std; +using namespace cv; + +void help() { + + cout << + "Usage:" << endl << + "./facedetect --cascade=<cascade_path> " + "--scale=<image scale greater or equal to 1, try 1.3 for example> " + "filename" << endl << endl << + "Example:" << endl << + "./facedetect --cascade=\"./data/haarcascades/haarcascade_frontalface_alt.xml\" " + "--scale=1.3 ./photo.jpg" << endl << endl << + "Using OpenCV version " << CV_VERSION << endl; + +} + +void detectFaces(Mat &img, CascadeClassifier &cascade, double scale) { + + Mat gray; + cvtColor(img, gray, CV_BGR2GRAY); + + Mat smallImg(cvRound(img.rows / scale), cvRound(img.cols / scale), CV_8UC1); + Size smallImgSize = smallImg.size(); + + resize(gray, smallImg, smallImgSize, 0, 0, INTER_LINEAR); + equalizeHist(smallImg, smallImg); + + vector<Rect> faces; + cascade.detectMultiScale(smallImg, faces, 1.1, 2, CV_HAAR_SCALE_IMAGE, Size(30, 30)); + + int i = 0; + for (vector<Rect>::const_iterator r = faces.begin(); r != faces.end(); r++, i++) { + + printf( + "face;x=%f&y=%f&width=%f&height=%f\n", + (float) r->x / smallImgSize.width, + (float) r->y / smallImgSize.height, + (float) r->width / smallImgSize.width, + (float) r->height / smallImgSize.height + ); + + } + +} + +int main(int argc, const char** argv) { + + const std::string scaleOpt = "--scale="; + size_t scaleOptLen = scaleOpt.length(); + const std::string cascadeOpt = "--cascade="; + size_t cascadeOptLen = cascadeOpt.length(); + + std::string cascadeName, inputName; + double scale = 1; + + for (int i = 1; i < argc; i++) { + + if (cascadeOpt.compare(0, cascadeOptLen, argv[i], cascadeOptLen) == 0) { + + cascadeName.assign(argv[i] + cascadeOptLen); + + } else if (scaleOpt.compare(0, scaleOptLen, argv[i], scaleOptLen) == 0) { + + if (!sscanf(argv[i] + scaleOpt.length(), "%lf", &scale) || scale < 1) + scale = 1; + + } else if (argv[i][0] == '-') { + + cout << "warning;Unknown option " << argv[i] << endl; + + } else + inputName.assign(argv[i]); + + } + + if (cascadeName.empty()) { + + cout << "error;You must specify the cascade." << endl; + help(); + + return -1; + + } + + CascadeClassifier cascade; + + if (!cascade.load(cascadeName)) { + + cout << "error;Could not load classifier cascade. Filename: \"" << cascadeName << "\"" << endl; + + return -1; + } + + if (inputName.empty()) { + + cout << "error;You must specify the file to process." << endl; + help(); + + return -1; + + } + + Mat image = imread(inputName, 1); + + if (image.empty()) { + + cout << "error;Could not load the file to process. Filename: \"" << inputName << "\"" << endl; + + return -1; + + } + + detectFaces(image, cascade, scale); + + return 0; + +} |