~ubuntu-branches/ubuntu/saucy/digikam/saucy

« back to all changes in this revision

Viewing changes to libs/database/haar/haariface.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Alessandro Ghersi
  • Date: 2010-10-24 00:20:43 UTC
  • mfrom: (1.2.31 upstream)
  • Revision ID: james.westby@ubuntu.com-20101024002043-y7y9fg4rvxy0obcc
Tags: 2:1.5.0-0ubuntu1
* New upstream release
  - Bump build-dependencies
  - Build against libkipi-dev 1.5.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
7
7
 * Description : Haar Database interface
8
8
 *
9
9
 * Copyright (C) 2003 by Ricardo Niederberger Cabral <nieder at mail dot ru>
10
 
 * Copyright (C) 2009 by Gilles Caulier <caulier dot gilles at gmail dot com>
11
 
 * Copyright (C) 2009 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
12
 
 * Copyright (C) 2009 by Andi Clemens <andi dot clemens at gmx dot net>
 
10
 * Copyright (C) 2009-2010 by Gilles Caulier <caulier dot gilles at gmail dot com>
 
11
 * Copyright (C) 2009-2010 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
 
12
 * Copyright (C) 2009-2010 by Andi Clemens <andi dot clemens at gmx dot net>
13
13
 *
14
14
 * This program is free software; you can redistribute it
15
15
 * and/or modify it under the terms of the GNU General
57
57
#include "searchxml.h"
58
58
#include "haar.h"
59
59
#include "sqlquery.h"
60
 
/*#include "imagecomments_p.h"
61
 
#include "imageposition_p.h"
62
 
*/
 
60
 
63
61
using namespace std;
64
62
 
65
63
namespace Digikam
75
73
 */
76
74
class DatabaseBlob
77
75
{
78
 
 
79
76
public:
80
77
 
81
78
    enum { Version = 1 };
86
83
 
87
84
    /** Read the QByteArray into the Haar::SignatureData.
88
85
     */
89
 
    void read(const QByteArray& array, Haar::SignatureData *data)
 
86
    void read(const QByteArray& array, Haar::SignatureData* data)
90
87
    {
91
88
        QDataStream stream(array);
92
89
 
111
108
                stream >> data->sig[i][j];
112
109
    }
113
110
 
114
 
    QByteArray write(Haar::SignatureData *data)
 
111
    QByteArray write(Haar::SignatureData* data)
115
112
    {
116
113
        QByteArray array;
117
114
        array.reserve(sizeof(qint32) + 3*sizeof(double) + 3*sizeof(qint32)*Haar::NumberOfCoefficients);
134
131
    }
135
132
};
136
133
 
137
 
class HaarIfacePriv
 
134
// -----------------------------------------------------------------------------------------------------
 
135
 
 
136
class HaarIface::HaarIfacePriv
138
137
{
139
 
 
140
138
public:
141
139
 
142
140
    HaarIfacePriv()
223
221
        Haar::SignatureData targetSig;
224
222
 
225
223
        // reference for easier access
226
 
        SignatureCache &signatureCache = *this->signatureCache;
 
224
        SignatureCache& signatureCache = *this->signatureCache;
227
225
 
228
226
        SqlQuery query = access.backend()->prepareQuery(signatureQuery);
229
227
        if (!access.backend()->exec(query))
237
235
        }
238
236
    }
239
237
 
240
 
    bool              useSignatureCache;
241
 
    Haar::ImageData*  data;
242
 
    Haar::WeightBin*  bin;
243
 
    SignatureCache*   signatureCache;
244
 
    QString           signatureQuery;
245
 
    QString           signatureByAlbumRootsQuery;
246
 
    QSet<int>         albumRootsToSearch;
 
238
    bool             useSignatureCache;
 
239
    Haar::ImageData* data;
 
240
    Haar::WeightBin* bin;
 
241
    SignatureCache*  signatureCache;
 
242
    QString          signatureQuery;
 
243
    QString          signatureByAlbumRootsQuery;
 
244
    QSet<int>        albumRootsToSearch;
247
245
};
248
246
 
249
247
HaarIface::HaarIface()
423
421
    return bestMatches(&sig, numberOfResults, type);
424
422
}
425
423
 
426
 
QList<qlonglong> HaarIface::bestMatches(Haar::SignatureData *querySig, int numberOfResults, SketchType type)
 
424
QList<qlonglong> HaarIface::bestMatches(Haar::SignatureData* querySig, int numberOfResults, SketchType type)
427
425
{
428
426
    QMap<qlonglong, double> scores = searchDatabase(querySig, type);
429
427
 
434
432
    bool initialFill = false;
435
433
    double score, worstScore, bestScore;
436
434
    qlonglong id;
 
435
 
437
436
    for (QMap<qlonglong, double>::const_iterator it = scores.constBegin(); it != scores.constEnd(); ++it)
438
437
    {
439
438
        score = it.value();
474
473
    return bestMatches.values();
475
474
}
476
475
 
477
 
QList<qlonglong> HaarIface::bestMatchesWithThreshold(Haar::SignatureData *querySig, double requiredPercentage,
 
476
QList<qlonglong> HaarIface::bestMatchesWithThreshold(Haar::SignatureData* querySig, double requiredPercentage,
478
477
                                                     SketchType type)
479
478
{
480
479
    QMap<qlonglong, double> scores = searchDatabase(querySig, type);
487
486
    QMultiMap<double, qlonglong> bestMatches;
488
487
    double score, percentage;
489
488
    qlonglong id;
 
489
 
490
490
    for (QMap<qlonglong, double>::const_iterator it = scores.constBegin(); it != scores.constEnd(); ++it)
491
491
    {
492
492
        score = it.value();
513
513
}
514
514
 
515
515
/// This method is the core functionality: It assigns a score to every image in the db
516
 
QMap<qlonglong, double> HaarIface::searchDatabase(Haar::SignatureData *querySig, SketchType type)
 
516
QMap<qlonglong, double> HaarIface::searchDatabase(Haar::SignatureData* querySig, SketchType type)
517
517
{
518
518
    d->createWeightBin();
519
519
 
578
578
            }
579
579
            else
580
580
            {
581
 
                double              &score = scores[imageid];
582
 
                Haar::SignatureData &qSig  = *querySig;
583
 
                Haar::SignatureData &tSig  = targetSig;
 
581
                double&              score = scores[imageid];
 
582
                Haar::SignatureData& qSig  = *querySig;
 
583
                Haar::SignatureData& tSig  = targetSig;
584
584
 
585
585
                score = calculateScore(qSig, tSig, weights, queryMaps);
586
586
            }
589
589
    // read cached signature map if possible
590
590
    else
591
591
    {
592
 
        foreach (const qlonglong &imageid, signatureCache.keys())
 
592
        foreach (const qlonglong& imageid, signatureCache.keys())
593
593
        {
594
594
            double& score              = scores[imageid];
595
 
            Haar::SignatureData &qSig  = *querySig;
596
 
            Haar::SignatureData &tSig  = signatureCache[imageid];
 
595
            Haar::SignatureData& qSig  = *querySig;
 
596
            Haar::SignatureData& tSig  = signatureCache[imageid];
597
597
 
598
598
            score = calculateScore(qSig, tSig, weights, queryMaps);
599
599
        }
600
600
    }
601
601
 
602
 
 
603
602
    return scores;
604
603
}
605
604
 
628
627
    return image;
629
628
}
630
629
 
631
 
bool HaarIface::retrieveSignatureFromDB(qlonglong imageid, Haar::SignatureData *sig)
 
630
bool HaarIface::retrieveSignatureFromDB(qlonglong imageid, Haar::SignatureData* sig)
632
631
{
633
632
    QList<QVariant> values;
634
633
    DatabaseAccess().backend()->execSql(QString("SELECT matrix FROM ImageHaarMatrix WHERE imageid=?"),
643
642
    return true;
644
643
}
645
644
 
646
 
void HaarIface::getBestAndWorstPossibleScore(Haar::SignatureData *sig, SketchType type,
647
 
                                             double *lowestAndBestScore, double *highestAndWorstScore)
 
645
void HaarIface::getBestAndWorstPossibleScore(Haar::SignatureData* sig, SketchType type,
 
646
                                             double* lowestAndBestScore, double* highestAndWorstScore)
648
647
{
649
648
    Haar::Weights weights((Haar::Weights::SketchType)type);
650
649
    double score = 0;
676
675
}
677
676
 
678
677
void HaarIface::rebuildDuplicatesAlbums(const QList<int>& albums2Scan, const QList<int>& tags2Scan,
679
 
                                        double requiredPercentage, HaarProgressObserver *observer)
 
678
                                        double requiredPercentage, HaarProgressObserver* observer)
680
679
{
681
680
    // Carry out search. This takes long.
682
681
    QMap< qlonglong, QList<qlonglong> > results = findDuplicatesInAlbumsAndTags(albums2Scan,
714
713
    }
715
714
}
716
715
 
717
 
 
718
716
QMap< qlonglong, QList<qlonglong> > HaarIface::findDuplicatesInAlbums(const QList<int>& albums2Scan,
719
 
                                               double requiredPercentage, HaarProgressObserver *observer)
 
717
                                               double requiredPercentage, HaarProgressObserver* observer)
720
718
{
721
719
    QSet<qlonglong> idList;
722
720
 
731
729
 
732
730
QMap< qlonglong, QList<qlonglong> > HaarIface::findDuplicatesInAlbumsAndTags(const QList<int>& albums2Scan,
733
731
                                               const QList<int>& tags2Scan,
734
 
                                               double requiredPercentage, HaarProgressObserver *observer)
 
732
                                               double requiredPercentage, HaarProgressObserver* observer)
735
733
{
736
734
    QSet<qlonglong> idList;
737
735
 
751
749
}
752
750
 
753
751
QMap< qlonglong, QList<qlonglong> > HaarIface::findDuplicates(const QSet<qlonglong>& images2Scan,
754
 
                                               double requiredPercentage, HaarProgressObserver *observer)
 
752
                                               double requiredPercentage, HaarProgressObserver* observer)
755
753
{
756
754
    QMap< qlonglong, QList<qlonglong> >  resultsMap;
757
755
    QSet<qlonglong>::const_iterator      it;
829
827
    }
830
828
 
831
829
    // Step 2: Decrease the score if query and target have significant coefficients in common
832
 
    Haar::Idx *sig               = 0;
833
 
    Haar::SignatureMap *queryMap = 0;
 
830
    Haar::Idx* sig               = 0;
 
831
    Haar::SignatureMap* queryMap = 0;
834
832
    int x                        = 0;
835
833
 
836
834
    for (int channel = 0; channel < 3; ++channel)