Commit aa5961835a36c6a9c38dbf1a83ef67bb958ffd33
1 parent
87f7a91f
Fixed file.flat() and file.init() to work with points and rects. other minor bug fixes
Showing
8 changed files
with
139 additions
and
34 deletions
openbr/openbr_plugin.cpp
| ... | ... | @@ -43,6 +43,9 @@ using namespace br; |
| 43 | 43 | using namespace cv; |
| 44 | 44 | |
| 45 | 45 | /* File - public methods */ |
| 46 | +// Note that the convention for displaying metadata is as follows: | |
| 47 | +// [] for lists in which argument order does not matter (e.g. [FTO=false, Index=0]), | |
| 48 | +// () for lists in which argument order matters (e.g. First_Eye(100.0,100.0)). | |
| 46 | 49 | QString File::flat() const |
| 47 | 50 | { |
| 48 | 51 | QStringList values; |
| ... | ... | @@ -51,18 +54,14 @@ QString File::flat() const |
| 51 | 54 | const QVariant value = this->value(key); |
| 52 | 55 | if (value.isNull()) values.append(key); |
| 53 | 56 | else { |
| 54 | - if (value.canConvert(QVariant::String)) { | |
| 55 | - values.append(key + "=" + value.toString()); | |
| 56 | - } | |
| 57 | - else { | |
| 58 | - if (value.canConvert(QVariant::PointF)) values.append(key + "=" + QString("(%1,%2)").arg(QString::number(qvariant_cast<QPointF>(value).x()), | |
| 59 | - QString::number(qvariant_cast<QPointF>(value).y()))); | |
| 60 | - else if (value.canConvert(QVariant::RectF)) values.append(key + "=" + QString("(%1,%2,%3,%4)").arg(QString::number(qvariant_cast<QRectF>(value).x()), | |
| 61 | - QString::number(qvariant_cast<QRectF>(value).y()), | |
| 62 | - QString::number(qvariant_cast<QRectF>(value).width()), | |
| 63 | - QString::number(qvariant_cast<QRectF>(value).height()))); | |
| 64 | - else values.append(key + "="); | |
| 57 | + if (QString(value.typeName()) == "QVariantList") { | |
| 58 | + QStringList landmarks; | |
| 59 | + foreach(const QVariant &landmark, qvariant_cast<QVariantList>(value)) { | |
| 60 | + landmarks.append(toString(landmark)); | |
| 61 | + } | |
| 62 | + if (!landmarks.isEmpty()) values.append(key + "=[" + landmarks.join(", ") + "]"); | |
| 65 | 63 | } |
| 64 | + else values.append(key + "=" + toString(value)); | |
| 66 | 65 | } |
| 67 | 66 | } |
| 68 | 67 | |
| ... | ... | @@ -266,26 +265,49 @@ void File::init(const QString &file) |
| 266 | 265 | if (unnamed) setParameter(i, words[0]); |
| 267 | 266 | else set(words[0], QVariant()); |
| 268 | 267 | } else { |
| 269 | - if (words[1][0] == '(') { | |
| 270 | - QStringList values = words[1].split(','); | |
| 271 | - if (values.size() == 2) /* QPointF */ { | |
| 272 | - values[1].chop(1); | |
| 273 | - QPointF point(values[0].mid(1).toFloat(), values[1].remove(')').toFloat()); | |
| 274 | - set(words[0], point); | |
| 275 | - } | |
| 276 | - else /* QRectF */ { | |
| 277 | - values[3].chop(1); | |
| 278 | - QRectF rect(values[0].mid(1).toFloat(), values[1].toFloat(), values[2].toFloat(), values[3].remove(')').toFloat()); | |
| 279 | - set(words[0], rect); | |
| 280 | - } | |
| 281 | - } | |
| 282 | - else set(words[0], words[1]); | |
| 268 | + fromString(words[0],words[1]); | |
| 283 | 269 | } |
| 284 | 270 | } |
| 285 | 271 | name = name.left(index); |
| 286 | 272 | } |
| 287 | 273 | } |
| 288 | 274 | |
| 275 | +QString File::toString(const QVariant &variant) const | |
| 276 | +{ | |
| 277 | + if (variant.canConvert(QVariant::String)) return variant.toString(); | |
| 278 | + else if(variant.canConvert(QVariant::PointF)) return QString("(%1,%2)").arg(QString::number(qvariant_cast<QPointF>(variant).x()), | |
| 279 | + QString::number(qvariant_cast<QPointF>(variant).y())); | |
| 280 | + else if (variant.canConvert(QVariant::RectF)) return QString("(%1,%2,%3,%4)").arg(QString::number(qvariant_cast<QRectF>(variant).x()), | |
| 281 | + QString::number(qvariant_cast<QRectF>(variant).y()), | |
| 282 | + QString::number(qvariant_cast<QRectF>(variant).width()), | |
| 283 | + QString::number(qvariant_cast<QRectF>(variant).height())); | |
| 284 | + return QString(); | |
| 285 | +} | |
| 286 | + | |
| 287 | +void File::fromString(const QString &key, const QString &value) | |
| 288 | +{ | |
| 289 | + if (value[0] == '[') /* QVariantList */ { | |
| 290 | + QStringList values = value.mid(1, value.size()-2).split(", "); | |
| 291 | + foreach(const QString &word, values) fromString(key, word); | |
| 292 | + } | |
| 293 | + else if (value[0] == '(') { | |
| 294 | + QStringList values = value.split(','); | |
| 295 | + if (values.size() == 2) /* QPointF */ { | |
| 296 | + values[1].chop(1); | |
| 297 | + QPointF point(values[0].mid(1).toFloat(), values[1].toFloat()); | |
| 298 | + if (key != "Points") set(key, point); | |
| 299 | + else appendPoint(point); | |
| 300 | + } | |
| 301 | + else /* QRectF */ { | |
| 302 | + values[3].chop(1); | |
| 303 | + QRectF rect(values[0].mid(1).toFloat(), values[1].toFloat(), values[2].toFloat(), values[3].toFloat()); | |
| 304 | + if (key != "Rects") set(key, rect); | |
| 305 | + else appendRect(rect); | |
| 306 | + } | |
| 307 | + } | |
| 308 | + else set(key, value); | |
| 309 | +} | |
| 310 | + | |
| 289 | 311 | /* File - global methods */ |
| 290 | 312 | QDebug br::operator<<(QDebug dbg, const File &file) |
| 291 | 313 | { | ... | ... |
openbr/openbr_plugin.h
| ... | ... | @@ -245,6 +245,8 @@ private: |
| 245 | 245 | BR_EXPORT friend QDataStream &operator>>(QDataStream &stream, File &file); |
| 246 | 246 | |
| 247 | 247 | void init(const QString &file); |
| 248 | + QString toString(const QVariant &variant) const; | |
| 249 | + void fromString(const QString &key, const QString &value); | |
| 248 | 250 | }; |
| 249 | 251 | |
| 250 | 252 | BR_EXPORT QDebug operator<<(QDebug dbg, const File &file); /*!< \brief Prints br::File::flat() to \c stderr. */ | ... | ... |
openbr/plugins/distance.cpp
| ... | ... | @@ -177,6 +177,37 @@ class PipeDistance : public Distance |
| 177 | 177 | |
| 178 | 178 | BR_REGISTER(Distance, PipeDistance) |
| 179 | 179 | |
| 180 | +class AverageDistance : public Distance | |
| 181 | +{ | |
| 182 | + Q_OBJECT | |
| 183 | + Q_PROPERTY(br::Distance* distance READ get_distance WRITE set_distance RESET reset_distance STORED false) | |
| 184 | + BR_PROPERTY(br::Distance*, distance, make("Dist(L2)")) | |
| 185 | + | |
| 186 | + void train(const TemplateList &src) | |
| 187 | + { | |
| 188 | + distance->train(src); | |
| 189 | + } | |
| 190 | + | |
| 191 | + float compare(const Template &a, const Template &b) const | |
| 192 | + { | |
| 193 | + if (a.size() != b.size()) | |
| 194 | + qDebug() << a.size() << " " << b.size(); | |
| 195 | + | |
| 196 | + float score = 0; | |
| 197 | + | |
| 198 | + for (int i = 0; i < a.size(); i++) { | |
| 199 | + //Template | |
| 200 | + score += distance->compare(a[i],b[i]); | |
| 201 | + } | |
| 202 | + | |
| 203 | + qDebug() << score; | |
| 204 | + | |
| 205 | + return score; | |
| 206 | + } | |
| 207 | +}; | |
| 208 | + | |
| 209 | +BR_REGISTER(Distance, AverageDistance) | |
| 210 | + | |
| 180 | 211 | /*! |
| 181 | 212 | * \ingroup distances |
| 182 | 213 | * \brief Fast 8-bit L1 distance | ... | ... |
openbr/plugins/gallery.cpp
| ... | ... | @@ -302,6 +302,8 @@ class memGallery : public Gallery |
| 302 | 302 | |
| 303 | 303 | static void align(TemplateList &templates) |
| 304 | 304 | { |
| 305 | + //if (templates[0].size() > 1) return; | |
| 306 | + | |
| 305 | 307 | bool uniform = true; |
| 306 | 308 | QVector<uchar> alignedData(templates.bytes<size_t>()); |
| 307 | 309 | size_t offset = 0; | ... | ... |
openbr/plugins/misc.cpp
| ... | ... | @@ -322,6 +322,54 @@ BR_REGISTER(Transform, RenameFirstTransform) |
| 322 | 322 | |
| 323 | 323 | /*! |
| 324 | 324 | * \ingroup transforms |
| 325 | + * \brief Name a point | |
| 326 | + * \author Scott Klum \cite sklum | |
| 327 | + */ | |
| 328 | +class LabelTransform : public UntrainableMetaTransform | |
| 329 | +{ | |
| 330 | + Q_OBJECT | |
| 331 | + Q_PROPERTY(QList<int> points READ get_points WRITE set_points RESET reset_points STORED false) | |
| 332 | + Q_PROPERTY(QStringList names READ get_names WRITE set_names RESET reset_names STORED false) | |
| 333 | + BR_PROPERTY(QList<int>, points, QList<int>()) | |
| 334 | + BR_PROPERTY(QStringList, names, QStringList()) | |
| 335 | + | |
| 336 | + void project(const Template &src, Template &dst) const | |
| 337 | + { | |
| 338 | + if (points.size() != names.size()) qFatal("Point/name size mismatch"); | |
| 339 | + | |
| 340 | + dst = src; | |
| 341 | + | |
| 342 | + for (int i=0; i<points.size(); i++) | |
| 343 | + dst.file.set(names[i], points[i]); | |
| 344 | + } | |
| 345 | +}; | |
| 346 | + | |
| 347 | +BR_REGISTER(Transform, LabelTransform) | |
| 348 | + | |
| 349 | +/*! | |
| 350 | + * \ingroup transforms | |
| 351 | + * \brief Name a point | |
| 352 | + * \author Scott Klum \cite sklum | |
| 353 | + */ | |
| 354 | +class AnonymizeTransform : public UntrainableMetaTransform | |
| 355 | +{ | |
| 356 | + Q_OBJECT | |
| 357 | + Q_PROPERTY(QStringList names READ get_names WRITE set_names RESET reset_names STORED false) | |
| 358 | + BR_PROPERTY(QStringList, names, QStringList()) | |
| 359 | + | |
| 360 | + void project(const Template &src, Template &dst) const | |
| 361 | + { | |
| 362 | + dst = src; | |
| 363 | + | |
| 364 | + foreach (const QString &name, names) | |
| 365 | + if (src.file.contains(name)) dst.file.appendPoint(src.file.get<QPointF>(name)); | |
| 366 | + } | |
| 367 | +}; | |
| 368 | + | |
| 369 | +BR_REGISTER(Transform, AnonymizeTransform) | |
| 370 | + | |
| 371 | +/*! | |
| 372 | + * \ingroup transforms | |
| 325 | 373 | * \brief Change the br::Template::file extension |
| 326 | 374 | * \author Josh Klontz \cite jklontz |
| 327 | 375 | */ | ... | ... |
openbr/plugins/pp5.cpp
openbr/plugins/regions.cpp
| ... | ... | @@ -157,7 +157,7 @@ BR_REGISTER(Transform, DupTransform) |
| 157 | 157 | * \todo Padding should be a percent of total image size |
| 158 | 158 | */ |
| 159 | 159 | |
| 160 | -class RectFromLandmarksTransform : public UntrainableTransform | |
| 160 | +class RectFromPointsTransform : public UntrainableTransform | |
| 161 | 161 | { |
| 162 | 162 | Q_OBJECT |
| 163 | 163 | Q_PROPERTY(QList<int> indices READ get_indices WRITE set_indices RESET reset_indices STORED false) |
| ... | ... | @@ -181,7 +181,7 @@ class RectFromLandmarksTransform : public UntrainableTransform |
| 181 | 181 | maxX = maxY = -std::numeric_limits<int>::max(); |
| 182 | 182 | |
| 183 | 183 | foreach(int index, indices) { |
| 184 | - if (src.file.points().size() > index+1) { | |
| 184 | + if (src.file.points().size() > index) { | |
| 185 | 185 | if (src.file.points()[index].x() < minX) minX = src.file.points()[index].x(); |
| 186 | 186 | if (src.file.points()[index].x() > maxX) maxX = src.file.points()[index].x(); |
| 187 | 187 | if (src.file.points()[index].y() < minY) minY = src.file.points()[index].y(); |
| ... | ... | @@ -203,7 +203,7 @@ class RectFromLandmarksTransform : public UntrainableTransform |
| 203 | 203 | } |
| 204 | 204 | }; |
| 205 | 205 | |
| 206 | -BR_REGISTER(Transform, RectFromLandmarksTransform) | |
| 206 | +BR_REGISTER(Transform, RectFromPointsTransform) | |
| 207 | 207 | |
| 208 | 208 | } // namespace br |
| 209 | 209 | ... | ... |
openbr/plugins/stasm.cpp
| ... | ... | @@ -18,11 +18,11 @@ class StasmInitializer : public Initializer |
| 18 | 18 | |
| 19 | 19 | void initialize() const |
| 20 | 20 | { |
| 21 | - Globals->abbreviations.insert("RectFromStasmEyes","RectFromLandmarks([27, 28, 29, 30, 31, 32, 33, 34, 35, 36],0.125,6.0)+Resize(44,164)"); // | |
| 22 | - Globals->abbreviations.insert("RectFromStasmJaw","RectFromLandmarks([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14],10)"); | |
| 23 | - Globals->abbreviations.insert("RectFromStasmBrow","RectFromLandmarks([15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26],0.25,6.5)+Resize(44,230)"); | |
| 24 | - Globals->abbreviations.insert("RectFromStasmNose","RectFromLandmarks([38, 39, 40, 41, 42, 43, 44, 67],0.1,1.5)+Resize(44,44)"); | |
| 25 | - Globals->abbreviations.insert("RectFromStasmMouth","RectFromLandmarks([48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66],0.3,3.0)+Resize(44,110)"); | |
| 21 | + Globals->abbreviations.insert("RectFromStasmEyes","RectFromPoints([27, 28, 29, 30, 31, 32, 33, 34, 35, 36],0.125,6.0)+Resize(44,164)"); // | |
| 22 | + Globals->abbreviations.insert("RectFromStasmJaw","RectFromPoints([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14],10)"); | |
| 23 | + Globals->abbreviations.insert("RectFromStasmBrow","RectFromPoints([15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26],0.25,6.5)+Resize(44,230)"); | |
| 24 | + Globals->abbreviations.insert("RectFromStasmNose","RectFromPoints([38, 39, 40, 41, 42, 43, 44, 67],0.1,1.5)+Resize(44,44)"); | |
| 25 | + Globals->abbreviations.insert("RectFromStasmMouth","RectFromPoints([48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66],0.3,3.0)+Resize(44,110)"); | |
| 26 | 26 | } |
| 27 | 27 | }; |
| 28 | 28 | ... | ... |