/* This file is part of Fast Track. FastTrack is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. FastTrack is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with FastTrack. If not, see . */ #include "cli.h" void loadConfig(const QString &path, QHash ¶meters) { QFile parameterFile(path); if (parameterFile.open(QIODevice::ReadOnly | QIODevice::Text)) { QTextStream in(¶meterFile); QString line; QStringList params; while (in.readLineInto(&line)) { if (line.contains(QLatin1String("="))) { params = line.split(QStringLiteral("="), Qt::SkipEmptyParts); parameters.insert(params[0].trimmed(), params[1].trimmed()); } } parameters.remove(QStringLiteral("title")); parameterFile.close(); } } void help() { printf("Usage: [OPTION]... [FILE]...\n"); fputs(("\ Use FastTrack version \ "), stdout); fputs((APP_VERSION), stdout); fputs(("\ from the command line.\n\ \n\ "), stdout); fputs(("\ All arguments are mandatory except --backPath and --cfg. Loading a configuration file with --cfg overwrite any selected parameters.\n\ "), stdout); fputs(("\ --maxArea maximal area of objects\n\ --minArea minimal area of objects\n\ \n\ --lightBack is the background light? 0: Yes, 1: No\n\ --thresh binary threshold, if lightBack is set to 0 (resp. 1), pixels with values less (resp. more) than thresh are considered to belong to an object\n\ --reg registration method, 0: None, 1: Simple, 2: ECC, 3: Features\n\ \n\ --spot part of the object that features is used for the matching, 0: head, 1: tail, 2: body\n\ --normDist normalization distance pixels\n\ --normAngle normalization angle degres\n\ --normArea normalization area pixels\n\ --normPerim normalization perimeter pixels\n\ --maxDist maximal distance of matching in pixels, if an object travels more than this distance, it is considered as a new object\n\ --maxTime maximal time, if an object disappears more than this time, it is considered as a new object\n\ \n\ --nBack number of images to compute the background\n\ --methBack method to compute the background. 0: min, 1: max, 2: average\n\ --regBack registration method to compute the background. 0: None, 1: Simple, 2: ECC, 3: Features\n\ \n\ --xTop roi x top corner (0:width-1)\n\ --yTop roi y top corner (0:height-1)\n\ --xBottom roi x top corner (0:xTop-1), set to 0 to avoid cropping\n\ --yBottom roi y top corner (0:yTop-1), set to 0 to avoid cropping\n\ \n\ --morph morphological operation, 0: None, 1: Erode, 2: Dilate, 3: Open, 4: Close, 5: Gradient, 6: TopHat, 7: BlackHat, 8: HitMiss\n\ --morphSize size of the kernel used in the morphological operation, can be omited if no operation are performed\n\ --morphType type of the kernel used in the morphological operation, can be omited if no operation are performed, 0: Rect, 1: Cross, 2: Ellipse\n\ \n\ --path path to the movie or one image of a sequence\n\ --backPath optional, path to a background image\n\ \n\ --cfg optional, path to a configuration file, if path is not included in the configuration file, --path option need to be put before --cfg option\n\ "), stdout); } int cli(int, char **) { QCommandLineParser parser; const QStringList parameterNames = { QStringLiteral("maxArea"), QStringLiteral("minArea"), QStringLiteral("spot"), QStringLiteral("normDist"), QStringLiteral("normAngle"), QStringLiteral("normArea"), QStringLiteral("normPerim"), QStringLiteral("maxDist"), QStringLiteral("maxTime"), QStringLiteral("thresh"), QStringLiteral("nBack"), QStringLiteral("methBack"), QStringLiteral("regBack"), QStringLiteral("xTop"), QStringLiteral("yTop"), QStringLiteral("xBottom"), QStringLiteral("yBottom"), QStringLiteral("reg"), QStringLiteral("lightBack"), QStringLiteral("morph"), QStringLiteral("morphSize"), QStringLiteral("morphType"), QStringLiteral("path"), QStringLiteral("backPath")}; for (const QString &name : parameterNames) { parser.addOption(QCommandLineOption(name, QString(), QStringLiteral("value"))); } parser.addOption(QCommandLineOption(QStringLiteral("cfg"), QString(), QStringLiteral("path"))); parser.addOption(QCommandLineOption(QStringLiteral("help"))); parser.addOption(QCommandLineOption(QStringLiteral("version"))); if (!parser.parse(QCoreApplication::arguments())) { fprintf(stderr, "%s\n", parser.errorText().toLocal8Bit().constData()); return 1; } if (parser.isSet(QStringLiteral("help"))) { help(); return 0; } if (parser.isSet(QStringLiteral("version"))) { printf("FastTrack "); printf(APP_VERSION); printf("\nLicense GPLv3+: GNU GPL version 3\nThis is free software: you are free to change and redistribute it.\nThere is NO WARRANTY, to the extent permitted by law.\nWritten by Benjamin Gallois\n"); return 0; } QHash parameters; for (const QString &name : parameterNames) { if (parser.isSet(name)) { parameters.insert(name, parser.value(name)); } } if (parser.isSet(QStringLiteral("cfg"))) { loadConfig(parser.value(QStringLiteral("cfg")), parameters); } QHashIterator i(parameters); while (i.hasNext()) { i.next(); cout << i.key().toStdString() << " set to: " << i.value().toStdString() << endl; } Tracking *tracking; if (parameters.contains(QStringLiteral("backPath"))) { tracking = new Tracking(parameters.value(QStringLiteral("path")).toStdString(), parameters.value(QStringLiteral("backPath")).toStdString()); } else { tracking = new Tracking(parameters.value(QStringLiteral("path")).toStdString(), ""); } QObject::connect(tracking, &Tracking::finished, []() { cout << "Tracking ended normally" << endl; }); QObject::connect(tracking, &Tracking::forceFinished, [](const QString &message) { cout << message.toStdString() << endl; }); tracking->updatingParameters(parameters); tracking->startProcess(); return 0; }