File indexing completed on 2025-01-19 03:57:41

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2010-06-16
0007  * Description : Face detection CLI tool
0008  *
0009  * SPDX-FileCopyrightText: 2010 by Aditya Bhatt <adityabhatt1991 at gmail dot com>
0010  * SPDX-FileCopyrightText: 2019 by Thanh Trung Dinh <dinhthanhtrung1996 at gmail dot com>
0011  *
0012  * SPDX-License-Identifier: GPL-2.0-or-later
0013  *
0014  * ============================================================ */
0015 
0016 // Qt includes
0017 
0018 #include <QApplication>
0019 #include <QImage>
0020 #include <QHBoxLayout>
0021 #include <QLabel>
0022 #include <QPixmap>
0023 #include <QWidget>
0024 #include <QElapsedTimer>
0025 #include <QRectF>
0026 #include <QList>
0027 #include <QScrollArea>
0028 #include <QPainter>
0029 #include <QtGlobal>
0030 
0031 // Local includes
0032 
0033 #include "digikam_debug.h"
0034 #include "facedetector.h"
0035 
0036 using namespace Digikam;
0037 
0038 void detectFaces(const QString& imagePath)
0039 {
0040     qCDebug(DIGIKAM_TESTS_LOG) << "Loading " << imagePath;
0041     QImage img(imagePath);
0042     QImage imgScaled(img.scaled(416, 416, Qt::KeepAspectRatio));
0043 
0044     FaceDetector detector;
0045     qCDebug(DIGIKAM_TESTS_LOG) << "Detecting faces";
0046 
0047     QElapsedTimer timer;
0048     unsigned int elapsedDetection = 0;
0049 
0050     timer.start();
0051     QList<QRectF> faces = detector.detectFaces(imagePath);
0052     elapsedDetection = timer.elapsed();
0053 
0054     qCDebug(DIGIKAM_TESTS_LOG) << "(Input CV) Found " << faces.size() << " faces, in " << elapsedDetection << "ms";
0055 
0056     if (faces.isEmpty())
0057     {
0058         qCDebug(DIGIKAM_TESTS_LOG) << "No faces found";
0059         return;
0060     }
0061 
0062     qCDebug(DIGIKAM_TESTS_LOG) << "Coordinates of detected faces : ";
0063 
0064     Q_FOREACH (const QRectF& r, faces)
0065     {
0066         qCDebug(DIGIKAM_TESTS_LOG) << r;
0067     }
0068 
0069     QWidget* const mainWidget = new QWidget;
0070 
0071     QScrollArea* const scrollArea = new QScrollArea;
0072     scrollArea->setWidget(mainWidget);
0073     scrollArea->setWidgetResizable(true);
0074 
0075     QHBoxLayout* const layout = new QHBoxLayout(mainWidget);
0076     QLabel* const fullImage = new QLabel;
0077     fullImage->setScaledContents(true);
0078     layout->addWidget(fullImage);
0079 
0080     QPainter painter(&imgScaled);
0081     QPen paintPen(Qt::green);
0082     paintPen.setWidth(1);
0083     painter.setPen(paintPen);
0084 
0085     Q_FOREACH (const QRectF& rr, faces)
0086     {
0087         QLabel* const label = new QLabel;
0088         label->setScaledContents(false);
0089         QRect rectDraw      = FaceDetector::toAbsoluteRect(rr, imgScaled.size());
0090         QRect r             = FaceDetector::toAbsoluteRect(rr, img.size());
0091         QImage part         = img.copy(r);
0092         label->setPixmap(QPixmap::fromImage(part.scaled(qMin(img.size().width(), 50),
0093                                                         qMin(img.size().width(), 50),
0094                                                         Qt::KeepAspectRatio)));
0095         layout->addWidget(label);
0096         painter.drawRect(rectDraw);
0097     }
0098 
0099     // Only setPixmap after finishing drawing bboxes around detected faces
0100     fullImage->setPixmap(QPixmap::fromImage(imgScaled));
0101 
0102     scrollArea->show();
0103     scrollArea->setWindowTitle(imagePath);
0104     qApp->processEvents(); // dirty hack
0105 }
0106 
0107 int main(int argc, char** argv)
0108 {
0109     if (argc < 2)
0110     {
0111         qCDebug(DIGIKAM_TESTS_LOG) << "Bad Arguments!!!\nUsage: " << argv[0] << " <image1> <image2> ...";
0112         return 0;
0113     }
0114 
0115     QApplication app(argc, argv);
0116 
0117     for (int i = 1 ; i < argc ; ++i)
0118     {
0119         detectFaces(QString::fromLocal8Bit(argv[i]));
0120     }
0121 
0122     app.exec();
0123 
0124     return 0;
0125 }