void MainWindow::createThreads()
{
    pt_videoThread = new QThread(this);
    pt_videocapture = new QVideoCapture();
    pt_videocapture->moveToThread(pt_videoThread);
    connect(pt_videoThread, SIGNAL(started()), pt_videocapture, SLOT(initializeTimer()));
    connect(pt_videoThread, SIGNAL(finished()), pt_videocapture, SLOT(close()));
    connect(pt_videoThread, SIGNAL(finished()), pt_videocapture, SLOT(deleteLater()));

    pt_stasmThread = new QThread(this);
    pt_stasm = new QStasm();
    pt_stasm->moveToThread(pt_stasmThread);
    connect(pt_stasmThread, SIGNAL(finished()), pt_stasm, SLOT(deleteLater()));

    pt_opencvThread = new QThread(this);
    pt_opencv = new QOpencvProcessor();
    pt_opencv->moveToThread(pt_opencvThread);
    connect(pt_opencvThread, SIGNAL(finished()), pt_opencv, SLOT(deleteLater())); 

    pt_videowriter = new QVideoWriter();
    pt_videowriter->moveToThread(pt_videoThread);
    connect(pt_videoThread, SIGNAL(finished()), pt_videowriter, SLOT(deleteLater()));

    pt_facetracker = new QFaceTracker();
    #ifdef CASCADECLASSIFIERS_PATH
        bool res = pt_facetracker->loadFaceClassifier(QString("%1%2").arg(CASCADECLASSIFIERS_PATH, "/haarcascade_frontalface_alt2.xml").toStdString());
        qWarning("Face classifier was %s", res ? "loaded": "not loaded");
        res = pt_facetracker->loadEyeClassifier(QString("%1%2").arg(CASCADECLASSIFIERS_PATH, "/haarcascade_eye.xml").toStdString());
        qWarning("Eye classifier was %s", res ? "loaded": "not loaded");
    #else
        pt_facetracker->loadFaceClassifier("data/haarcascade_frontalface_alt2.xml");
        pt_facetracker->loadEyeClassifier("data/haarcascade_eye.xml");
    #endif
    pt_facetracker->moveToThread(pt_stasmThread);
    connect(pt_stasmThread, SIGNAL(finished()), pt_facetracker, SLOT(deleteLater()));

    qRegisterMetaType<cv::Mat>("cv::Mat");
    qRegisterMetaType<cv::RotatedRect>("cv::RotatedRect");
    connect(pt_videocapture, SIGNAL(frameUpdated(cv::Mat)), pt_opencv, SLOT(custom_algorithm(cv::Mat)), Qt::BlockingQueuedConnection);
    connect(pt_videocapture, SIGNAL(frameUpdated(cv::Mat)), pt_facetracker, SLOT(updateImage(cv::Mat)), Qt::BlockingQueuedConnection);
    connect(pt_facetracker, SIGNAL(faceUpdated(cv::Mat,cv::RotatedRect)), pt_stasm, SLOT(search_points(cv::Mat, cv::RotatedRect)));
    connect(pt_stasm, SIGNAL(landmarksUpdated(cv::Mat,const float*,uint)), ui->display, SLOT(updateImage(cv::Mat,const float*,uint)));
    connect(pt_stasm, SIGNAL(displacementsUpdated(const float*,uint)), ui->waterfall, SLOT(updateNextColumn(const float*,uint)));

    qRegisterMetaType<DataSeria>("DataSeria");
    pt_seriesanalyzer = new QSeriesAnalyzer();
    pt_seriesanalyzer->moveToThread(pt_opencvThread);
    connect(pt_opencvThread, SIGNAL(finished()), pt_seriesanalyzer, SLOT(deleteLater()));

    pt_videoThread->start();   
    pt_opencvThread->start();
    pt_stasmThread->start(QThread::HighPriority);
}
FaceDatabaseProvider::FaceDatabaseProvider(QSparqlConnection *connection, QObject *parent) :
    QStandardItemModel(0, GalleryPeopleListPage::CeilingColumn, parent),
    m_sparqlConnection(connection)
{
    QString databaseName = QString(getenv("XDG_DATA_HOME")) + "/gallerycore/data/faces.db";
    NullThumbnailer thumbnailer;
    m_faceDatabase = new XQFaceDatabase(thumbnailer, databaseName);
    update();
    ENFORCE(connect(m_faceDatabase, SIGNAL(faceUpdated(XQFaceRegion,QString)),
                    this, SLOT(update())));
    connect(m_faceDatabase, SIGNAL(groupMerged(QString,QString)),
            this, SLOT(update()));
}