<commit_before>// Copyright (c) Burator 2014-2015
#include <QFile>
#include <QDebug>

#include <vector>

#include "Util.h"
#include "FaceDetector.h"

B_BEGIN_NAMESPACE

FaceDetector::FaceDetector() {
  valid = true;

  // Read data from Qt resources.
  try {
    auto fs = Util::fileToFileStorage(":res/face.xml");
    if (!fs || !faceCas.read(fs->getFirstTopLevelNode())) {
      qCritical() << "Could not read faces data.";
      valid = false;
    }
  }
  catch (...) {
    qCritical() << "Invalid face cascade!";
    valid = false;
  }

  try {
    auto fs = Util::fileToFileStorage(":res/profileface.xml");
    if (!fs || !pfaceCas.read(fs->getFirstTopLevelNode())) {
      qCritical() << "Could not read profile faces data.";
      valid = false;
    }
  }
  catch (...) {
    qCritical() << "Invalid profile face cascade!";
    valid = false;
  }

  try {
    auto fs = Util::fileToFileStorage(":res/eyes.xml");
    if (!fs || !eyesCas.read(fs->getFirstTopLevelNode())) {
      qCritical() << "Could not read eyes data.";
      valid = false;
    }
  }
  catch (...) {
    qCritical() << "Invalid eyes cascade!";
    valid = false;
  }
}

QList<FacePtr> FaceDetector::detect(const MatPtr image) {
  QList<FacePtr> results;
  if (!image) {
    return results;
  }

  // Make grayscaled version of the image, and equalize the histogram
  // which normalizes the brightness and increases the contrast in the
  // image.
  cv::Mat grayImg;
  cvtColor(*image.get(), grayImg, cv::COLOR_BGR2GRAY);
  equalizeHist(grayImg, grayImg);

  // Detect faces with scale factor 1.1, minimum 3 neighbors and
  // minimum 80x80 face size.
  std::vector<cv::Rect> faces;
  faceCas.detectMultiScale(grayImg, faces, 1.1, 3, 0, cv::Size(80, 80));
  results.append(createFaces(faces, grayImg));
  faces.clear();

  // Detect profile faces with the left side visible.
  pfaceCas.detectMultiScale(grayImg, faces, 1.1, 3, 0, cv::Size(80, 80));
  results.append(createFaces(faces, grayImg));
  faces.clear();

  // Flip image vertically to detect the right side of faces.
  cv::flip(grayImg, grayImg, 1);
  pfaceCas.detectMultiScale(grayImg, faces, 1.1, 3, 0, cv::Size(80, 80));
  results.append(createFaces(faces, grayImg, true));

  return results;
}

QList<FacePtr> FaceDetector::createFaces(std::vector<cv::Rect> &faces,
                                         const cv::Mat &image, bool vflip) {
  cv::Size imageSize = image.size();
  QList<FacePtr> results;
  for (auto it = faces.begin(); it != faces.end(); ++it) {<commit_msg>Release grayscaled mat after face detection.<commit_after>// Copyright (c) Burator 2014-2015
#include <QFile>
#include <QDebug>

#include <vector>

#include "Util.h"
#include "FaceDetector.h"

B_BEGIN_NAMESPACE

FaceDetector::FaceDetector() {
  valid = true;

  // Read data from Qt resources.
  try {
    auto fs = Util::fileToFileStorage(":res/face.xml");
    if (!fs || !faceCas.read(fs->getFirstTopLevelNode())) {
      qCritical() << "Could not read faces data.";
      valid = false;
    }
  }
  catch (...) {
    qCritical() << "Invalid face cascade!";
    valid = false;
  }

  try {
    auto fs = Util::fileToFileStorage(":res/profileface.xml");
    if (!fs || !pfaceCas.read(fs->getFirstTopLevelNode())) {
      qCritical() << "Could not read profile faces data.";
      valid = false;
    }
  }
  catch (...) {
    qCritical() << "Invalid profile face cascade!";
    valid = false;
  }

  try {
    auto fs = Util::fileToFileStorage(":res/eyes.xml");
    if (!fs || !eyesCas.read(fs->getFirstTopLevelNode())) {
      qCritical() << "Could not read eyes data.";
      valid = false;
    }
  }
  catch (...) {
    qCritical() << "Invalid eyes cascade!";
    valid = false;
  }
}

QList<FacePtr> FaceDetector::detect(const MatPtr image) {
  QList<FacePtr> results;
  if (!image) {
    return results;
  }

  // Make grayscaled version of the image, and equalize the histogram
  // which normalizes the brightness and increases the contrast in the
  // image.
  cv::Mat grayImg;
  cvtColor(*image.get(), grayImg, cv::COLOR_BGR2GRAY);
  equalizeHist(grayImg, grayImg);

  // Detect faces with scale factor 1.1, minimum 3 neighbors and
  // minimum 80x80 face size.
  std::vector<cv::Rect> faces;
  faceCas.detectMultiScale(grayImg, faces, 1.1, 3, 0, cv::Size(80, 80));
  results.append(createFaces(faces, grayImg));
  faces.clear();

  // Detect profile faces with the left side visible.
  pfaceCas.detectMultiScale(grayImg, faces, 1.1, 3, 0, cv::Size(80, 80));
  results.append(createFaces(faces, grayImg));
  faces.clear();

  // Flip image vertically to detect the right side of faces.
  cv::flip(grayImg, grayImg, 1);
  pfaceCas.detectMultiScale(grayImg, faces, 1.1, 3, 0, cv::Size(80, 80));
  results.append(createFaces(faces, grayImg, true));

  grayImg.release();
  return results;
}

QList<FacePtr> FaceDetector::createFaces(std::vector<cv::Rect> &faces,
                                         const cv::Mat &image, bool vflip) {
  cv::Size imageSize = image.size();
  QList<FacePtr> results;
  for (auto it = faces.begin(); it != faces.end(); ++it) {
{'fraction_non_alphanumeric': 0.1552538370720189, 'fraction_numerical': 0.016135379771743407, 'mean_word_length': 3.340734415029889, 'pattern_counts': {'":': 6, '<': 45, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 6}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5176433', 'n_tokens_mistral': 1820, 'n_tokens_neox': 1683, 'n_words': 444}