Commit 5f37e44fb324453e4854eecfa035b97a169e10c7
1 parent
94f8e680
added more transforms
Showing
4 changed files
with
75 additions
and
17 deletions
sdk/plugins/algorithms.cpp
| @@ -50,7 +50,7 @@ class AlgorithmsInitializer : public Initializer | @@ -50,7 +50,7 @@ class AlgorithmsInitializer : public Initializer | ||
| 50 | Globals->abbreviations.insert("SmallSIFT", "Open+LimitSize(512)+KeyPointDetector(SIFT)+KeyPointDescriptor(SIFT):KeyPointMatcher(BruteForce)"); | 50 | Globals->abbreviations.insert("SmallSIFT", "Open+LimitSize(512)+KeyPointDetector(SIFT)+KeyPointDescriptor(SIFT):KeyPointMatcher(BruteForce)"); |
| 51 | Globals->abbreviations.insert("SmallSURF", "Open+LimitSize(512)+KeyPointDetector(SURF)+KeyPointDescriptor(SURF):KeyPointMatcher(BruteForce)"); | 51 | Globals->abbreviations.insert("SmallSURF", "Open+LimitSize(512)+KeyPointDetector(SURF)+KeyPointDescriptor(SURF):KeyPointMatcher(BruteForce)"); |
| 52 | Globals->abbreviations.insert("ColorHist", "Open+LimitSize(512)!EnsureChannels(3)+SplitChannels+Hist(256,0,8)+Cat+Normalize(L1):L2"); | 52 | Globals->abbreviations.insert("ColorHist", "Open+LimitSize(512)!EnsureChannels(3)+SplitChannels+Hist(256,0,8)+Cat+Normalize(L1):L2"); |
| 53 | - Globals->abbreviations.insert("IHH", "Open+SplitChannels/(Cvt(Gray)+Gradient+Bin(0,6.283,8,true))+Integral+Merge+IntegralSampler"); | 53 | + Globals->abbreviations.insert("IHH", "Open+(RG+MAdd(0.5))/(Cvt(Gray)+Gradient+Bin(0,360,8,true))+Merge+Integral+IntegralSampler+CvtFloat:L2"); |
| 54 | 54 | ||
| 55 | // Hash | 55 | // Hash |
| 56 | Globals->abbreviations.insert("FileName", "Name+Identity:Identical"); | 56 | Globals->abbreviations.insert("FileName", "Name+Identity:Identical"); |
sdk/plugins/cvt.cpp
| @@ -160,6 +160,63 @@ class EnsureChannelsTransform : public UntrainableTransform | @@ -160,6 +160,63 @@ class EnsureChannelsTransform : public UntrainableTransform | ||
| 160 | 160 | ||
| 161 | BR_REGISTER(Transform, EnsureChannelsTransform) | 161 | BR_REGISTER(Transform, EnsureChannelsTransform) |
| 162 | 162 | ||
| 163 | +/*! | ||
| 164 | + * \ingroup transforms | ||
| 165 | + * \brief Normalized RG color space. | ||
| 166 | + * \author Josh Klontz \cite jklontz | ||
| 167 | + */ | ||
| 168 | +class RGTransform : public UntrainableTransform | ||
| 169 | +{ | ||
| 170 | + Q_OBJECT | ||
| 171 | + | ||
| 172 | + void project(const Template &src, Template &dst) const | ||
| 173 | + { | ||
| 174 | + if (src.m().type() != CV_8UC3) | ||
| 175 | + qFatal("Expected CV_8UC3 images."); | ||
| 176 | + | ||
| 177 | + const Mat &m = src.m(); | ||
| 178 | + Mat R(m.size(), CV_8UC1); // R / (R+G+B) | ||
| 179 | + Mat G(m.size(), CV_8UC1); // G / (R+G+B) | ||
| 180 | + | ||
| 181 | + for (int i=0; i<m.rows; i++) | ||
| 182 | + for (int j=0; j<m.cols; j++) { | ||
| 183 | + Vec3b v = m.at<Vec3b>(i,j); | ||
| 184 | + uchar& b = v[0]; | ||
| 185 | + uchar& g = v[1]; | ||
| 186 | + uchar& r = v[2]; | ||
| 187 | + | ||
| 188 | + R.at<uchar>(i, j) = saturate_cast<uchar>(255.0*r/(r+g+b)); | ||
| 189 | + G.at<uchar>(i, j) = saturate_cast<uchar>(255.0*g/(r+g+b)); | ||
| 190 | + } | ||
| 191 | + | ||
| 192 | + dst.append(R); | ||
| 193 | + dst.append(G); | ||
| 194 | + } | ||
| 195 | +}; | ||
| 196 | + | ||
| 197 | +BR_REGISTER(Transform, RGTransform) | ||
| 198 | + | ||
| 199 | +/*! | ||
| 200 | + * \ingroup transforms | ||
| 201 | + * \brief dst = a*src+b | ||
| 202 | + * \author Josh Klontz \cite jklontz | ||
| 203 | + */ | ||
| 204 | +class MAddTransform : public UntrainableTransform | ||
| 205 | +{ | ||
| 206 | + Q_OBJECT | ||
| 207 | + Q_PROPERTY(double a READ get_a WRITE set_a RESET reset_a STORED false) | ||
| 208 | + Q_PROPERTY(double b READ get_b WRITE set_b RESET reset_b STORED false) | ||
| 209 | + BR_PROPERTY(double, a, 1) | ||
| 210 | + BR_PROPERTY(double, b, 0) | ||
| 211 | + | ||
| 212 | + void project(const Template &src, Template &dst) const | ||
| 213 | + { | ||
| 214 | + src.m().convertTo(dst.m(), src.m().depth(), a, b); | ||
| 215 | + } | ||
| 216 | +}; | ||
| 217 | + | ||
| 218 | +BR_REGISTER(Transform, MAddTransform) | ||
| 219 | + | ||
| 163 | } // namespace br | 220 | } // namespace br |
| 164 | 221 | ||
| 165 | #include "cvt.moc" | 222 | #include "cvt.moc" |
sdk/plugins/hist.cpp
| @@ -83,13 +83,13 @@ class BinTransform : public UntrainableTransform | @@ -83,13 +83,13 @@ class BinTransform : public UntrainableTransform | ||
| 83 | 83 | ||
| 84 | void project(const Template &src, Template &dst) const | 84 | void project(const Template &src, Template &dst) const |
| 85 | { | 85 | { |
| 86 | - src.m().convertTo(dst, bins > 256 ? CV_16U : CV_8U, bins/(max-min)); | 86 | + src.m().convertTo(dst, bins > 256 ? CV_16U : CV_8U, bins/(max-min), -0.5 /* floor */); |
| 87 | if (!split) return; | 87 | if (!split) return; |
| 88 | 88 | ||
| 89 | Mat input = dst; | 89 | Mat input = dst; |
| 90 | QList<Mat> outputs; outputs.reserve(bins); | 90 | QList<Mat> outputs; outputs.reserve(bins); |
| 91 | for (int i=0; i<bins; i++) | 91 | for (int i=0; i<bins; i++) |
| 92 | - outputs.append(input == i); | 92 | + outputs.append(input == i); // Note: Matrix elements are 0 or 255 |
| 93 | dst.clear(); dst.append(outputs); | 93 | dst.clear(); dst.append(outputs); |
| 94 | } | 94 | } |
| 95 | }; | 95 | }; |
sdk/plugins/integral.cpp
| @@ -2,6 +2,8 @@ | @@ -2,6 +2,8 @@ | ||
| 2 | #include <Eigen/Core> | 2 | #include <Eigen/Core> |
| 3 | #include <openbr_plugin.h> | 3 | #include <openbr_plugin.h> |
| 4 | 4 | ||
| 5 | +#include "core/opencvutils.h" | ||
| 6 | + | ||
| 5 | using namespace cv; | 7 | using namespace cv; |
| 6 | 8 | ||
| 7 | namespace br | 9 | namespace br |
| @@ -26,25 +28,25 @@ BR_REGISTER(Transform, IntegralTransform) | @@ -26,25 +28,25 @@ BR_REGISTER(Transform, IntegralTransform) | ||
| 26 | 28 | ||
| 27 | /*! | 29 | /*! |
| 28 | * \ingroup transforms | 30 | * \ingroup transforms |
| 29 | - * \brief Sliding window object recognition from a multi-channel intergral image. | 31 | + * \brief Sliding window feature extraction from a multi-channel intergral image. |
| 30 | * \author Josh Klontz \cite jklontz | 32 | * \author Josh Klontz \cite jklontz |
| 31 | */ | 33 | */ |
| 32 | -class IntegralSampler : public UntrainableTransform | 34 | +class IntegralSamplerTransform : public UntrainableTransform |
| 33 | { | 35 | { |
| 34 | Q_OBJECT | 36 | Q_OBJECT |
| 35 | Q_PROPERTY(int scales READ get_scales WRITE set_scales RESET reset_scales STORED false) | 37 | Q_PROPERTY(int scales READ get_scales WRITE set_scales RESET reset_scales STORED false) |
| 36 | Q_PROPERTY(float scaleFactor READ get_scaleFactor WRITE set_scaleFactor RESET reset_scaleFactor STORED false) | 38 | Q_PROPERTY(float scaleFactor READ get_scaleFactor WRITE set_scaleFactor RESET reset_scaleFactor STORED false) |
| 37 | Q_PROPERTY(float stepFactor READ get_stepFactor WRITE set_stepFactor RESET reset_stepFactor STORED false) | 39 | Q_PROPERTY(float stepFactor READ get_stepFactor WRITE set_stepFactor RESET reset_stepFactor STORED false) |
| 38 | Q_PROPERTY(int minSize READ get_minSize WRITE set_minSize RESET reset_minSize STORED false) | 40 | Q_PROPERTY(int minSize READ get_minSize WRITE set_minSize RESET reset_minSize STORED false) |
| 39 | - BR_PROPERTY(int, scales, 1) | ||
| 40 | - BR_PROPERTY(float, scaleFactor, 1.25) | 41 | + BR_PROPERTY(int, scales, 3) |
| 42 | + BR_PROPERTY(float, scaleFactor, 2) | ||
| 41 | BR_PROPERTY(float, stepFactor, 0.25) | 43 | BR_PROPERTY(float, stepFactor, 0.25) |
| 42 | BR_PROPERTY(int, minSize, 8) | 44 | BR_PROPERTY(int, minSize, 8) |
| 43 | 45 | ||
| 44 | void project(const Template &src, Template &dst) const | 46 | void project(const Template &src, Template &dst) const |
| 45 | { | 47 | { |
| 46 | typedef Eigen::Map< const Eigen::Matrix<qint32,Eigen::Dynamic,1> > InputDescriptor; | 48 | typedef Eigen::Map< const Eigen::Matrix<qint32,Eigen::Dynamic,1> > InputDescriptor; |
| 47 | - typedef Eigen::Map< Eigen::Matrix<qint32,Eigen::Dynamic,1> > OutputDescriptor; | 49 | + typedef Eigen::Map< Eigen::Matrix<float,Eigen::Dynamic,1> > OutputDescriptor; |
| 48 | const Mat &m = src.m(); | 50 | const Mat &m = src.m(); |
| 49 | if (m.depth() != CV_32S) qFatal("Expected CV_32S matrix depth."); | 51 | if (m.depth() != CV_32S) qFatal("Expected CV_32S matrix depth."); |
| 50 | const int channels = m.channels(); | 52 | const int channels = m.channels(); |
| @@ -53,16 +55,16 @@ class IntegralSampler : public UntrainableTransform | @@ -53,16 +55,16 @@ class IntegralSampler : public UntrainableTransform | ||
| 53 | int descriptors = 0; | 55 | int descriptors = 0; |
| 54 | int currentSize = min(m.rows, m.cols)-1; | 56 | int currentSize = min(m.rows, m.cols)-1; |
| 55 | for (int scale=0; scale<scales; scale++) { | 57 | for (int scale=0; scale<scales; scale++) { |
| 56 | - descriptors += ceil((m.rows-currentSize)*stepFactor/currentSize) * | ||
| 57 | - ceil((m.cols-currentSize)*stepFactor/currentSize); | 58 | + descriptors += int(1+(m.rows-currentSize)/(currentSize*stepFactor)) * |
| 59 | + int(1+(m.cols-currentSize)/(currentSize*stepFactor)); | ||
| 58 | currentSize /= scaleFactor; | 60 | currentSize /= scaleFactor; |
| 59 | if (currentSize < minSize) | 61 | if (currentSize < minSize) |
| 60 | break; | 62 | break; |
| 61 | } | 63 | } |
| 62 | - Mat n(descriptors, channels, CV_32SC1); | 64 | + Mat n(descriptors, channels, CV_32FC1); |
| 63 | 65 | ||
| 64 | const qint32 *dataIn = (qint32*)m.data; | 66 | const qint32 *dataIn = (qint32*)m.data; |
| 65 | - qint32 *dataOut = (qint32*)n.data; | 67 | + float *dataOut = (float*)n.data; |
| 66 | currentSize = min(m.rows, m.cols)-1; | 68 | currentSize = min(m.rows, m.cols)-1; |
| 67 | int index = 0; | 69 | int index = 0; |
| 68 | for (int scale=0; scale<scales; scale++) { | 70 | for (int scale=0; scale<scales; scale++) { |
| @@ -71,10 +73,10 @@ class IntegralSampler : public UntrainableTransform | @@ -71,10 +73,10 @@ class IntegralSampler : public UntrainableTransform | ||
| 71 | for (int j=currentSize; j<m.cols; j+=currentStep) { | 73 | for (int j=currentSize; j<m.cols; j+=currentStep) { |
| 72 | InputDescriptor a(dataIn+((i-currentSize)*rowStep+(j-currentSize)*channels), channels, 1); | 74 | InputDescriptor a(dataIn+((i-currentSize)*rowStep+(j-currentSize)*channels), channels, 1); |
| 73 | InputDescriptor b(dataIn+((i-currentSize)*rowStep+ j *channels), channels, 1); | 75 | InputDescriptor b(dataIn+((i-currentSize)*rowStep+ j *channels), channels, 1); |
| 74 | - InputDescriptor c(dataIn+( i *rowStep+(j-currentSize)*channels), channels, 1); | ||
| 75 | - InputDescriptor d(dataIn+( i *rowStep+ j *channels), channels, 1); | 76 | + InputDescriptor c(dataIn+(i *rowStep+(j-currentSize)*channels), channels, 1); |
| 77 | + InputDescriptor d(dataIn+(i *rowStep+ j *channels), channels, 1); | ||
| 76 | OutputDescriptor y(dataOut+(index*channels), channels, 1); | 78 | OutputDescriptor y(dataOut+(index*channels), channels, 1); |
| 77 | - y = d-b-c+a; | 79 | + y = (d-b-c+a).cast<float>()/(currentSize*currentSize); |
| 78 | index++; | 80 | index++; |
| 79 | } | 81 | } |
| 80 | } | 82 | } |
| @@ -82,12 +84,11 @@ class IntegralSampler : public UntrainableTransform | @@ -82,12 +84,11 @@ class IntegralSampler : public UntrainableTransform | ||
| 82 | if (currentSize < minSize) | 84 | if (currentSize < minSize) |
| 83 | break; | 85 | break; |
| 84 | } | 86 | } |
| 85 | - | ||
| 86 | dst.m() = n; | 87 | dst.m() = n; |
| 87 | } | 88 | } |
| 88 | }; | 89 | }; |
| 89 | 90 | ||
| 90 | -BR_REGISTER(Transform, IntegralSampler) | 91 | +BR_REGISTER(Transform, IntegralSamplerTransform) |
| 91 | 92 | ||
| 92 | /*! | 93 | /*! |
| 93 | * \ingroup transforms | 94 | * \ingroup transforms |