Commit 37f46fbf401996f9bc827878786cccbf292bf807
Looks like caotto beat me to it
Showing
9 changed files
with
213 additions
and
80 deletions
openbr/openbr_plugin.cpp
| @@ -476,13 +476,18 @@ TemplateList TemplateList::fromGallery(const br::File &gallery) | @@ -476,13 +476,18 @@ TemplateList TemplateList::fromGallery(const br::File &gallery) | ||
| 476 | 476 | ||
| 477 | // indexes some property, assigns an integer id to each unique value of propName | 477 | // indexes some property, assigns an integer id to each unique value of propName |
| 478 | // stores the index values in "Label" of the output template list | 478 | // stores the index values in "Label" of the output template list |
| 479 | -TemplateList TemplateList::relabel(const TemplateList &tl, const QString & propName) | 479 | +TemplateList TemplateList::relabel(const TemplateList &tl, const QString &propName, bool preserveIntegers) |
| 480 | { | 480 | { |
| 481 | const QList<QString> originalLabels = File::get<QString>(tl, propName); | 481 | const QList<QString> originalLabels = File::get<QString>(tl, propName); |
| 482 | QHash<QString,int> labelTable; | 482 | QHash<QString,int> labelTable; |
| 483 | - foreach (const QString & label, originalLabels) | ||
| 484 | - if (!labelTable.contains(label)) | ||
| 485 | - labelTable.insert(label, labelTable.size()); | 483 | + foreach (const QString &label, originalLabels) |
| 484 | + if (!labelTable.contains(label)) { | ||
| 485 | + int value; bool ok; | ||
| 486 | + value = label.toInt(&ok); | ||
| 487 | + // If the label is already an integer value we don't want to change it. | ||
| 488 | + if (ok && preserveIntegers) labelTable.insert(label, value); | ||
| 489 | + else labelTable.insert(label, labelTable.size()); | ||
| 490 | + } | ||
| 486 | 491 | ||
| 487 | TemplateList result = tl; | 492 | TemplateList result = tl; |
| 488 | for (int i=0; i<result.size(); i++) | 493 | for (int i=0; i<result.size(); i++) |
openbr/openbr_plugin.h
| @@ -438,7 +438,7 @@ struct TemplateList : public QList<Template> | @@ -438,7 +438,7 @@ struct TemplateList : public QList<Template> | ||
| 438 | BR_EXPORT static TemplateList fromGallery(const File &gallery); /*!< \brief Create a template list from a br::Gallery. */ | 438 | BR_EXPORT static TemplateList fromGallery(const File &gallery); /*!< \brief Create a template list from a br::Gallery. */ |
| 439 | 439 | ||
| 440 | /*!< \brief Ensure labels are in the range [0,numClasses-1]. */ | 440 | /*!< \brief Ensure labels are in the range [0,numClasses-1]. */ |
| 441 | - BR_EXPORT static TemplateList relabel(const TemplateList & tl, const QString & propName); | 441 | + BR_EXPORT static TemplateList relabel(const TemplateList &tl, const QString &propName, bool preserveIntegers); |
| 442 | 442 | ||
| 443 | QList<int> indexProperty(const QString & propName, QHash<QString, int> * valueMap=NULL,QHash<int, QVariant> * reverseLookup = NULL) const; | 443 | QList<int> indexProperty(const QString & propName, QHash<QString, int> * valueMap=NULL,QHash<int, QVariant> * reverseLookup = NULL) const; |
| 444 | QList<int> indexProperty(const QString & propName, QHash<QString, int> & valueMap, QHash<int, QVariant> & reverseLookup) const; | 444 | QList<int> indexProperty(const QString & propName, QHash<QString, int> & valueMap, QHash<int, QVariant> & reverseLookup) const; |
openbr/plugins/eigen3.cpp
| @@ -317,7 +317,7 @@ class LDATransform : public Transform | @@ -317,7 +317,7 @@ class LDATransform : public Transform | ||
| 317 | void train(const TemplateList &_trainingSet) | 317 | void train(const TemplateList &_trainingSet) |
| 318 | { | 318 | { |
| 319 | // creates "Label" | 319 | // creates "Label" |
| 320 | - TemplateList trainingSet = TemplateList::relabel(_trainingSet, inputVariable); | 320 | + TemplateList trainingSet = TemplateList::relabel(_trainingSet, inputVariable, isBinary); |
| 321 | int instances = trainingSet.size(); | 321 | int instances = trainingSet.size(); |
| 322 | 322 | ||
| 323 | // Perform PCA dimensionality reduction | 323 | // Perform PCA dimensionality reduction |
openbr/plugins/gui.cpp
| @@ -447,7 +447,8 @@ public: | @@ -447,7 +447,8 @@ public: | ||
| 447 | } | 447 | } |
| 448 | emit this->changeTitle(newTitle); | 448 | emit this->changeTitle(newTitle); |
| 449 | 449 | ||
| 450 | - foreach(const cv::Mat & m, t) { | 450 | + foreach (const cv::Mat &m, t) { |
| 451 | + if (!m.data) continue; | ||
| 451 | qImageBuffer = toQImage(m); | 452 | qImageBuffer = toQImage(m); |
| 452 | displayBuffer->convertFromImage(qImageBuffer); | 453 | displayBuffer->convertFromImage(qImageBuffer); |
| 453 | 454 |
openbr/plugins/slidingwindow.cpp
| @@ -42,15 +42,15 @@ class SlidingWindowTransform : public MetaTransform | @@ -42,15 +42,15 @@ class SlidingWindowTransform : public MetaTransform | ||
| 42 | { | 42 | { |
| 43 | Q_OBJECT | 43 | Q_OBJECT |
| 44 | Q_PROPERTY(br::Transform *transform READ get_transform WRITE set_transform RESET reset_transform STORED false) | 44 | Q_PROPERTY(br::Transform *transform READ get_transform WRITE set_transform RESET reset_transform STORED false) |
| 45 | - Q_PROPERTY(int stepSize READ get_stepSize WRITE set_stepSize RESET reset_stepSize STORED false) | ||
| 46 | - Q_PROPERTY(bool takeFirst READ get_takeFirst WRITE set_takeFirst RESET reset_takeFirst STORED false) | ||
| 47 | Q_PROPERTY(int windowWidth READ get_windowWidth WRITE set_windowWidth RESET reset_windowWidth STORED false) | 45 | Q_PROPERTY(int windowWidth READ get_windowWidth WRITE set_windowWidth RESET reset_windowWidth STORED false) |
| 46 | + Q_PROPERTY(bool takeFirst READ get_takeFirst WRITE set_takeFirst RESET reset_takeFirst STORED false) | ||
| 48 | Q_PROPERTY(float threshold READ get_threshold WRITE set_threshold RESET reset_threshold STORED false) | 47 | Q_PROPERTY(float threshold READ get_threshold WRITE set_threshold RESET reset_threshold STORED false) |
| 48 | + Q_PROPERTY(float stepFraction READ get_stepFraction WRITE set_stepFraction RESET reset_stepFraction STORED false) | ||
| 49 | BR_PROPERTY(br::Transform *, transform, NULL) | 49 | BR_PROPERTY(br::Transform *, transform, NULL) |
| 50 | - BR_PROPERTY(int, stepSize, 1) | ||
| 51 | - BR_PROPERTY(bool, takeFirst, false) | ||
| 52 | BR_PROPERTY(int, windowWidth, 24) | 50 | BR_PROPERTY(int, windowWidth, 24) |
| 51 | + BR_PROPERTY(bool, takeFirst, false) | ||
| 53 | BR_PROPERTY(float, threshold, 0) | 52 | BR_PROPERTY(float, threshold, 0) |
| 53 | + BR_PROPERTY(float, stepFraction, 0.25) | ||
| 54 | 54 | ||
| 55 | private: | 55 | private: |
| 56 | int windowHeight; | 56 | int windowHeight; |
| @@ -66,36 +66,6 @@ private: | @@ -66,36 +66,6 @@ private: | ||
| 66 | } | 66 | } |
| 67 | } | 67 | } |
| 68 | 68 | ||
| 69 | - void project(const Template &src, Template &dst) const | ||
| 70 | - { | ||
| 71 | - dst = src; | ||
| 72 | - // no need to slide a window over ground truth data | ||
| 73 | - if (src.file.getBool("Train", false)) return; | ||
| 74 | - | ||
| 75 | - dst.file.clearRects(); | ||
| 76 | - float scale = src.file.get<float>("scale", 1); | ||
| 77 | - Template windowTemplate(src.file, src); | ||
| 78 | - QList<float> confidences = dst.file.getList<float>("Confidences", QList<float>()); | ||
| 79 | - for (double y = 0; y + windowHeight < src.m().rows; y += stepSize) { | ||
| 80 | - for (double x = 0; x + windowWidth < src.m().cols; x += stepSize) { | ||
| 81 | - Mat windowMat(src, Rect(x, y, windowWidth, windowHeight)); | ||
| 82 | - windowTemplate.replace(0,windowMat); | ||
| 83 | - Template detect; | ||
| 84 | - transform->project(windowTemplate, detect); | ||
| 85 | - float conf = detect.m().at<float>(0); | ||
| 86 | - | ||
| 87 | - // the result will be in the Label | ||
| 88 | - if (conf > threshold) { | ||
| 89 | - dst.file.appendRect(QRectF((float) x * scale, (float) y * scale, (float) windowWidth * scale, (float) windowHeight * scale)); | ||
| 90 | - confidences.append(conf); | ||
| 91 | - if (takeFirst) | ||
| 92 | - return; | ||
| 93 | - } | ||
| 94 | - } | ||
| 95 | - } | ||
| 96 | - dst.file.setList<float>("Confidences", confidences); | ||
| 97 | - } | ||
| 98 | - | ||
| 99 | void store(QDataStream &stream) const | 69 | void store(QDataStream &stream) const |
| 100 | { | 70 | { |
| 101 | transform->store(stream); | 71 | transform->store(stream); |
| @@ -107,11 +77,71 @@ private: | @@ -107,11 +77,71 @@ private: | ||
| 107 | transform->load(stream); | 77 | transform->load(stream); |
| 108 | stream >> windowHeight; | 78 | stream >> windowHeight; |
| 109 | } | 79 | } |
| 80 | + | ||
| 81 | + void project(const Template &src, Template &dst) const | ||
| 82 | + { | ||
| 83 | + (void)src;(void)dst;qFatal("don't do that"); | ||
| 84 | + } | ||
| 85 | + | ||
| 86 | + void project(const TemplateList &src, TemplateList &dst) const | ||
| 87 | + { | ||
| 88 | + float scale = src.first().file.get<float>("scale", 1); | ||
| 89 | + projectHelp(src, dst, windowWidth, windowHeight, scale); | ||
| 90 | + } | ||
| 91 | + | ||
| 92 | +protected: | ||
| 93 | + void projectHelp(const TemplateList &src, TemplateList &dst, int windowWidth, int windowHeight, float scale = 1) const | ||
| 94 | + { | ||
| 95 | + // no need to slide a window over ground truth data | ||
| 96 | + if (src.first().file.getBool("Train", false)) { | ||
| 97 | + dst = src; | ||
| 98 | + return; | ||
| 99 | + } | ||
| 100 | + | ||
| 101 | + foreach (const Template &t, src) { | ||
| 102 | + for (float y = 0; y + windowHeight < t.m().rows; y += windowHeight*stepFraction) { | ||
| 103 | + for (float x = 0; x + windowWidth < t.m().cols; x += windowWidth*stepFraction) { | ||
| 104 | + Mat windowMat(t.m(), Rect(x, y, windowWidth, windowHeight)); | ||
| 105 | + Template detect; | ||
| 106 | + transform->project(Template(t.file, windowMat), detect); | ||
| 107 | + | ||
| 108 | + // the result will be the only value in the Mat | ||
| 109 | + float conf = detect.m().at<float>(0); | ||
| 110 | + if (conf > threshold) { | ||
| 111 | + detect.file.set("Detection", QRectF(x*scale, y*scale, windowWidth*scale, windowHeight*scale)); | ||
| 112 | + detect.file.set("Confidence", conf); | ||
| 113 | + dst.append(detect); | ||
| 114 | + if (takeFirst) | ||
| 115 | + return; | ||
| 116 | + } | ||
| 117 | + } | ||
| 118 | + } | ||
| 119 | + } | ||
| 120 | + } | ||
| 110 | }; | 121 | }; |
| 111 | 122 | ||
| 112 | BR_REGISTER(Transform, SlidingWindowTransform) | 123 | BR_REGISTER(Transform, SlidingWindowTransform) |
| 113 | 124 | ||
| 114 | -static TemplateList cropTrainingSamples(const TemplateList &data, const float aspectRatio, const int minSize = 0, const float maxOverlap = 0.5, const int negToPosRatio = 1) | 125 | +/*! |
| 126 | + * \ingroup transforms | ||
| 127 | + * \brief Overloads SlidingWindowTransform for integral images that should be | ||
| 128 | + * sampled at multiple scales. | ||
| 129 | + * \author Josh Klontz \cite jklontz | ||
| 130 | + */ | ||
| 131 | +class IntegralSlidingWindowTransform : public SlidingWindowTransform | ||
| 132 | +{ | ||
| 133 | + Q_OBJECT | ||
| 134 | + | ||
| 135 | + void project(const TemplateList &src, TemplateList &dst) const | ||
| 136 | + { | ||
| 137 | + // TODO: call SlidingWindowTransform::project on multiple scales | ||
| 138 | + SlidingWindowTransform::projectHelp(src, dst, 24, 24); | ||
| 139 | + } | ||
| 140 | +}; | ||
| 141 | + | ||
| 142 | +BR_REGISTER(Transform, IntegralSlidingWindowTransform) | ||
| 143 | + | ||
| 144 | +static TemplateList cropTrainingSamples(const TemplateList &data, const float aspectRatio, const int minSize = 32, const float maxOverlap = 0.5, const int negToPosRatio = 1) | ||
| 115 | { | 145 | { |
| 116 | TemplateList result; | 146 | TemplateList result; |
| 117 | foreach (const Template &tmpl, data) { | 147 | foreach (const Template &tmpl, data) { |
| @@ -121,8 +151,8 @@ static TemplateList cropTrainingSamples(const TemplateList &data, const float as | @@ -121,8 +151,8 @@ static TemplateList cropTrainingSamples(const TemplateList &data, const float as | ||
| 121 | Rect &posRect = posRects[i]; | 151 | Rect &posRect = posRects[i]; |
| 122 | 152 | ||
| 123 | // Adjust for training samples that have different aspect ratios | 153 | // Adjust for training samples that have different aspect ratios |
| 124 | - const int diff = posRect.width - int(posRect.height * aspectRatio); | ||
| 125 | - posRect.x += diff / 2; | 154 | + const int diff = int(posRect.height * aspectRatio) - posRect.width; |
| 155 | + posRect.x -= diff / 2; | ||
| 126 | posRect.width += diff; | 156 | posRect.width += diff; |
| 127 | 157 | ||
| 128 | // Ignore samples larger than the image | 158 | // Ignore samples larger than the image |
| @@ -174,7 +204,7 @@ static TemplateList cropTrainingSamples(const TemplateList &data, const float as | @@ -174,7 +204,7 @@ static TemplateList cropTrainingSamples(const TemplateList &data, const float as | ||
| 174 | 204 | ||
| 175 | /*! | 205 | /*! |
| 176 | * \ingroup transforms | 206 | * \ingroup transforms |
| 177 | - * \brief . | 207 | + * \brief Pass along images at different scales. |
| 178 | * \author Austin Blanton \cite imaus10 | 208 | * \author Austin Blanton \cite imaus10 |
| 179 | */ | 209 | */ |
| 180 | class BuildScalesTransform : public MetaTransform | 210 | class BuildScalesTransform : public MetaTransform |
| @@ -219,25 +249,38 @@ private: | @@ -219,25 +249,38 @@ private: | ||
| 219 | 249 | ||
| 220 | void project(const Template &src, Template &dst) const | 250 | void project(const Template &src, Template &dst) const |
| 221 | { | 251 | { |
| 222 | - dst = src; | 252 | + (void)src;(void)dst;qFatal("please don't"); |
| 253 | + } | ||
| 254 | + | ||
| 255 | + void project(const TemplateList &src, TemplateList &dst) const | ||
| 256 | + { | ||
| 223 | // do not scale images during training | 257 | // do not scale images during training |
| 224 | - if (src.file.getBool("Train", false)) return; | ||
| 225 | - | ||
| 226 | - int rows = src.m().rows; | ||
| 227 | - int cols = src.m().cols; | ||
| 228 | - int windowHeight = (int) qRound((float) windowWidth / aspectRatio); | ||
| 229 | - float startScale; | ||
| 230 | - if ((cols / rows) > aspectRatio) | ||
| 231 | - startScale = qRound((float) rows / (float) windowHeight); | ||
| 232 | - else | ||
| 233 | - startScale = qRound((float) cols / (float) windowWidth); | ||
| 234 | - for (float scale = startScale; scale >= minScale; scale -= (1.0 - scaleFactor)) { | ||
| 235 | - Template scaleImg(src.file, Mat()); | ||
| 236 | - scaleImg.file.set("scale", scale); | ||
| 237 | - resize(src, scaleImg, Size(qRound(cols / scale), qRound(rows / scale))); | ||
| 238 | - transform->project(scaleImg, dst); | ||
| 239 | - if (takeLargestScale && !dst.file.rects().empty()) | ||
| 240 | - return; | 258 | + if (src.first().file.getBool("Train", false)) { |
| 259 | + dst = src; | ||
| 260 | + return; | ||
| 261 | + } | ||
| 262 | + | ||
| 263 | + foreach(const Template &t, src) { | ||
| 264 | + int rows = t.m().rows; | ||
| 265 | + int cols = t.m().cols; | ||
| 266 | + int windowHeight = (int) qRound((float) windowWidth / aspectRatio); | ||
| 267 | + float startScale; | ||
| 268 | + if ((cols / rows) > aspectRatio) | ||
| 269 | + startScale = qRound((float) rows / (float) windowHeight); | ||
| 270 | + else | ||
| 271 | + startScale = qRound((float) cols / (float) windowWidth); | ||
| 272 | + for (float scale = startScale; scale >= minScale; scale -= (1.0 - scaleFactor)) { | ||
| 273 | + Template scaleImg(t.file, Mat()); | ||
| 274 | + scaleImg.file.set("scale", scale); | ||
| 275 | + resize(t.m(), scaleImg.m(), Size(qRound(cols / scale), qRound(rows / scale))); | ||
| 276 | + TemplateList results; | ||
| 277 | + TemplateList input; | ||
| 278 | + input.append(scaleImg); | ||
| 279 | + transform->project(input, results); | ||
| 280 | + dst.append(results); | ||
| 281 | + if (takeLargestScale && !dst.empty()) | ||
| 282 | + return; | ||
| 283 | + } | ||
| 241 | } | 284 | } |
| 242 | } | 285 | } |
| 243 | 286 | ||
| @@ -270,6 +313,7 @@ class Detector : public Transform | @@ -270,6 +313,7 @@ class Detector : public Transform | ||
| 270 | { | 313 | { |
| 271 | const float aspectRatio = getAspectRatio(data); | 314 | const float aspectRatio = getAspectRatio(data); |
| 272 | TemplateList cropped = cropTrainingSamples(data, aspectRatio); | 315 | TemplateList cropped = cropTrainingSamples(data, aspectRatio); |
| 316 | + qDebug("Detector using: %d training samples.", cropped.size()); | ||
| 273 | cropped.first().file.set("aspectRatio", aspectRatio); | 317 | cropped.first().file.set("aspectRatio", aspectRatio); |
| 274 | transform->train(cropped); | 318 | transform->train(cropped); |
| 275 | } | 319 | } |
| @@ -327,12 +371,19 @@ private: | @@ -327,12 +371,19 @@ private: | ||
| 327 | 371 | ||
| 328 | void project(const Template &src, Template &dst) const | 372 | void project(const Template &src, Template &dst) const |
| 329 | { | 373 | { |
| 330 | - dst = src; | ||
| 331 | - if (!dst.file.contains("Confidences")) | ||
| 332 | - return; | 374 | + (void)src;(void)dst;qFatal("nope"); |
| 375 | + } | ||
| 333 | 376 | ||
| 334 | - //Compute overlap between rectangles and create discrete Laplacian matrix | ||
| 335 | - QList<Rect> rects = OpenCVUtils::toRects(src.file.rects()); | 377 | + void project(const TemplateList &src, TemplateList &dst) const |
| 378 | + { | ||
| 379 | + QList<Rect> rects; | ||
| 380 | + QList<float> confidences; | ||
| 381 | + foreach (const Template &t, src) { | ||
| 382 | + rects.append(OpenCVUtils::toRect(t.file.get<QRectF>("Detection"))); | ||
| 383 | + confidences.append(t.file.get<float>("Confidence")); | ||
| 384 | + } | ||
| 385 | + | ||
| 386 | + // Compute overlap between rectangles and create discrete Laplacian matrix | ||
| 336 | int n = rects.size(); | 387 | int n = rects.size(); |
| 337 | if (n == 0) | 388 | if (n == 0) |
| 338 | return; | 389 | return; |
| @@ -379,12 +430,12 @@ private: | @@ -379,12 +430,12 @@ private: | ||
| 379 | // each input dimension. Each input dimension corresponds to | 430 | // each input dimension. Each input dimension corresponds to |
| 380 | // one of the input rect region. Thus, each eigenvector represents | 431 | // one of the input rect region. Thus, each eigenvector represents |
| 381 | // a set of overlaping regions. | 432 | // a set of overlaping regions. |
| 382 | - float midX[nRegions]; | ||
| 383 | - float midY[nRegions]; | ||
| 384 | - float avgWidth[nRegions]; | ||
| 385 | - float avgHeight[nRegions]; | ||
| 386 | - float confs[nRegions]; | ||
| 387 | - int cnts[nRegions]; | 433 | + float * midX = new float[nRegions]; |
| 434 | + float * midY = new float[nRegions]; | ||
| 435 | + float * avgWidth = new float[nRegions]; | ||
| 436 | + float *avgHeight = new float[nRegions]; | ||
| 437 | + float *confs = new float[nRegions]; | ||
| 438 | + int *cnts = new int[nRegions]; | ||
| 388 | int mx; | 439 | int mx; |
| 389 | int mxIdx; | 440 | int mxIdx; |
| 390 | for (int i = 0 ; i < nRegions; i++) { | 441 | for (int i = 0 ; i < nRegions; i++) { |
| @@ -396,7 +447,6 @@ private: | @@ -396,7 +447,6 @@ private: | ||
| 396 | cnts[i] = 0; | 447 | cnts[i] = 0; |
| 397 | } | 448 | } |
| 398 | 449 | ||
| 399 | - QList<float> confidences = dst.file.getList<float>("Confidences"); | ||
| 400 | for (int i = 0; i < n; i++) { | 450 | for (int i = 0; i < n; i++) { |
| 401 | mx = 0.0; | 451 | mx = 0.0; |
| 402 | mxIdx = -1; | 452 | mxIdx = -1; |
| @@ -431,8 +481,20 @@ private: | @@ -431,8 +481,20 @@ private: | ||
| 431 | } | 481 | } |
| 432 | } | 482 | } |
| 433 | 483 | ||
| 434 | - dst.file.setRects(consolidatedRects); | ||
| 435 | - dst.file.setList<float>("Confidences", consolidatedConfidences); | 484 | + for (int i=0; i<consolidatedRects.size(); i++) { |
| 485 | + Template t(src.first().file); | ||
| 486 | + t.file.set("Detection", OpenCVUtils::fromRect(consolidatedRects.at(i))); | ||
| 487 | + t.file.set("Confidence", consolidatedConfidences.at(i)); | ||
| 488 | + dst.append(t); | ||
| 489 | + } | ||
| 490 | + | ||
| 491 | + delete [] midX; | ||
| 492 | + delete [] midY; | ||
| 493 | + delete [] avgWidth; | ||
| 494 | + delete [] avgHeight; | ||
| 495 | + delete [] confs; | ||
| 496 | + delete [] cnts; | ||
| 497 | + | ||
| 436 | } | 498 | } |
| 437 | }; | 499 | }; |
| 438 | 500 |
openbr/plugins/stream.cpp
| @@ -363,7 +363,7 @@ public: | @@ -363,7 +363,7 @@ public: | ||
| 363 | return this->templates.size(); | 363 | return this->templates.size(); |
| 364 | } | 364 | } |
| 365 | 365 | ||
| 366 | - bool open(TemplateList & input, br::Idiocy::StreamModes _mode) | 366 | + bool open(const TemplateList & input, br::Idiocy::StreamModes _mode) |
| 367 | { | 367 | { |
| 368 | // Set up variables specific to us | 368 | // Set up variables specific to us |
| 369 | current_template_idx = 0; | 369 | current_template_idx = 0; |
| @@ -1030,8 +1030,10 @@ public: | @@ -1030,8 +1030,10 @@ public: | ||
| 1030 | void projectUpdate(const TemplateList & src, TemplateList & dst) | 1030 | void projectUpdate(const TemplateList & src, TemplateList & dst) |
| 1031 | { | 1031 | { |
| 1032 | dst = src; | 1032 | dst = src; |
| 1033 | + if (src.empty()) | ||
| 1034 | + return; | ||
| 1033 | 1035 | ||
| 1034 | - bool res = readStage->dataSource.open(dst,readMode); | 1036 | + bool res = readStage->dataSource.open(src,readMode); |
| 1035 | if (!res) { | 1037 | if (!res) { |
| 1036 | qDebug("stream failed to open %s", qPrintable(dst[0].file.name)); | 1038 | qDebug("stream failed to open %s", qPrintable(dst[0].file.name)); |
| 1037 | return; | 1039 | return; |
| @@ -1082,6 +1084,8 @@ public: | @@ -1082,6 +1084,8 @@ public: | ||
| 1082 | // with anything output via the calls to finalize. | 1084 | // with anything output via the calls to finalize. |
| 1083 | //dst = collectionStage->getOutput(); | 1085 | //dst = collectionStage->getOutput(); |
| 1084 | 1086 | ||
| 1087 | + // dst is set to all output received by the final stage, along | ||
| 1088 | + // with anything output via the calls to finalize. | ||
| 1085 | foreach(const TemplateList & list, collector->sets) { | 1089 | foreach(const TemplateList & list, collector->sets) { |
| 1086 | dst.append(list); | 1090 | dst.append(list); |
| 1087 | } | 1091 | } |
scripts/downloadDatasets.sh
| @@ -102,3 +102,21 @@ if [ ! -d ../data/MEDS/img ]; then | @@ -102,3 +102,21 @@ if [ ! -d ../data/MEDS/img ]; then | ||
| 102 | mv data/*/*.jpg ../data/MEDS/img | 102 | mv data/*/*.jpg ../data/MEDS/img |
| 103 | rm -r data NIST_SD32_MEDS-II_face.zip | 103 | rm -r data NIST_SD32_MEDS-II_face.zip |
| 104 | fi | 104 | fi |
| 105 | + | ||
| 106 | +#LFPW | ||
| 107 | +if [ ! -d ../data/lfpw/trainset ]; then | ||
| 108 | + echo "Downloading LFPW..." | ||
| 109 | + if hash curl 2>/dev/null; then | ||
| 110 | + curl -OL http://ibug.doc.ic.ac.uk/media/uploads/competitions/lfpw.zip | ||
| 111 | + else | ||
| 112 | + wget http://ibug.doc.ic.ac.uk/media/uploads/competitions/lfpw.zip | ||
| 113 | + fi | ||
| 114 | + | ||
| 115 | + unzip lfpw.zip | ||
| 116 | + mv lfpw ../data | ||
| 117 | + cd ../data/lfpw | ||
| 118 | + python ../../scripts/lfpwToSigset.py | ||
| 119 | + cd ../../scripts | ||
| 120 | + rm lfpw.zip | ||
| 121 | +fi | ||
| 122 | + |
scripts/lfpwToSigset.py
0 → 100644
| 1 | +#!/usr/bin/python | ||
| 2 | + | ||
| 3 | +# This scripts converts the LFPW .pts files into xml sigsets that can be readily | ||
| 4 | +# used within openbr. | ||
| 5 | + | ||
| 6 | +from xml.dom.minidom import Document | ||
| 7 | +import glob | ||
| 8 | +import os | ||
| 9 | + | ||
| 10 | +for lfpwType in ['train','test']: | ||
| 11 | + files = glob.glob('%sset/*.pts' % lfpwType) | ||
| 12 | + files.sort() | ||
| 13 | + cnt = 0 | ||
| 14 | + | ||
| 15 | + xmlDoc = Document() | ||
| 16 | + xmlRoot = xmlDoc.createElement('biometric-signature-set') | ||
| 17 | + for ptsFile in files: | ||
| 18 | + cnt += 1 | ||
| 19 | + ini = open(ptsFile) | ||
| 20 | + lines = ini.readlines() | ||
| 21 | + ini.close() | ||
| 22 | + | ||
| 23 | + pntStrList = [] | ||
| 24 | + n = int(lines[1].split()[1]) | ||
| 25 | + for i in range(3,3+n): | ||
| 26 | + pntStrList.append('(%s)' % (','.join(lines[i].split()))) | ||
| 27 | + pntStr = '[%s]' % ','.join(pntStrList) | ||
| 28 | + | ||
| 29 | + xmlSubj = xmlDoc.createElement('biometric-signature') | ||
| 30 | + xmlSubj.setAttribute('name','subj_%05d' % cnt) | ||
| 31 | + xmlPres = xmlDoc.createElement('presentation') | ||
| 32 | + xmlPres.setAttribute('file-name','%sset/%s.png' % (lfpwType,os.path.splitext(ptsFile)[0])) | ||
| 33 | + xmlPres.setAttribute('Points',pntStr) | ||
| 34 | + xmlSubj.appendChild(xmlPres) | ||
| 35 | + xmlRoot.appendChild(xmlSubj) | ||
| 36 | + | ||
| 37 | + if not os.path.exists('sigset'): | ||
| 38 | + os.mkdir('sigset') | ||
| 39 | + out = open('sigset/%s.xml' % lfpwType,'w') | ||
| 40 | + print >> out, xmlRoot.toprettyxml() | ||
| 41 | + out.close() | ||
| 42 | + | ||
| 43 | + |
scripts/pedestrianBaselineLBP.sh
| @@ -13,7 +13,7 @@ fi | @@ -13,7 +13,7 @@ fi | ||
| 13 | ALG="Open+Cvt(Gray)+Rename(neg,0)+BuildScales(Blur(2)+LBP(1,2)+SlidingWindow(Hist(59)+Cat+LDA(isBinary=true),windowWidth=10,takeLargestScale=false,threshold=2),windowWidth=10,takeLargestScale=false,minScale=4)+ConsolidateDetections+Discard" | 13 | ALG="Open+Cvt(Gray)+Rename(neg,0)+BuildScales(Blur(2)+LBP(1,2)+SlidingWindow(Hist(59)+Cat+LDA(isBinary=true),windowWidth=10,takeLargestScale=false,threshold=2),windowWidth=10,takeLargestScale=false,minScale=4)+ConsolidateDetections+Discard" |
| 14 | 14 | ||
| 15 | # Josh's new algorithm (in progress) | 15 | # Josh's new algorithm (in progress) |
| 16 | -# ALG2="Open+Cvt(Gray)+Detector(Gradient+Bin(0,360,9,true)+Merge+Integral+SlidingWindow(Identity))" | 16 | +# ALG="Open+Cvt(Gray)+Detector(Gradient+Bin(0,360,9,true)+Merge+Integral+IntegralSlidingWindow(RecursiveIntegralSampler(2,2,0,PCA(0.95))+Cat+LDA(0.95,isBinary=true)))" |
| 17 | 17 | ||
| 18 | br -useGui 0 \ | 18 | br -useGui 0 \ |
| 19 | -algorithm "${ALG}" \ | 19 | -algorithm "${ALG}" \ |