Commit 6293aebec14d49615bc161c3caa48e0610dcdeca

Authored by Brendan Klare
1 parent 1daaeabb

Bug fix in the negative value thresholding

Showing 1 changed file with 119 additions and 0 deletions
openbr/plugins/ltp.cpp 0 → 100644
  1 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2 + * Copyright 2012 The MITRE Corporation *
  3 + * *
  4 + * Licensed under the Apache License, Version 2.0 (the "License"); *
  5 + * you may not use this file except in compliance with the License. *
  6 + * You may obtain a copy of the License at *
  7 + * *
  8 + * http://www.apache.org/licenses/LICENSE-2.0 *
  9 + * *
  10 + * Unless required by applicable law or agreed to in writing, software *
  11 + * distributed under the License is distributed on an "AS IS" BASIS, *
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
  13 + * See the License for the specific language governing permissions and *
  14 + * limitations under the License. *
  15 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  16 +
  17 +#include <opencv2/imgproc/imgproc.hpp>
  18 +#include <limits>
  19 +#include "openbr_internal.h"
  20 +#include <iostream>
  21 +
  22 +using namespace cv;
  23 +
  24 +namespace br
  25 +{
  26 +
  27 +/*!
  28 + * \ingroup transforms
  29 + * \brief Tan, Xiaoyang, and Bill Triggs. "Enhanced local texture feature sets for face recognition under difficult lighting conditions." Analysis and Modeling of Faces and Gestures. Springer Berlin Heidelberg, 2007. 168-182.
  30 + * \author Brendan Klare \cite bklare
  31 + * \author Josh Klontz \cite jklontz
  32 + */
  33 +class LTPTransform : public UntrainableTransform
  34 +{
  35 + Q_OBJECT
  36 + Q_PROPERTY(int radius READ get_radius WRITE set_radius RESET reset_radius STORED false)
  37 + Q_PROPERTY(float threshold READ get_threshold WRITE set_threshold RESET reset_threshold STORED false)
  38 + BR_PROPERTY(int, radius, 1)
  39 + BR_PROPERTY(float, threshold, 0.1F)
  40 +
  41 + unsigned short lut[8][3];
  42 + uchar null;
  43 +
  44 + void init()
  45 + {
  46 + unsigned short cnt = 0;
  47 + for (int i = 0; i < 8; i++) {
  48 + for (int j = 0; j < 3; j++)
  49 + lut[i][j] = cnt++;
  50 + cnt++; //we skip the 4th number (only three patterns)
  51 + }
  52 + }
  53 +
  54 + void project(const Template &src, Template &dst) const
  55 + {
  56 + Mat m; src.m().convertTo(m, CV_32F); assert(m.isContinuous() && (m.channels() == 1));
  57 +
  58 + Mat n(m.rows, m.cols, CV_16U);
  59 + n = null;
  60 + float thresholdNeg = -1.0 * threshold; //compute once (can move to init)
  61 +
  62 + const float *p = (const float*)m.ptr();
  63 + float diff;
  64 + for (int r=radius; r<m.rows-radius; r++) {
  65 + for (int c=radius; c<m.cols-radius; c++) {
  66 + const float cval = (p[(r+0*radius)*m.cols+c+0*radius]);
  67 +
  68 + diff = p[(r-1*radius)*m.cols+c-1*radius] - cval;
  69 + if (diff > threshold) n.at<unsigned short>(r,c) = lut[0][0];
  70 + else if (diff < thresholdNeg) n.at<unsigned short>(r,c) = lut[0][1];
  71 + else n.at<unsigned short>(r,c) = lut[0][2];
  72 +
  73 + diff = p[(r-1*radius)*m.cols+c+0*radius] - cval;
  74 + if (diff > threshold) n.at<unsigned short>(r,c) += lut[1][0];
  75 + else if (diff < thresholdNeg) n.at<unsigned short>(r,c) += lut[1][1];
  76 + else n.at<unsigned short>(r,c) += lut[1][2];
  77 +
  78 + diff = p[(r-1*radius)*m.cols+c+1*radius] - cval;
  79 + if (diff > threshold) n.at<unsigned short>(r,c) += lut[2][0];
  80 + else if (diff < thresholdNeg) n.at<unsigned short>(r,c) += lut[2][1];
  81 + else n.at<unsigned short>(r,c) += lut[2][2];
  82 +
  83 + diff = p[(r+0*radius)*m.cols+c+1*radius] - cval;
  84 + if (diff > threshold) n.at<unsigned short>(r,c) += lut[3][0];
  85 + else if (diff < thresholdNeg) n.at<unsigned short>(r,c) += lut[3][1];
  86 + else n.at<unsigned short>(r,c) += lut[3][2];
  87 +
  88 + diff = p[(r+1*radius)*m.cols+c+1*radius] - cval;
  89 + if (diff > threshold) n.at<unsigned short>(r,c) += lut[4][0];
  90 + else if (diff < thresholdNeg) n.at<unsigned short>(r,c) += lut[4][1];
  91 + else n.at<unsigned short>(r,c) += lut[4][2];
  92 +
  93 + diff = p[(r+1*radius)*m.cols+c+0*radius] - cval;
  94 + if (diff > threshold) n.at<unsigned short>(r,c) += lut[5][0];
  95 + else if (diff < thresholdNeg) n.at<unsigned short>(r,c) += lut[5][1];
  96 + else n.at<unsigned short>(r,c) += lut[5][2];
  97 +
  98 + diff = p[(r+1*radius)*m.cols+c-1*radius] - cval;
  99 + if (diff > threshold) n.at<unsigned short>(r,c) += lut[6][0];
  100 + else if (diff < thresholdNeg) n.at<unsigned short>(r,c) += lut[6][1];
  101 + else n.at<unsigned short>(r,c) += lut[6][2];
  102 +
  103 + diff = p[(r+0*radius)*m.cols+c-1*radius] - cval;
  104 + if (diff > threshold) n.at<unsigned short>(r,c) += lut[7][0];
  105 + else if (diff < thresholdNeg) n.at<unsigned short>(r,c) += lut[7][1];
  106 + else n.at<unsigned short>(r,c) += lut[7][2];
  107 + }
  108 + }
  109 +
  110 + dst += n;
  111 + }
  112 +};
  113 +
  114 +BR_REGISTER(Transform, LTPTransform)
  115 +
  116 +
  117 +} // namespace br
  118 +
  119 +#include "ltp.moc"
... ...