Commit 656723557985836af2bcd6566f67280cd5a6c25d

Authored by Scott Klum
2 parents 56866e7f 937d05f5

Merge pull request #315 from biometrics/rndsample

Implemented RndSample transform
Showing 1 changed file with 87 additions and 0 deletions
openbr/plugins/random.cpp
@@ -14,11 +14,14 @@ @@ -14,11 +14,14 @@
14 * limitations under the License. * 14 * limitations under the License. *
15 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 15 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
16 16
  17 +#include <numeric>
  18 +
17 #include <opencv2/imgproc/imgproc.hpp> 19 #include <opencv2/imgproc/imgproc.hpp>
18 #include "openbr_internal.h" 20 #include "openbr_internal.h"
19 21
20 #include "openbr/core/common.h" 22 #include "openbr/core/common.h"
21 #include "openbr/core/opencvutils.h" 23 #include "openbr/core/opencvutils.h"
  24 +#include "openbr/core/qtutils.h"
22 25
23 using namespace cv; 26 using namespace cv;
24 27
@@ -132,6 +135,90 @@ BR_REGISTER(Transform, RndRegionTransform) @@ -132,6 +135,90 @@ BR_REGISTER(Transform, RndRegionTransform)
132 135
133 /*! 136 /*!
134 * \ingroup transforms 137 * \ingroup transforms
  138 + * \brief Selects a random region about a point to use for training.
  139 + * \author Scott Klum \cite sklum
  140 + */
  141 +
  142 +class RndSampleTransform : public UntrainableMetaTransform
  143 +{
  144 + Q_OBJECT
  145 + Q_PROPERTY(int pointIndex READ get_pointIndex WRITE set_pointIndex RESET reset_pointIndex)
  146 + Q_PROPERTY(int sampleRadius READ get_sampleRadius WRITE set_sampleRadius RESET reset_sampleRadius)
  147 + Q_PROPERTY(int sampleFactor READ get_sampleFactor WRITE set_sampleFactor RESET reset_sampleFactor)
  148 + Q_PROPERTY(bool duplicatePositiveSamples READ get_duplicatePositiveSamples WRITE set_duplicatePositiveSamples RESET reset_duplicatePositiveSamples STORED true)
  149 + Q_PROPERTY(QList<float> sampleOverlapBands READ get_sampleOverlapBands WRITE set_sampleOverlapBands RESET reset_sampleOverlapBands STORED true)
  150 + Q_PROPERTY(int samplesPerOverlapBand READ get_samplesPerOverlapBand WRITE set_samplesPerOverlapBand RESET reset_samplesPerOverlapBand STORED true)
  151 + Q_PROPERTY(bool classification READ get_classification WRITE set_classification RESET reset_classification STORED true)
  152 + Q_PROPERTY(float overlapPower READ get_overlapPower WRITE set_overlapPower RESET reset_overlapPower STORED true)
  153 + Q_PROPERTY(QString inputVariable READ get_inputVariable WRITE set_inputVariable RESET reset_inputVariable STORED true)
  154 + BR_PROPERTY(int, pointIndex, 0)
  155 + BR_PROPERTY(int, sampleRadius, 6)
  156 + BR_PROPERTY(int, sampleFactor, 4)
  157 + BR_PROPERTY(bool, duplicatePositiveSamples, true)
  158 + BR_PROPERTY(QList<float>, sampleOverlapBands, QList<float>() << .1 << .5 << .7 << .9 << 1.0)
  159 + BR_PROPERTY(int, samplesPerOverlapBand, 2)
  160 + BR_PROPERTY(bool, classification, true)
  161 + BR_PROPERTY(float, overlapPower, 1)
  162 + BR_PROPERTY(QString, inputVariable, "Label")
  163 +
  164 + void project(const TemplateList &src, TemplateList &dst) const
  165 + {
  166 + foreach(const Template &t, src) {
  167 + QPointF point = t.file.points()[0];
  168 + QRectF region(point.x()-sampleRadius, point.y()-sampleRadius, sampleRadius*2, sampleRadius*2);
  169 +
  170 + if (region.x() < 0 ||
  171 + region.y() < 0 ||
  172 + region.x() + region.width() >= t.m().cols ||
  173 + region.y() + region.height() >= t.m().rows)
  174 + continue;
  175 +
  176 + int positiveSamples = duplicatePositiveSamples ? (sampleOverlapBands.size()-1)*samplesPerOverlapBand : 1;
  177 + for (int k=0; k<positiveSamples; k++) {
  178 + dst.append(Template(t.file, Mat(t.m(), OpenCVUtils::toRect(region))));
  179 + dst.last().file.set(inputVariable, 1);
  180 + }
  181 +
  182 + QList<int> labelCount;
  183 + for (int k=0; k<sampleOverlapBands.size()-1; k++)
  184 + labelCount << 0;
  185 +
  186 + while (std::accumulate(labelCount.begin(),labelCount.end(),0.0) < (sampleOverlapBands.size()-1)*samplesPerOverlapBand) {
  187 + float x = rand() % (sampleFactor*sampleRadius) + region.x() - sampleFactor/2*sampleRadius;
  188 + float y = rand() % (sampleFactor*sampleRadius) + region.y() - sampleFactor/2*sampleRadius;
  189 +
  190 + if (x < 0 || y < 0 || x+2*sampleRadius > t.m().cols || y+2*sampleRadius > t.m().rows)
  191 + continue;
  192 +
  193 + QRectF negativeLocation = QRectF(x, y, sampleRadius*2, sampleRadius*2);
  194 +
  195 + float overlap = QtUtils::overlap(region, negativeLocation);
  196 +
  197 + for (int k = 0; k<sampleOverlapBands.size()-1; k++) {
  198 + if (overlap >= sampleOverlapBands.at(k) && overlap < sampleOverlapBands.at(k+1) && labelCount[k] < samplesPerOverlapBand) {
  199 + Mat m(t.m(),OpenCVUtils::toRect(negativeLocation));
  200 + dst.append(Template(t.file, m));
  201 + float label = classification ? 0 : pow(overlap,overlapPower);
  202 + dst.last().file.set(inputVariable, label);
  203 + labelCount[k]++;
  204 + }
  205 + }
  206 + }
  207 + }
  208 + }
  209 +
  210 + void project(const Template &src, Template &dst) const {
  211 + TemplateList temp;
  212 + project(TemplateList() << src, temp);
  213 + if (!temp.isEmpty()) dst = temp.first();
  214 + }
  215 +
  216 +};
  217 +
  218 +BR_REGISTER(Transform, RndSampleTransform)
  219 +
  220 +/*!
  221 + * \ingroup transforms
135 * \brief Generates a random landmark. 222 * \brief Generates a random landmark.
136 * \author Josh Klontz \cite jklontz 223 * \author Josh Klontz \cite jklontz
137 */ 224 */