File indexing completed on 2025-01-19 03:55:50

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 25/08/2013
0007  * Description : Image Quality Calculor
0008  *
0009  * SPDX-FileCopyrightText: 2013-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
0010  * SPDX-FileCopyrightText: 2021-2022 by Phuoc Khanh Le <phuockhanhnk94 at gmail dot com>
0011  *
0012  * SPDX-License-Identifier: GPL-2.0-or-later
0013  *
0014  * ============================================================ */
0015 
0016 #include "imagequalitycalculator.h"
0017 
0018 // Qt includes
0019 
0020 #include <QRecursiveMutex>
0021 
0022 namespace Digikam
0023 {
0024 
0025 class Q_DECL_HIDDEN ImageQualityCalculator::Private
0026 {
0027 public:
0028 
0029     explicit Private()
0030       : threshold_punish(0.9),
0031         weight_punish   (20.0)
0032     {
0033     }
0034 
0035     float                  threshold_punish;
0036     float                  weight_punish;
0037 
0038     QRecursiveMutex        mutex;
0039 
0040     QList<ResultDetection> detectionResults;
0041 };
0042 
0043 ImageQualityCalculator::ImageQualityCalculator()
0044     : d(new Private)
0045 {
0046     d->detectionResults = QList<ResultDetection>();
0047 }
0048 
0049 ImageQualityCalculator::~ImageQualityCalculator()
0050 {
0051     delete d;
0052 }
0053 
0054 void ImageQualityCalculator::addDetectionResult(const QString& name,
0055                                                 const float score,
0056                                                 const float weight) const
0057 {
0058     ResultDetection result;
0059 
0060     result.detetionType = name;
0061     result.weight       = weight;
0062     result.score        = score;
0063 
0064     QMutexLocker locker(&d->mutex);
0065 
0066     d->detectionResults.append(result);
0067 }
0068 
0069 void ImageQualityCalculator::normalizeWeight() const
0070 {
0071     float sum = 0.0F;
0072 
0073     for (const auto& result : d->detectionResults)
0074     {
0075         sum += result.weight;
0076     }
0077 
0078     for (auto& result : d->detectionResults)
0079     {
0080         result.weight /= sum;
0081     }
0082 }
0083 
0084 float ImageQualityCalculator::calculateQuality() const
0085 {
0086     QMutexLocker locker(&d->mutex);
0087 
0088     if (!numberDetectors())
0089     {
0090         return (-1.0F);
0091     }
0092 
0093     adjustWeightByQualityLevel();
0094 
0095     normalizeWeight();
0096 
0097     float damage = 0.0F;
0098 
0099     for (const auto& result : d->detectionResults)
0100     {
0101         damage += result.score * result.weight;
0102     }
0103 
0104     return ((1.0F - damage) * 100.0F);
0105 }
0106 
0107 int ImageQualityCalculator::numberDetectors() const
0108 {
0109     return d->detectionResults.count();
0110 }
0111 
0112 void ImageQualityCalculator::adjustWeightByQualityLevel() const
0113 {
0114     for (auto& result : d->detectionResults)
0115     {
0116         if (result.score > d->threshold_punish)
0117         {
0118             result.weight *= d->weight_punish;
0119         }
0120     }
0121 }
0122 
0123 } // namespace Digikam