/* Copyright 2016 Software Freedom Conservancy Inc. * * Copyright 2011 Valentín Barros Puertas * Copyright 2018 Ricardo Fantin da Costa * * 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 #include using namespace std; using namespace cv; void help() { cout << "Usage:" << endl << "./facedetect --cascade= " "--scale= " "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 faces; cascade.detectMultiScale(smallImg, faces, 1.1, 2, CV_HAAR_SCALE_IMAGE, Size(30, 30)); int i = 0; for (vector::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; }