diff --git a/docs/docs/docs/cpp_api.md b/docs/docs/docs/cpp_api.md
index cee4b98..b4a7a69 100644
--- a/docs/docs/docs/cpp_api.md
+++ b/docs/docs/docs/cpp_api.md
@@ -24,11 +24,11 @@ Values are not necessarily stored as strings in the metadata table.
The system will attempt to infer and convert them to their "native" type.
The conversion logic is as follows:
-1. If the value starts with **[** and ends with **]** then it is treated as a comma separated list and represented with QVariantList. Each value in the list is parsed recursively.
-2. If the value starts with **(** and ends with **)** and contains four comma separated elements, each convertable to a floating point number, then it is represented with QRectF.
-3. If the value starts with **(** and ends with **)** and contains two comma separated elements, each convertable to a floating point number, then it is represented with QPointF.
+1. If the value starts with **[** and ends with **]** then it is treated as a comma separated list and represented with [QVariantList](http://doc.qt.io/qt-5/qvariant.html#QVariantList-typedef). Each value in the list is parsed recursively.
+2. If the value starts with **(** and ends with **)** and contains four comma separated elements, each convertable to a floating point number, then it is represented with [QRectF](http://doc.qt.io/qt-4.8/qrectf.html).
+3. If the value starts with **(** and ends with **)** and contains two comma separated elements, each convertable to a floating point number, then it is represented with [QPointF](http://doc.qt.io/qt-4.8/qpointf.html).
4. If the value is convertable to a floating point number then it is represented with float.
-5. Otherwise, it is represented with QString.
+5. Otherwise, it is represented with [QString](http://doc.qt.io/qt-5/QString.html).
Metadata keys fall into one of two categories:
* camelCaseKeys are inputs that specify how to process the file.
@@ -44,11 +44,11 @@ Index | int | Index of a template in a template list
Confidence | float | Classification/Regression quality
FTE | bool | Failure to enroll
FTO | bool | Failure to open
-*_X | float | Position
-*_Y | float | Position
-*_Width | float | Size
-*_Height | float | Size
-*_Radius | float | Size
+\*_X | float | Position
+\*_Y | float | Position
+\*_Width | float | Size
+\*_Height | float | Size
+\*_Radius | float | Size
Label | QString | Class label
Theta | float | Pose
Roll | float | Pose
@@ -59,7 +59,7 @@ Rects | QList | List of unnamed rects
Age | float | Age used for demographic filtering
Gender | QString | Subject gender
Train | bool | The data is for training, as opposed to enrollment
-_* | * | Reserved for internal use
+_\* | \* | Reserved for internal use
---
@@ -75,7 +75,7 @@ Failed to enroll. If true this file failed to be processed somewhere in the temp
### m_metadata
-Map for storing metadata. It is a QString, QVariant key value pairing.
+Map for storing metadata. It is a [QString](http://doc.qt.io/qt-5/QString.html), [QVariant](http://doc.qt.io/qt-5/qvariant.html) key value pairing.
---
@@ -85,11 +85,11 @@ Map for storing metadata. It is a QSt
Default constructor. Sets [FTE](#fte) to false.
-### File(const QString &file)
+### File(const [QString](http://doc.qt.io/qt-5/QString.html) &file)
Initializes the file by calling the private function init.
-### File(const QString &file, const QVariant &label)
+### File(const [QString](http://doc.qt.io/qt-5/QString.html) &file, const [QVariant](http://doc.qt.io/qt-5/qvariant.html) &label)
Initializes the file by calling the private function init. Append label to the [metadata](#m_metadata) using the key "Label".
@@ -97,7 +97,7 @@ Initializes the file by calling the private function init. Append label to the [
Initializes the file with a c-style string.
-### File(const QVariantMap &metadata)
+### File(const [QVariantMap](http://doc.qt.io/qt-5/qvariant.html#QVariantMap-typedef) &metadata)
Sets [FTE](#file#fte) to false and sets the [file metadata](#m_metadata) to metadata.
@@ -106,9 +106,9 @@ Sets [FTE](#file#fte) to false and sets the [file metadata](#m_metadata) to meta
## Static Functions
-### static QVariant parse(QString &value) const
+### static [QVariant](http://doc.qt.io/qt-5/qvariant.html) parse([QString](http://doc.qt.io/qt-5/QString.html) &value) const
-Try to convert value to a QPointF, QRectF, int or float. If a conversion is possible it returns the converted value, otherwise it returns the unconverted string.
+Try to convert value to a [QPointF](http://doc.qt.io/qt-4.8/qpointf.html), [QRectF](http://doc.qt.io/qt-4.8/qrectf.html), int or float. If a conversion is possible it returns the converted value, otherwise it returns the unconverted string.
QString point = "(1, 1)";
QString rect = "(1, 1, 5, 5)";
@@ -122,9 +122,9 @@ Try to convert value to a QPointF
File::parse(fp); // returns QVariant(float, 1.0f)
File::parse(string); // returns QVariant(QString, "Hello World")
-### static QList<QVariant> values(const QList<U> &fileList, const QString &key)
+### static [QList](http://doc.qt.io/qt-5/QList.html)<[QVariant](http://doc.qt.io/qt-5/qvariant.html)> values(const [QList](http://doc.qt.io/qt-5/QList.html)<U> &fileList, const [QString](http://doc.qt.io/qt-5/QString.html) &key)
-This function requires a type specification in place of U. Valid types are [File](#file) and QString. Returns a list of the values of the key in each of the given files.
+This function requires a type specification in place of U. Valid types are [File](#file) and [QString](http://doc.qt.io/qt-5/QString.html). Returns a list of the values of the key in each of the given files.
File f1, f2;
f1.set("Key1", QVariant::fromValue(1));
@@ -134,9 +134,9 @@ This function requires a type specification in place of U. Valid types are [File
File::values(QList() << f1 << f2, "Key1"); // returns [QVariant(float, 1),
// QVariant(float, 3)]
-### static QList<T> get(const QList<U> &fileList, const QString &key)
+### static [QList](http://doc.qt.io/qt-5/QList.html)<T> get(const [QList](http://doc.qt.io/qt-5/QList.html)<U> &fileList, const [QString](http://doc.qt.io/qt-5/QString.html) &key)
-This function requires a type specification in place of T and U. Valid types for U are [File](#file) and QString. T can be any type. Returns a list of the values of the key in each of the given files. If the key doesn't exist in any of the files or the value cannot be converted to type T an error is thrown.
+This function requires a type specification in place of T and U. Valid types for U are [File](#file) and [QString](http://doc.qt.io/qt-5/QString.html). T can be any type. Returns a list of the values of the key in each of the given files. If the key doesn't exist in any of the files or the value cannot be converted to type T an error is thrown.
File f1, f2;
f1.set("Key1", QVariant::fromValue(1));
@@ -147,9 +147,9 @@ This function requires a type specification in place of T and U. Valid types for
File::get(QList() << f1 << f2, "Key2"); // Error: Key doesn't exist in f2
File::get(QList() << f1 << f2, "Key1"); // Error: float is not convertable to QRectF
-### static QList<T> get(const QList<U> &fileList, const QString &key, const T &defaultValue)
+### static [QList](http://doc.qt.io/qt-5/QList.html)<T> get(const [QList](http://doc.qt.io/qt-5/QList.html)<U> &fileList, const [QString](http://doc.qt.io/qt-5/QString.html) &key, const T &defaultValue)
-This function requires a type specification in place of T and U. Valid types for U are [File](#file) and QString. T can be any type. Returns a list of the values of the key in each of the given files. If the key doesn't exist in any of the files or the value cannot be converted to type T the given defaultValue is returned.
+This function requires a type specification in place of T and U. Valid types for U are [File](#file) and [QString](http://doc.qt.io/qt-5/QString.html). T can be any type. Returns a list of the values of the key in each of the given files. If the key doesn't exist in any of the files or the value cannot be converted to type T the given defaultValue is returned.
File f1, f2;
f1.set("Key1", QVariant::fromValue(1));
@@ -160,7 +160,7 @@ This function requires a type specification in place of T and U. Valid types for
File::get(QList() << f1 << f2, "Key2", QList() << 1); // returns [1.]
File::get(QList() << f1 << f2, "Key1, QList()"); // returns []
-### QDebug operator <<(QDebug dbg, const [File](#file) &file)
+### [QDebug](http://doc.qt.io/qt-5/qdebug.html) operator <<([QDebug](http://doc.qt.io/qt-5/qdebug.html) dbg, const [File](#file) &file)
Calls [flat](#qstring-flat-const) on the given file and that streams that file to stderr.
@@ -169,7 +169,7 @@ Calls [flat](#qstring-flat-const) on the given file and that streams that file t
qDebug() << file; // "../path/to/pictures/picture.jpg[Key=Value]" streams to stderr
-### QDataStream &operator <<(QDataStream &stream, const [File](#file) &file)
+### [QDataStream](http://doc.qt.io/qt-5/qdatastream.html) &operator <<([QDataStream](http://doc.qt.io/qt-5/qdatastream.html) &stream, const [File](#file) &file)
Serialize a file to a data stream.
@@ -181,7 +181,7 @@ Serialize a file to a data stream.
stream << file; // "../path/to/pictures/picture.jpg[Key=Value]" serialized to the stream
}
-### QDataStream &operator >>(QDataStream &stream, [File](#file) &file)
+### [QDataStream](http://doc.qt.io/qt-5/qdatastream.html) &operator >>([QDataStream](http://doc.qt.io/qt-5/qdatastream.html) &stream, [File](#file) &file)
Deserialize a file from a data stream.
@@ -203,11 +203,11 @@ Deserialize a file from a data stream.
## Functions
-### Operator QString() const
+### Operator [QString](http://doc.qt.io/qt-5/QString.html)() const
-returns [name](#name). Allows Files to be used as QString.
+returns [name](#name). Allows Files to be used as [QString](http://doc.qt.io/qt-5/QString.html).
-### QString flat() const
+### [QString](http://doc.qt.io/qt-5/QString.html) flat() const
Returns the [name](#name) and [metadata](#m_metadata) as string.
@@ -217,7 +217,7 @@ Returns the [name](#name) and [metadata](#m_metadata) as string.
file.flat(); // returns "../path/to/pictures/picture.jpg[Key1=1,Key2=2]"
-### QString hash() const
+### [QString](http://doc.qt.io/qt-5/QString.html) hash() const
Returns a hash of the file.
@@ -227,7 +227,7 @@ Returns a hash of the file.
file.hash(); // returns "kElVwY"
-### QStringList localKeys() const
+### [QStringList](http://doc.qt.io/qt-5/qstringlist.html) localKeys() const
Returns an immutable version of the local metadata keys gotten by calling [metadata](#metadata).keys().
@@ -237,7 +237,7 @@ Returns an immutable version of the local metadata keys gotten by calling [metad
file.localKeys(); // returns [Key1, Key2]
-### QVariantMap localMetadata() const
+### [QVariantMap](http://doc.qt.io/qt-5/qvariant.html#QVariantMap-typedef) localMetadata() const
returns an immutable version of the local [metadata](#m_metadata).
@@ -247,7 +247,7 @@ returns an immutable version of the local [metadata](#m_metadata).
file.localMetadata(); // return QMap(("Key1", QVariant(float, 1)) ("Key2", QVariant(float, 2)))
-### void append(QVariantMap &localMetadata)
+### void append([QVariantMap](http://doc.qt.io/qt-5/qvariant.html#QVariantMap-typedef) &localMetadata)
Add new metadata fields to [metadata](#m_metadata).
@@ -277,7 +277,7 @@ Append another file using the **;** separator. The file names are combined with
f1.localKeys(); // returns "[Key1, Key2, Key3, separator]"
-### File &operator +=(const QMap<QString, QVariant> &other)
+### File &operator +=(const [QMap](http://doc.qt.io/qt-5/qmap.html)<[QString](http://doc.qt.io/qt-5/QString.html), [QVariant](http://doc.qt.io/qt-5/qvariant.html)> &other)
Shortcut operator to call [append](#void-appendqvariantmap-localmetadata).
@@ -285,7 +285,7 @@ Shortcut operator to call [append](#void-appendqvariantmap-localmetadata).
Shortcut operator to call [append](#void-appendconst-file-other).
-### QList<[File](#file)> split() const
+### [QList](http://doc.qt.io/qt-5/qlist.html)<[File](#file)> split() const
Parse [name](#name) and split on the **;** separator. Each split file has the same [metadata](#m_metadata) as the joined file.
@@ -302,7 +302,7 @@ Parse [name](#name) and split on the **;** separator. Each split file has the sa
f1.split(); // returns [../path/to/pictures/picture1.jpg[Key1=1, Key2=2, Key3=3, separator=;],
// ../path/to/pictures/picture2.jpg[Key1=1, Key2=2, Key3=3, separator=;]]
-### QList<[File](#file)> split(const QString &separator) const
+### [QList](http://doc.qt.io/qt-5/qlist.html)<[File](#file)> split(const [QString](http://doc.qt.io/qt-5/QString.html) &separator) const
Split the file on the given separator. Each split file has the same [metadata](#m_metadata) as the joined file.
@@ -313,7 +313,7 @@ Split the file on the given separator. Each split file has the same [metadata](#
f.split(","); // returns [../path/to/pictures/picture1.jpg[Key1=1, Key2=2],
../path/to/pictures/picture2.jpg[Key1=1, Key2=2]]
-### void setParameter(int index, const QVariant &value)
+### void setParameter(int index, const [QVariant](http://doc.qt.io/qt-5/qvariant.html) &value)
Insert a keyless value into the [metadata](#m_metadata).
@@ -397,39 +397,39 @@ Returns true if [name](#name) equals "Terminal".
Returns true if the file at [name](#name) exists on disk.
-### QString fileName() const
+### [QString](http://doc.qt.io/qt-5/QString.html) fileName() const
Returns the file's base name and extension.
File file("../path/to/pictures/picture.jpg");
file.fileName(); // returns "picture.jpg"
-### QString baseName() const
+### [QString](http://doc.qt.io/qt-5/QString.html) baseName() const
Returns the file's base name.
File file("../path/to/pictures/picture.jpg");
file.baseName(); // returns "picture"
-### QString suffix() const
+### [QString](http://doc.qt.io/qt-5/QString.html) suffix() const
Returns the file's extension.
File file("../path/to/pictures/picture.jpg");
file.suffix(); // returns "jpg"
-### QString path() const
+### [QString](http://doc.qt.io/qt-5/QString.html) path() const
Return's the path of the file, excluding the name.
File file("../path/to/pictures/picture.jpg");
file.suffix(); // returns "../path/to/pictures"
-### QString resolved() const
+### [QString](http://doc.qt.io/qt-5/QString.html) resolved() const
Returns [name](#name). If name does not exist it prepends name with the path in Globals->path.
-### bool contains(const QString &key) const
+### bool contains(const [QString](http://doc.qt.io/qt-5/QString.html) &key) const
Returns True if the key is in the [metadata](#m_metadata) and False otherwise.
@@ -439,7 +439,7 @@ Returns True if the key is in the [metadata](#m_metadata) and False otherwise.
file.contains("Key1"); // returns true
file.contains("Key2"); // returns false
-### bool contains(const QStringList &keys) const
+### bool contains(const [QStringList](http://doc.qt.io/qt-4.8/qstringlist.html) &keys) const
Returns True if all of the keys are in the [metadata](#m_metadata) and False otherwise.
@@ -451,7 +451,7 @@ Returns True if all of the keys are in the [metadata](#m_metadata) and False oth
file.contains(QStringList() << "Key1" << "Key2") // returns true
file.contains(QStringList() << "Key1" << "Key3"); // returns false
-### QVariant value(const QString &key) const
+### [QVariant](http://doc.qt.io/qt-5/qvariant.html) value(const [QString](http://doc.qt.io/qt-5/QString.html) &key) const
Returns the value associated with key in the [metadata](#m_metadata).
@@ -459,7 +459,7 @@ Returns the value associated with key in the [metadata](#m_metadata).
file.set("Key1", QVariant::fromValue(1));
file.value("Key1"); // returns QVariant(float, 1)
-### void set(const QString &key, const QVariant &value)
+### void set(const [QString](http://doc.qt.io/qt-5/QString.html) &key, const [QVariant](http://doc.qt.io/qt-5/qvariant.html) &value)
Insert or overwrite the [metadata](#m_metadata) key with the given value.
@@ -469,7 +469,7 @@ Insert or overwrite the [metadata](#m_metadata) key with the given value.
f.set("Key1", QVariant::fromValue(1));
f.flat(); // returns "[Key1=1]"
-### void set(const QString &key, const QString &value)
+### void set(const [QString](http://doc.qt.io/qt-5/QString.html) &key, const [QString](http://doc.qt.io/qt-5/QString.html) &value)
Insert or overwrite the [metadata](#m_metadata) key with the given value.
@@ -479,7 +479,7 @@ Insert or overwrite the [metadata](#m_metadata) key with the given value.
f.set("Key1", QString("1"));
f.flat(); // returns "[Key1=1]"
-### void setList(const QString &key, const QList &value)
+### void setList(const [QString](http://doc.qt.io/qt-5/QString.html) &key, const [QList](http://doc.qt.io/qt-5/qlist.html)<T> &value)
This function requires a type specification in place of T. Insert or overwrite the [metadata](#m_metadata) key with the value. The value will remain a list and should be queried with the function [getList](#qlistt-getlistconst-qstring-key-const).
@@ -489,7 +489,7 @@ This function requires a type specification in place of T. Insert or overwrite t
file.setList("List", list);
file.getList("List"); // return [1., 2. 3.]
-### void remove(const QString &key)
+### void remove(const [QString](http://doc.qt.io/qt-5/QString.html) &key)
Remove the key value pair associated with the given key from the [metadata](#metadata)
@@ -502,7 +502,7 @@ Remove the key value pair associated with the given key from the [metadata](#met
f.remove("Key1");
f.flat(); // returns "[Key2=2]"
-### T get(const QString &key)
+### T get(const [QString](http://doc.qt.io/qt-5/QString.html) &key)
This function requires a type specification in place of T. Try and get the value associated with the given key in the [metadata](#m_metadata). If the key does not exist or cannot be converted to the given type an error is thrown.
@@ -513,7 +513,7 @@ This function requires a type specification in place of T. Try and get the value
f.get("Key2"); // Error: Key2 is not in the metadata
f.get("Key1"); // Error: A float can't be converted to a QRectF
-### T get(const QString &key, const T &defaultValue)
+### T get(const [QString](http://doc.qt.io/qt-5/QString.html) &key, const T &defaultValue)
This function requires a type specification in place of T. Try and get the value associated with the given key in the [metadata](#m_metadata). If the key does not exist or cannot be converted to the given type the defaultValue is returned.
@@ -524,7 +524,7 @@ This function requires a type specification in place of T. Try and get the value
f.get("Key2", 5); // returns 5
f.get("Key1", QRectF(0, 0, 10, 10)); // returns QRectF(0, 0, 10x10)
-### bool getBool(const QString &key, bool defaultValue = false)
+### bool getBool(const [QString](http://doc.qt.io/qt-5/QString.html) &key, bool defaultValue = false)
This is a specialization of [get](#t-getconst-qstring-key) for the boolean type. If the key is not in the [metadata](#m_metadata) the defaultValue is returned. If the key is in the metadata but the value cannot be converted to a bool **true** is returned. If the key is found and the value can be converted to a bool the value is returned.
@@ -537,9 +537,9 @@ This is a specialization of [get](#t-getconst-qstring-key) for the boolean type.
f.getBool("Key3"); // returns false (default value)
f.getBool("Key3", true); // returns true (default value)
-### QList<T> getList(const QString &key) const
+### [QList](http://doc.qt.io/qt-5/QList.html)<T> getList(const [QString](http://doc.qt.io/qt-5/QString.html) &key) const
-This function requires a type specification in place of T. Similar to [get](#t-getconst-qstring-key) only this returns a list. If the key is not found or the value cannot be converted into a QList an error is thrown.
+This function requires a type specification in place of T. Similar to [get](#t-getconst-qstring-key) only this returns a list. If the key is not found or the value cannot be converted into a [QList](http://doc.qt.io/qt-5/QList.html)<T> an error is thrown.
File file;
@@ -550,9 +550,9 @@ This function requires a type specification in place of T. Similar to [get](#t-g
file.getList("List"); // Error: float cannot be converted to QRectF
file.getList("Key"); // Error: key doesn't exist
-### QList<T> getList(const QString &key, const QList<T> &defaultValue) const
+### [QList](http://doc.qt.io/qt-5/QList.html)<T> getList(const [QString](http://doc.qt.io/qt-5/QString.html) &key, const [QList](http://doc.qt.io/qt-5/QList.html)<T> &defaultValue) const
-This function requires a type specification in place of T. Similar to [get](#t-getconst-qstring-key-const-t-defaultvalue) only this returns a list. If the key is not found or the value cannot be converted into a QList<T> the supplied defaultValue is returned.
+This function requires a type specification in place of T. Similar to [get](#t-getconst-qstring-key-const-t-defaultvalue) only this returns a list. If the key is not found or the value cannot be converted into a [QList](http://doc.qt.io/qt-5/QList.html)<T> the supplied defaultValue is returned.
File file;
@@ -563,9 +563,9 @@ This function requires a type specification in place of T. Similar to [get](#t-g
file.getList("List", QList()); // return []
file.getList("Key", QList() << 1 << 2 << 3); // return [1., 2., 3.]
-### QList<QPointF> namedPoints() const
+### [QList](http://doc.qt.io/qt-5/QList.html)<[QPointF](http://doc.qt.io/qt-4.8/qpointf.html)> namedPoints() const
-Find all of the points that can be parsed from [metadata](#m_metadata) keys and return them. Only values that are convertable to QPointF are found. Values that can be converted to QList<QPointF> are not included.
+Find all of the points that can be parsed from [metadata](#m_metadata) keys and return them. Only values that are convertable to [QPointF](http://doc.qt.io/qt-4.8/qpointf.html) are found. Values that can be converted to [QList](http://doc.qt.io/qt-5/QList.html)><[QPointF](http://doc.qt.io/qt-4.8/qpointf.html)> are not included.
File file;
file.set("Key1", QVariant::fromValue(QPointF(1, 1)));
@@ -577,7 +577,7 @@ Find all of the points that can be parsed from [metadata](#m_metadata) keys and
file.setPoints(QList() << QPointF(3, 3)); // changes metadata["Points"] to QList
f.namedPoints(); // returns [QPointF(1, 1), QPointF(2, 2)]
-### QList<QPointF> points() const
+### [QList](http://doc.qt.io/qt-5/QList.html)<[QPointf](http://doc.qt.io/qt-4.8/qpointf.html)>> points() const
Returns the list of points stored in [metadata](#m_metadata)["Points"]. A list is expected and a single point not in a list will not be returned. Convenience functions [appendPoint](#void-appendpointconst-qpointf-point), [appendPoints](#void-appendpointsconst-qlistqpointf-points), [clearPoints](#void-clearpoints) and [setPoints](#void-setpointsconst-qlistqpointf-points) have been provided to manipulate the internal points list.
@@ -588,7 +588,7 @@ Returns the list of points stored in [metadata](#m_metadata)["Points"]. A list i
file.setPoints(QList() << QPointF(2, 2));
file.points(); // returns [QPointF(2, 2)]
-### void appendPoint(const QPointF &point)
+### void appendPoint(const [QPointF](http://doc.qt.io/qt-4.8/qpointf.html) &point)
Add a point to the file's points list stored in [metadata](#m_metadata)["Points"]
@@ -598,7 +598,7 @@ Add a point to the file's points list stored in [metadata](#m_metadata)["Points"
file.appendPoint(QPointF(1, 1));
file.points(); // returns [QPointF(1, 1)]
-### void appendPoints(const QList<QPointF> &points)
+### void appendPoints(const [QList](http://doc.qt.io/qt-5/QList.html)<[QPointF](http://doc.qt.io/qt-4.8/qpointf.html)> &points)
Add a list of points to the file's points list stored in [metadata](#m_metadata)["Points"]
@@ -619,7 +619,7 @@ Clear the list of points stored in [metadata](#m_metadata)["Points"].
file.clearPoints();
file.points(); // returns []
-### void setPoints(const QList<QPointF> &points)
+### void setPoints(const [QList](http://doc.qt.io/qt-5/QList.html)<[QPointF](http://doc.qt.io/qt-4.8/qpointf.html)> &points)
Clears the points stored in [metadata](#m_metadata) and replaces them with points.
@@ -630,9 +630,9 @@ Clears the points stored in [metadata](#m_metadata) and replaces them with point
file.setPoints(QList() << QPointF(3, 3) << QPointF(4, 4));
file.points(); // returns [QPointF(3, 3), QPointF(4, 4)]
-### QList<QRectF> namedRects() const
+### [QList](http://doc.qt.io/qt-5/QList.html)<[QRectF](http://doc.qt.io/qt-4.8/qrectf.html)> namedRects() const
-Find all of the rects that can be parsed from [metadata](#m_metadata) keys and return them. Only values that are convertable to QRectF are found. Values that can be converted to QList<QRectF> are not included.
+Find all of the rects that can be parsed from [metadata](#m_metadata) keys and return them. Only values that are convertable to [QRectF](http://doc.qt.io/qt-4.8/qrectf.html) are found. Values that can be converted to [QList](http://doc.qt.io/qt-5/QList.html)<[QRectF](http://doc.qt.io/qt-4.8/qrectf.html)> are not included.
File file;
file.set("Key1", QVariant::fromValue(QRectF(1, 1, 5, 5)));
@@ -644,7 +644,7 @@ Find all of the rects that can be parsed from [metadata](#m_metadata) keys and r
file.setRects(QList() << QRectF(3, 3, 5x5)); // changes metadata["Rects"] to QList
f.namedRects(); // returns [QRectF(1, 1, 5x5), QRectF(2, 2, 5x5)]
-### QList<QRectF> rects() const
+### [QList](http://doc.qt.io/qt-5/QList.html)<[QRectF](http://doc.qt.io/qt-4.8/qrectf.html)> rects() const
Returns the list of points stored in [metadata](#m_metadata)["Rects"]. A list is expected and a single rect not in a list will not be returned. Convenience functions [appendRect](#void-appendrectconst-qrectf-rect), [appendRects](#void-appendrectsconst-qlistqrectf-rects), [clearRects](#void-clearrects) and [setRects](#void-setrectsconst-qlistqrectf-rects) have been provided to manipulate the internal points list.
@@ -655,7 +655,7 @@ Returns the list of points stored in [metadata](#m_metadata)["Rects"]. A list is
file.setRects(QList() << QRectF(2, 2, 5, 5));
file.rects(); // returns [QRectF(2, 2, 5x5)]
-### void appendRect(const QRectF &rect)
+### void appendRect(const [QRectF](http://doc.qt.io/qt-4.8/qrectf.html) &rect)
Add a rect to the file's rects list stored in [metadata](#m_metadata)["Rects"].
@@ -665,7 +665,7 @@ Add a rect to the file's rects list stored in [metadata](#m_metadata)["Rects"].
file.appendRect(QRectF(1, 1, 5, 5));
file.rects(); // returns [QRectF(1, 1, 5x5)]
-### void appendRect(const Rect &rect)
+### void appendRect(const [Rect](http://docs.opencv.org/modules/core/doc/basic_structures.html#rect) &rect)
Add a OpenCV style rect to the file's rects list stored in [metadata](#m_metadata)["Rects"]. The rect is automatically converted to a QRectF.
@@ -675,7 +675,7 @@ Add a OpenCV style rect to the file's rects list stored in [metadata](#m_metadat
file.appendRect(cv::Rect(1, 1, 5, 5)); // automatically converted to QRectF
file.rects(); // returns [QRectF(1, 1, 5x5)]
-### void appendRects(const QList<QRectF> &rects)
+### void appendRects(const [QList](http://doc.qt.io/qt-5/QList.html)<[QRectF](http://doc.qt.io/qt-4.8/qrectf.html)> &rects)
Add a list of rects to the file's rects list stored in [metadata](#m_metadata)["Rects"]
@@ -685,7 +685,7 @@ Add a list of rects to the file's rects list stored in [metadata](#m_metadata)["
file.appendRects(QList() << QRectF(1, 1, 5, 5) << QRectF(2, 2, 5, 5));
file.rects(); // returns [QRectF(1, 1, 5x5), QRectF(2, 2, 5x5)]
-### void appendRects(const QList<Rect> &rects)
+### void appendRects(const [QList](http://doc.qt.io/qt-5/QList.html)<[Rect](http://docs.opencv.org/modules/core/doc/basic_structures.html#rect)> &rects)
Add a list of OpenCV style rects to the file's rects list stored in [metadata](#m_metadata)["Rects"]. Each rect is automatically converted to a QRectF.
@@ -707,7 +707,7 @@ Clear the list of rects stored in [metadata](#m_metadata)["Rects"].
file.clearRects();
file.rects(); // returns []
-### void setRects(const QList<QRectF> &rects)
+### void setRects(const [QList](http://doc.qt.io/qt-5/QList.html)<[QRectF](http://doc.qt.io/qt-4.8/qrectf.html)> &rects)
Clears the rects stored in [metadata](#m_metadata)["Rects"] and replaces them with the given rects.
@@ -718,7 +718,7 @@ Clears the rects stored in [metadata](#m_metadata)["Rects"] and replaces them wi
file.setRects(QList() << QRectF(3, 3, 5, 5) << QRectF(4, 4, 5, 5));
file.rects(); // returns [QRectF(3, 3, 5x5), QRectF(4, 4, 5x5)]
-### void setRects(const QList<Rect> &rects)
+### void setRects(const [QList](http://doc.qt.io/qt-5/QList.html)<[Rect](http://docs.opencv.org/modules/core/doc/basic_structures.html#rect)> &rects)
Clears the rects stored in [metadata](#m_metadata)["Rects"] and replaces them with the given OpenCV style rects.
@@ -745,11 +745,11 @@ Default constructor. Doesn't do anything
Initialize the [FileList](#filelist) with n empty files
-### FileList(const QStringList &files)
+### FileList(const [QStringList](http://doc.qt.io/qt-4.8/qstringlist.html) &files)
Initialize the [FileList](#filelist) from a list of strings. Each string should have the format "filename[key1=value1, key2=value2, ... keyN=valueN]"
-### FileList(const QList<[File](#file)> &files)
+### FileList(const [QList](http://doc.qt.io/qt-4.8/qlist.html)<[File](#file)> &files)
Initialize the [FileList](#filelist) from a list of [files](#file).
@@ -767,9 +767,9 @@ Creates a [FileList](#filelist) from a [Gallery](#gallery). Galleries store one
## Functions
-### QStringList flat() const
+### [QStringList](http://doc.qt.io/qt-4.8/qstringlist.html) flat() const
-Calls [flat](#qstring-flat-const) on every [File](#file) in the list and returns the resulting strings as a QStringList.
+Calls [flat](#qstring-flat-const) on every [File](#file) in the list and returns the resulting strings as a [QStringList](http://doc.qt.io/qt-4.8/qstringlist.html).
File f1("picture1.jpg"), f2("picture2.jpg");
f1.set("Key", QString("Value"));
@@ -777,9 +777,9 @@ Calls [flat](#qstring-flat-const) on every [File](#file) in the list and returns
FileList fList(QList() << f1 << f2);
fList.flat(); // returns ["picture1.jpg[Key=Value]", "picture2.jpg"]
-### QStringList names() const
+### [QStringList](http://doc.qt.io/qt-4.8/qstringlist.html) names() const
-Stores the name of every [file](#file) in the list and returns the resulting strings as a QStringList.
+Stores the name of every [file](#file) in the list and returns the resulting strings as a [QStringList](http://doc.qt.io/qt-4.8/qstringlist.html).
File f1("picture1.jpg"), f2("picture2.jpg");
f1.set("Key", QString("Value"));
@@ -787,7 +787,7 @@ Stores the name of every [file](#file) in the list and returns the resulting str
FileList fList(QList() << f1 << f2);
fList.names(); // returns ["picture1.jpg", "picture2.jpg"]
-### void sort(const QString &key)
+### void sort(const [QString](http://doc.qt.io/qt-4.8/qstring.html) &key)
Sorts the [FileList](#filelist) based on the value associated with the given key in each file.
diff --git a/docs/docs/index.md b/docs/docs/index.md
index 60ce2fd..910d3e0 100644
--- a/docs/docs/index.md
+++ b/docs/docs/index.md
@@ -34,22 +34,23 @@ OpenBR is supported on multiple operating systems. Please select yours from the
We have created a few tutorials to help teach you the basic principles of the OpenBR system. If this is your first time using OpenBR you should look at these before moving on to the more technical descriptions below.
-* [OpenBR in 10 minutes or less!](tutorials.md#openbr in 10 minutes or less!)
-* [Face Recognition](tutorials.md#face recognition)
-* [Age Estimation](tutorials.md#age estimation)
-* [Gender Estimation](tutorials.md#gender estimation)
+* [Quick Start](tutorials.md#quick-start)
+* [Training in OpenBR](tutorials.md#training-in-openbr)
+* [Face Recognition](tutorials.md#face-recognition)
+* [Age Estimation](tutorials.md#age-estimation)
+* [Gender Estimation](tutorials.md#gender-estimation)
---
## Additional Materials
-OpenBR has several parts. For a brief overview of the entire framework please see [OpenBR in 10 minutes or less!](tutorials.md#openbr in 10 minutes or less!). Below are several more technical descriptions of important parts of the system. Enjoy!
+OpenBR has several parts. Below are several more technical descriptions of important parts of the system. Enjoy!
-* [Algorithms in OpenBR](technical.md#algorithms in openbr)
-* [The Command Line Interface](technical.md#the command line interface)
-* [The C API](technical.md#the c api)
-* [The C++ Plugin API](technical.md#the c++ plugin api)
-* [The Evaluation Harness](technical.md#the evaluation harness)
+* [Algorithms in OpenBR](technical.md#algorithms-in-openbr)
+* [The C API](docs/c_api.md)
+* [The Command Line Interface](docs/cl_api.md)
+* [The C++ Plugin API](docs/cpp_api.md)
+* [The Evaluation Harness](technical.md#the-evaluation-harness)
---
diff --git a/docs/docs/technical.md b/docs/docs/technical.md
index a7ccdc7..ee27277 100644
--- a/docs/docs/technical.md
+++ b/docs/docs/technical.md
@@ -74,3 +74,9 @@ If you are familiar with face recognition, you will likely recognize this as the
As a final note, the Eigenfaces algorithms uses the Euclidean distance (or L2-norm) to compare templates.
Since OpenBR expects *similarity* values when comparing templates, and not *distances*, the [DistDistance](docs/plugins/distance.md#distdistance) will return *-log(distance+1)* so that larger values indicate more similarity.
+
+---
+
+# The Evaluation Harness
+
+---
diff --git a/docs/docs/tutorials.md b/docs/docs/tutorials.md
index 920f55f..a6a254a 100644
--- a/docs/docs/tutorials.md
+++ b/docs/docs/tutorials.md
@@ -3,33 +3,51 @@ Welcome to OpenBR! Here we have a series of tutorials designed to get you up to
---
-# OpenBR in 10 minutes or less!
+# Quick Start
This tutorial is meant to familiarize you with the ideas, objects and motivations behind OpenBR using some fun examples. **Note:** parts of this tutorial require a webcam.
-OpenBR is a C++ library built on top of QT and OpenCV. It can either be used from the command line using the **br** application, or from interfacing with the [C API](#c-api). The command line is the easiest and fastest way to get started and this tutorial will use it for all of the examples.
+OpenBR is a C++ library built on top of QT and OpenCV. It can either be used from the command line using the **br** application, or from interfacing with the [C API](docs/c_api.md). The command line is the easiest and fastest way to get started and this tutorial will use it for all of the examples.
-First, make sure that OpenBR has been installed on your system using the steps described in the [installation section](#install.md). Then open up your terminal or command prompt and enter:
+First, make sure that OpenBR has been installed on your system using the steps described in the [installation section](install.md). Then open up your terminal or command prompt and enter:
- $ br -gui -algorithm "Open+Show(false)" -enroll 0.webcam
+ $ br -gui -algorithm "Show(false)" -enroll 0.webcam
-If everything goes well your webcam should have opened up and is streaming. Look you are using OpenBR! Let's talk about what's happening in this command. OpenBR expects flags to be prepended by a *-* and arguments to follow the flags and be separated by spaces. Flags normally require a specific number of flags. All of the possible flags and their values are [documented here](#docs/cl_api.md). Let's step through the individual arguments and values. **-gui** is the flag that tells OpenBR to open up a GUI window. Take a look at the [GUI plugins](#docs/plugins/gui.md) for other plugins that require the **-gui** flag. **-algorithm** is one of the most important flags in OpenBR. It expects one argument called the *algorithm string*. This string determines the pipeline that images and metadata propagate through. Finally, **-enroll** reads files from disk and *enrolls* them into the image pipeline. It takes one input argument (0.webcam in our example) and an optional output argument. OpenBR has a range of formats that can be enrolled into algorithms, some examples include .jpg, .png, .csv, and .xml. .webcam tells OpenBR to enroll frames from the computers webcam.
+If everything goes well your webcam should have opened up and is streaming. Look you are using OpenBR! Let's talk about what's happening in this command. OpenBR expects flags to be prepended by a *-* and arguments to follow the flags and be separated by spaces. Flags normally require a specific number of flags. All of the possible flags and their values are [documented here](docs/cl_api.md). Let's step through the individual arguments and values. **-gui** is the flag that tells OpenBR to open up a GUI window. Take a look at the [GUI plugins](docs/plugins/gui.md) for other plugins that require the **-gui** flag. **-algorithm** is one of the most important flags in OpenBR. It expects one argument called the *algorithm string*. This string determines the pipeline that images and metadata propagate through. Finally, **-enroll** reads files from disk and *enrolls* them into the image pipeline. It takes one input argument (0.webcam in our example) and an optional output argument. OpenBR has a range of formats that can be enrolled into algorithms, some examples include .jpg, .png, .csv, and .xml. .webcam tells OpenBR to enroll frames from the computers webcam.
-Let's try a slightly more complicated example, after all OpenBR can do way more then just open webcams! Face detection is normally the first step in a [face recognition](#face recognition) algorithm. Let's do face detection in OpenBR. Open up the terminal again and enter:
+Let's try a slightly more complicated example, after all OpenBR can do way more then just open webcams! Fire up the terminal again and enter:
- $ br -gui -algorithm "Open+Cvt(Gray)+Cascade(FrontalFace)+Draw+Show(false)" -enroll 0.webcam
+ $ br -gui -algorithm "Cvt(Gray)+Show(false)" -enroll 0.webcam
+Hey what happened? We took our normal BGR (OpenCV's alternative to RGB) image and converted it to a grayscale image. How did we do that? Simple, by adding "Cvt(Gray)" to the algorithm string. [Cvt](docs/plugins/imgproc.md#cvttransform), short for convert, is an example of an OpenBR *plugin*. [Show](docs/plugins/gui.md#showtransform) is a plugin as well. Every algorithm string in OpenBR is just a series of plugins joined together into a pipeline. In fact the **+** symbol is shorthand for a [Pipe](docs/plugins/core.md#pipetransform), another kind of OpenBR plugin. We specify **Gray** to [Cvt](docs/plugins/imgproc.md#cvttransform) as a runtime parameter to tell the plugin which color space to convert the image to. We also could have written **Cvt(HSV)** if we wanted to convert to the HSV color space or **Cvt(Luv)** if we wanted to convert to Luv. The arguments inside of the plugins are runtime parameters that can adjust the functionality. They can be provided as key-value pairs, **Cvt(Gray)** is equivalent to **Cvt(ColorSpace=Gray)**, or as keyless values. Make sure you are supplying parameters in the proper order if you are not using keys! Try and run the code with **Show(true)** and see how changing the parameters effect the output of the command (**Hint:** hit a key to cycle through the images).
-It was built primarily as a platform for [face recognition](#face recognition) but has grown to do other things like [age recognition](#age recognition) and [gender recognition](#gender recognition). The different functionalities of OpenBR are specified by algorithms which are passed in as strings. The algorithm to do face recognition is
+Let's make this example a little bit more exciting and relevant to OpenBR's biometric roots. Face detection is normally the first step in a [face recognition](#face-recognition) algorithm. Let's do face detection in OpenBR. Back in the terminal enter:
- $ Open+Cvt(Gray)+Cascade(FrontalFace)+ASEFEyes+Affine(88,88,0.25,0.35)++++SetMetadata(AlgorithmID,-1):Unit(ByteL1)
+ $ br -gui -algorithm "Cvt(Gray)+Cascade(FrontalFace)+Draw(lineThickness=3)+Show(false)" -enroll 0.webcam
-Woah, that's a lot! Face recognition is a pretty complicated process! We will break this whole string down in just a second, but first we can showcase one of the founding principles of OpenBR. In the face recognition algorithm there are a series of steps separated by +'s (and a few other symbols but they will all be explained); these steps are called plugins and they are the building blocks of all OpenBR algorithms. Each plugin is completely independent of all of the other plugins around it and each one can be swapped, inserted or removed at any time to form new algorithms. This makes it really easy to test new ideas as you come up with them!
+You're webcam should be open again but this time a box should have appeared around your face! We added two new plugins to our string, [Cascade](docs/plugins/metadata.md#cascadetransform) and [Draw](docs/plugins/gui.md#drawtransform). Let's walk through this plugin by plugin and see how it works:
-So, now lets talk about the basics of algorithms in OpenBR. We know that algorithms are just a series of plugins joined together using the + symbol. What about the : symbol right at the end of the algorithm however? :'s separate the processing part of the algorithm (also called enrollment or generation), from the evaluation part. OpenBR actually has different types of plugins to handle each part. Plugins to the left are called [transforms](docs/cpp_api.md#transform) and plugins to the right are called [distances](docs/cpp_api.md#distance). Transforms operate on the images as they pass through the algorithm and distances compare (or find the distance between) the images as they finish, usually constructing a similarity matrix in the process.
+1. [Cvt(Gray)](docs/plugins/imgproc.md#cvttransform): Convert the image from BGR to grayscale. Grayscale is required for [Cascade](docs/plugins/metadata.md#cascadetransform) to work properly.
+2. [Cascade(FrontalFace)](docs/plugins/metadata.md#cascadetransform): This is a wrapper on the OpenCV [Cascade Classification](http://docs.opencv.org/modules/objdetect/doc/cascade_classification.html) framework. It detects frontal faces using the **FrontalFace** model.
+3. [Draw(lineThickness=3)](docs/plugins/gui.md#drawtransform): Take the rects detected by [Cascade](docs/plugins/metadata.md#cascadetransform) and draw them onto the frame from the webcam. **lineThickness** determines the thickness of the drawn rect.
+4. [Show(false)](docs/plugins/gui.md#showtransform): Show the image in a GUI window. **false** indicates the images should be shown in succession without waiting for a key press.
-This leads us on a small tangent to discuss how images are handled in OpenBR. OpenBR has two structures dedicated to handling data as it passes through an algorithm, [Files](docs/cpp_api.md#file) and [Templates](docs/cpp_api.md#template). Files handle metadata, the text and other information that can be associated with an image, and templates act as a container for images (we use OpenCV mats) and files. These templates are passed from transform to transform through the algorithm and are *transformed* (see, the name makes sense!) as they go.
+Pretty straightforward right? Each plugin completes one task and the passes the output on to the next plugin. You can pipe together as many plugins as you like as long as the output data from one can be the input data to the next. But wait! Output data? Input data? we haven't talked about data at all yet! How does OpenBR handle data? There are two objects that handle data is OpenBR; [Files](docs/cpp_api.md#file), which handle metadata, and [Templates](docs/cpp_api.md#template) which are containers for images and [Files](docs/cpp_api.md#file). Let's talk about [Files](docs/cpp_api.md#file) first. A file consists of file name, which is a path to a file on disk, and metadata which is a map of key-value pairs. The metadata can contain any textual information about the file. In the example above we use it to store the rectangles detected by [Cascade](docs/plugins/metadata.md#cascadetransform) and pass them along to [Draw](docs/plugins/metadata.md#drawtransform) for drawing. [Templates](docs/cpp_api.md#template) are containers for images, given as OpenCV [Mats](http://docs.opencv.org/modules/core/doc/basic_structures.html#mat), and [Files](docs/cpp_api.md#file). They can contain one image or a list of images. Plugins are either [Template](#docs/cpp_api.md#template) in, [Template](docs/cpp_api.md#template) out or [TemplateList](docs/cpp_api.md#templatelist) in, [TemplateList](docs/cpp_api.md#templatelist) out. [TemplateLists](docs/cpp_api.md#templatelist) are, of course, just a list of [Templates](docs/cpp_api.md#template) which a few functions added for your convenience.
-Great, you now know how data is handled in OpenBR but we still have a lot to cover in that algorithm string! Next lets talk about all of the parentheses next to each plugin. Many plugins have parameters that can be set at runtime. For example, [Cvt](docs/plugins/imgproc.md#cvttransform) (short for convert) changes the colorspace of an image. For face recognition we want to change it to gray so we pass in Gray as the parameter to Cvt. Pretty simple right? Parameters can either be passed in in the order they appear in the code, or they can use a key-value pairing. Cvt(Gray) is equivalent to Cvt(ColorSpace=Gray), check out the docs for the properties of each plugin.
+And there you go! You have gotten your quick start in OpenBR. We covered the [command line](docs/cl_api.md), plugins, and the key [data structures](docs/cpp_api.md) in OpenBR. If you want to learn more the next few tutorials will cover these fields with more depth. For even more information check out the technical overviews (#techical.md) and class documentation!
-The last symbol we need to cover is <>. In OpenBR <> represents i/o. Transforms within these brackets will try and load their parameters from the hard drive if they can (they also still take parameters from the command line as you can see). Plugin i/o won't be covered here because it isn't critically important to making OpenBR work for you out of the gate. Stay tuned for a later tutorial on this.
+---
+
+# Training in OpenBR
+
+---
+
+# Face Recognition
+
+---
+
+# Age Estimation
+
+---
+
+# Gender Estimation