summaryrefslogtreecommitdiff
path: root/facedetect/shotwell-facedetect.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'facedetect/shotwell-facedetect.cpp')
-rw-r--r--facedetect/shotwell-facedetect.cpp134
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;
+
+}