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
- Install the OpenCV library (consult your admin or search online for instructions).
- Compile a face detection program. PHP is too slow for this task, so use the provided C++ source code instead.
#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;
}
- Compile with this command:
g++ `pkg-config --cflags --libs opencv4` face.cpp `pkg-config --libs opencv4` -o face
- This creates a `face` executable that detects face positions.
- In your crop profile settings, add the following to the Face Detect field:
/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
