diff --git a/openbr/core/qtutils.cpp b/openbr/core/qtutils.cpp index 7ac1dad..d652aad 100644 --- a/openbr/core/qtutils.cpp +++ b/openbr/core/qtutils.cpp @@ -401,12 +401,17 @@ QString toString(const QVariant &variant) { if (QString(variant.typeName()) == "QVariantList") return toString(qvariant_cast(variant)); else if (variant.canConvert(QVariant::String)) return variant.toString(); - else if (variant.canConvert(QVariant::PointF)) return QString("(%1,%2)").arg(QString::number(qvariant_cast(variant).x()), - QString::number(qvariant_cast(variant).y())); - else if (variant.canConvert(QVariant::RectF)) return QString("(%1,%2,%3,%4)").arg(QString::number(qvariant_cast(variant).x()), - QString::number(qvariant_cast(variant).y()), - QString::number(qvariant_cast(variant).width()), - QString::number(qvariant_cast(variant).height())); + else if (variant.canConvert(QVariant::PointF)) { + QPointF point = qvariant_cast(variant); + return QString("(%1,%2)").arg(QString::number(point.x()),QString::number(point.y())); + } else if (variant.canConvert(QVariant::RectF)) { + QRectF rect = qvariant_cast(variant); + return QString("(%1,%2,%3,%4)").arg(QString::number(rect.x()), + QString::number(rect.y()), + QString::number(rect.width()), + QString::number(rect.height())); + } + return QString(); } diff --git a/openbr/core/qtutils.h b/openbr/core/qtutils.h index 7d618ae..3435b80 100644 --- a/openbr/core/qtutils.h +++ b/openbr/core/qtutils.h @@ -75,6 +75,16 @@ namespace QtUtils QString toString(const QVariant &variant); QString toString(const QVariantList &variantList); + template + QVariantList toVariantList(const QList &list) + { + QVariantList variantList; + foreach (const T &item, list) + variantList << item; + + return variantList; + } + /**** Point Utilities ****/ float euclideanLength(const QPointF &point); } diff --git a/openbr/openbr_plugin.cpp b/openbr/openbr_plugin.cpp index 21981ee..02a1caa 100644 --- a/openbr/openbr_plugin.cpp +++ b/openbr/openbr_plugin.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -40,6 +41,12 @@ using namespace br; using namespace cv; +// Some globals used to transfer data to Context::messageHandler so that +// we can restart the process if we try and fail to create a QApplication. +static bool creating_qapp = false; +static int * argc_ptr = NULL; +static char ** argv_ptr = NULL; + /* File - public methods */ // Note that the convention for displaying metadata is as follows: // [] for lists in which argument order does not matter (e.g. [FTO=false, Index=0]), @@ -218,6 +225,11 @@ void File::appendRect(const QRectF &rect) m_metadata["Rects"] = newRects; } +void File::appendRect(const Rect &rect) +{ + appendRect(OpenCVUtils::fromRect(rect)); +} + void File::appendRects(const QList &rects) { QList newRects = m_metadata["Rects"].toList(); @@ -226,6 +238,11 @@ void File::appendRects(const QList &rects) m_metadata["Rects"] = newRects; } +void File::appendRects(const QList &rects) +{ + appendRects(OpenCVUtils::fromRects(rects)); +} + /* File - private methods */ void File::init(const QString &file) { @@ -877,14 +894,28 @@ void br::Context::initialize(int &argc, char *argv[], QString sdkPath, bool use_ break; } } + + qInstallMessageHandler(messageHandler); + // We take in argc as a reference due to: // https://bugreports.qt-project.org/browse/QTBUG-5637 // QApplication should be initialized before anything else. // Since we can't ensure that it gets deleted last, we never delete it. if (QCoreApplication::instance() == NULL) { #ifndef BR_EMBEDDED - if (use_gui) application = new QApplication(argc, argv); - else application = new QCoreApplication(argc, argv); + if (use_gui) { + // Set up variables to be used in the message handler if this fails. + // Just so you know, we + creating_qapp = true; + argc_ptr = &argc; + argv_ptr = argv; + + application = new QApplication(argc, argv); + creating_qapp = false; + } + else { + application = new QCoreApplication(argc, argv); + } #else application = new QCoreApplication(argc, argv); #endif @@ -910,7 +941,6 @@ void br::Context::initialize(int &argc, char *argv[], QString sdkPath, bool use_ Globals->init(File()); Globals->useGui = use_gui; - qInstallMessageHandler(messageHandler); Common::seedRNG(); @@ -979,6 +1009,26 @@ void br::Context::messageHandler(QtMsgType type, const QMessageLogContext &conte static QMutex generalLock; QMutexLocker locker(&generalLock); + // If we are trying to create a QApplication, and get a fatal, then restart the process + // with useGui set to 0. + if (creating_qapp && type == QtFatalMsg) + { + // re-launch process with useGui = 0 + std::cout << "Failed to initialize gui, restarting with -useGui 0" << std::endl; + QStringList arguments; + arguments.append("-useGui"); + arguments.append("0"); + for (int i=1; i < *argc_ptr; i++) + { + arguments.append(argv_ptr[i]); + } + // QProcess::execute blocks until the other process completes. + QProcess::execute(argv_ptr[0], arguments); + // have to unlock this for some reason + locker.unlock(); + std::exit(0); + } + QString txt; if (type == QtDebugMsg) { if (Globals->quiet) return; diff --git a/openbr/plugins/template.cpp b/openbr/plugins/template.cpp index 316330c..5d92eba 100644 --- a/openbr/plugins/template.cpp +++ b/openbr/plugins/template.cpp @@ -28,55 +28,6 @@ BR_REGISTER(Transform, KeepMetadataTransform) /*! * \ingroup transforms - * \brief Restricts the metadata available within a file - * \author Scott Klum \cite sklum - */ -class RestrictMetadataTransform : public MetaTransform -{ - Q_OBJECT - Q_PROPERTY(QString description READ get_description WRITE set_description RESET reset_description STORED false) - BR_PROPERTY(QString, description, "Identity") - Q_PROPERTY(QStringList pointSets READ get_pointSets WRITE set_pointSets RESET reset_pointSets STORED false) - BR_PROPERTY(QStringList, pointSets, QStringList()) - Q_PROPERTY(QStringList rectSets READ get_rectSets WRITE set_rectSets RESET reset_rectSets STORED false) - BR_PROPERTY(QStringList, rectSets, QStringList()) - - br::Transform* transform; - - void init() - { - transform = make(description); - } - - void train(const QList &data) - { - // Update data to only include metadata from the given set - transform->train(data); - } - - void project(const Template &src, Template &dst) const - { - Template tmp = src; - - // Change this to clear only one if list isn't empty - tmp.file.clearPoints(); tmp.file.clearRects(); - - foreach(const QString& set, pointSets) tmp.file.appendPoints(src.getList(set)); - foreach(const QString& set, rectSets) tmp.file.appendRects(src.getList(set)); - - // Put a template through some transforms with the metadata restriction - transform->project(tmp, dst); - - // Keep original points/rects - dst.file.appendPoints(src.file.points()); - dst.file.appendRects(src.file.rects()); - } -}; - -BR_REGISTER(Transform, RestrictMetadataTransform) - -/*! - * \ingroup transforms * \brief Remove templates with the specified file extension or metadata value. * \author Josh Klontz \cite jklontz */