Table of Contents

FaceDetect

Automatic thumbnail cropping often fails to capture important content. When cropping horizontal thumbs from vertical images (or vice versa), the crop might include irrelevant areas like part of the body instead of the face. Examples http://demo.smartcj.com/category/Regular%20Links%202%20FHG/. This happens even with vertical-to-vertical crops if the head isn't centered.

Face detection solves this by identifying where faces appear in the image. If a face falls outside the thumbnail boundaries, the script shifts the crop area to include it.

Compare the results: http://demo.smartcj.com/category/FHG%20and%20Facedetect/ shows the same galleries cropped with face detection enabled — notice the improved framing.

Setup

#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/objdetect/objdetect.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>

const char* keys =
{
        "{input| |The source image}"
        "{outdir| |The output directory}"
        "{cascade| |The cascade file}"
};

int main(int argc, const char** argv)
{
        cv::CommandLineParser parser(argc, argv, keys);
        std::string infile = parser.get<std::string>("input");
        std::string outdir = parser.get<std::string>("outdir");
        std::string cascade_file = parser.get<std::string>("cascade");

        cv::CascadeClassifier cascade;
        if (cascade_file.empty() || !cascade.load(cascade_file))
        {
                std::cout << cv::format("Error: cannot load cascade file! \n");
                return -1;
        }

        cv::Mat src = cv::imread(infile);
        if (src.empty())
        {
                std::cout << cv::format("Error: cannot load source image!\n");
                return -1;
        }

        cv::Mat gray;
        cv::cvtColor(src, gray, cv::COLOR_BGR2GRAY);
        cv::equalizeHist(gray, gray);

        std::vector<cv::Rect> faces;
        cascade.detectMultiScale(gray, faces, 1.2, 3);

        cv::Mat src_copy = src.clone();
        for (int i = 0; i < faces.size(); i++)
        {
                std::cout << faces[i];
        }

        return 0;
}
g++ `pkg-config --cflags --libs opencv4` face.cpp `pkg-config --libs opencv4` -o face
/FULL/PATH/TO/face --input={FILE} --cascade=/FULL/PATH/TO/scj/includes/conf/face.xml

Where: - `/FULL/PATH/TO/face` — the compiled face detection program - `/FULL/PATH/TO/scj/includes/conf/face.xml` — the cascade file that identifies faces (included in every SmartCJ installation, but replaceable) - `–input={FILE}` — substitutes the current file being processed

Face Detect XML

OpenCV uses configuration files (XML) to detect faces. The default configuration is basic; you can replace it with alternative cascade files for better or different results depending on your content.

Find alternative cascade files here: https://github.com/sightmachine/SimpleCV/tree/master/SimpleCV/Features/HaarCascades