Commit 9f4f6f0ab8940b879da5407c06ab682681204a48

Authored by Josh Klontz
1 parent f1cfe8e8

removed plugins not supported by opencv4

openbr/plugins/classification/forest.cpp deleted
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 <openbr/plugins/openbr_internal.h>
18   -#include <openbr/core/opencvutils.h>
19   -
20   -using namespace cv;
21   -
22   -namespace br
23   -{
24   -
25   -/*!
26   - * \ingroup transforms
27   - * \brief Wraps OpenCV's random trees framework
28   - * \author Scott Klum \cite sklum
29   - * \br_link http://docs.opencv.org/modules/ml/doc/random_trees.html
30   - * \br_property bool classification If true the labels are expected to be categorical. Otherwise they are expected to be numerical. Default is true.
31   - * \br_property float splitPercentage Used to calculate the minimum number of samples per split in a random tree. The minimum number of samples is calculated as the number of samples x splitPercentage. Default is 0.01.
32   - * \br_property int maxDepth The maximum depth of each decision tree. Default is std::numeric_limits<int>::max() and typically should be set by the user.
33   - * \br_property int maxTrees The maximum number of trees in the forest. Default is 10.
34   - * \br_property float forestAccuracy A sufficient accuracy for the forest for training to terminate. Used if termCrit is EPS or Both. Default is 0.1.
35   - * \br_property bool returnConfidence If both classification and returnConfidence are use a fuzzy class label as the output of the forest. Default is true.
36   - * \br_property bool overwriteMat If true set dst to be a 1x1 Mat with the forest response as its value. Otherwise append the forest response to metadata using outputVariable as a key. Default is true.
37   - * \br_property QString inputVariable The metadata key for each templates label. Default is "Label".
38   - * \br_property QString outputVariable The metadata key for the forest response if overwriteMat is false. Default is "".
39   - * \br_property bool weight If true and classification is true the random forest will use prior accuracies. Default is false.
40   - * \br_property enum termCrit Termination criteria for training the random forest. Options are Iter, EPS and Both. Iter terminates when the maximum number of trees is reached. EPS terminates when forestAccuracy is met. Both terminates when either is true. Default is Iter.
41   - */
42   -class ForestTransform : public Transform
43   -{
44   - Q_OBJECT
45   -
46   - void init()
47   - {
48   - forest = ml::RTrees::create();
49   -
50   - if (outputVariable.isEmpty())
51   - outputVariable = inputVariable;
52   - }
53   -
54   - void train(const TemplateList &data)
55   - {
56   - trainForest(data);
57   - }
58   -
59   - void project(const Template &src, Template &dst) const
60   - {
61   - dst = src;
62   -
63   - float response;
64   - if (classification && returnConfidence) {
65   - // Fuzzy class label
66   - response = forest.predict_prob(src.m().reshape(1,1));
67   - } else {
68   - response = forest.predict(src.m().reshape(1,1));
69   - }
70   -
71   - if (overwriteMat) {
72   - dst.m() = Mat(1, 1, CV_32F);
73   - dst.m().at<float>(0, 0) = response;
74   - } else {
75   - dst.file.set(outputVariable, response);
76   - }
77   - }
78   -
79   - void load(QDataStream &stream)
80   - {
81   - OpenCVUtils::loadModel(forest,stream);
82   - }
83   -
84   - void store(QDataStream &stream) const
85   - {
86   - OpenCVUtils::storeModel(forest,stream);
87   - }
88   -
89   -protected:
90   - Q_ENUMS(TerminationCriteria)
91   - Q_PROPERTY(bool classification READ get_classification WRITE set_classification RESET reset_classification STORED false)
92   - Q_PROPERTY(float splitPercentage READ get_splitPercentage WRITE set_splitPercentage RESET reset_splitPercentage STORED false)
93   - Q_PROPERTY(int maxDepth READ get_maxDepth WRITE set_maxDepth RESET reset_maxDepth STORED false)
94   - Q_PROPERTY(int maxTrees READ get_maxTrees WRITE set_maxTrees RESET reset_maxTrees STORED false)
95   - Q_PROPERTY(float forestAccuracy READ get_forestAccuracy WRITE set_forestAccuracy RESET reset_forestAccuracy STORED false)
96   - Q_PROPERTY(bool returnConfidence READ get_returnConfidence WRITE set_returnConfidence RESET reset_returnConfidence STORED false)
97   - Q_PROPERTY(bool overwriteMat READ get_overwriteMat WRITE set_overwriteMat RESET reset_overwriteMat STORED false)
98   - Q_PROPERTY(QString inputVariable READ get_inputVariable WRITE set_inputVariable RESET reset_inputVariable STORED false)
99   - Q_PROPERTY(QString outputVariable READ get_outputVariable WRITE set_outputVariable RESET reset_outputVariable STORED false)
100   - Q_PROPERTY(bool weight READ get_weight WRITE set_weight RESET reset_weight STORED false)
101   - Q_PROPERTY(TerminationCriteria termCrit READ get_termCrit WRITE set_termCrit RESET reset_termCrit STORED false)
102   -
103   -public:
104   - enum TerminationCriteria { Iter = TermCriteria::ITER,
105   - EPS = TermCriteria::EPS,
106   - Both = TermCriteria::EPS | TermCriteria::ITER};
107   -
108   -protected:
109   - BR_PROPERTY(bool, classification, true)
110   - BR_PROPERTY(float, splitPercentage, .01)
111   - BR_PROPERTY(int, maxDepth, std::numeric_limits<int>::max())
112   - BR_PROPERTY(int, maxTrees, 10)
113   - BR_PROPERTY(float, forestAccuracy, .1)
114   - BR_PROPERTY(bool, returnConfidence, true)
115   - BR_PROPERTY(bool, overwriteMat, true)
116   - BR_PROPERTY(QString, inputVariable, "Label")
117   - BR_PROPERTY(QString, outputVariable, "")
118   - BR_PROPERTY(bool, weight, false)
119   - BR_PROPERTY(TerminationCriteria, termCrit, Iter)
120   -
121   - Ptr<ml::RTrees> forest;
122   -
123   - void trainForest(const TemplateList &data)
124   - {
125   - Mat samples = OpenCVUtils::toMat(data.data());
126   - Mat labels = OpenCVUtils::toMat(File::get<float>(data, inputVariable));
127   -
128   - Mat types = Mat(samples.cols + 1, 1, CV_8U);
129   - types.setTo(Scalar(ml::VAR_NUMERICAL));
130   -
131   - if (classification) {
132   - types.at<char>(samples.cols, 0) = ml::VAR_CATEGORICAL;
133   - } else {
134   - types.at<char>(samples.cols, 0) = ml::VAR_NUMERICAL;
135   - }
136   -
137   - forest->setMaxDepth(maxDepth);
138   - forest->setMinSampleCount(data.size() * splitPercentage);
139   - forest->setRegressionAccuracy(0);
140   - forest->setUseSurrogates(false);
141   - forest->setMaxCategories(2);
142   - forest->setCalculateVarImportance(false);
143   - forest->setActiveVarCount(0);
144   - forest->setTermCriteria(TermCriteria(termCrit, 1000, forestAccuracy));
145   -
146   - bool usePrior = classification && weight;
147   - if (usePrior) {
148   - int nonZero = countNonZero(labels);
149   -
150   - cv::Mat priors(1, 2, CV_32FC1);
151   - priors.at<float>(0, 0) = 1;
152   - priors.at<float>(0, 1) = (float)(samples.rows-nonZero)/nonZero;
153   -
154   - forest->setPriors(priors);
155   - }
156   -
157   - forest->train(ml::TrainData::create(samples, ml::ROW_SAMPLE, labels, noArray(), noArray(), noArray(), types));
158   -
159   - if (Globals->verbose) {
160   - qDebug() << "Number of trees:" << forest->getRoots().size();
161   -
162   - if (classification) {
163   - QTime timer;
164   - timer.start();
165   - int correctClassification = 0;
166   - float regressionError = 0;
167   - for (int i=0; i<samples.rows; i++) {
168   - float prediction = forest->predict(samples.row(i), noArray(), ml::StatModel::RAW_OUTPUT);
169   - float label = forest->predict(samples.row(i);
170   - if (label == labels.at<float>(i,0)) {
171   - correctClassification++;
172   - }
173   - regressionError += fabs(prediction-labels.at<float>(i,0));
174   - }
175   -
176   - qDebug("Time to classify %d samples: %d ms\n \
177   - Classification Accuracy: %f\n \
178   - MAE: %f\n \
179   - Sample dimensionality: %d",
180   - samples.rows,timer.elapsed(),(float)correctClassification/samples.rows,regressionError/samples.rows,samples.cols);
181   - }
182   - }
183   - }
184   -};
185   -
186   -BR_REGISTER(Transform, ForestTransform)
187   -
188   -/*!
189   - * \ingroup transforms
190   - * \brief Wraps OpenCV's random trees framework to induce features
191   - * \author Scott Klum \cite sklum
192   - * \br_link https://lirias.kuleuven.be/bitstream/123456789/316661/1/icdm11-camready.pdf
193   - * \br_property bool useRegressionValue SCOTT FILL ME IN.
194   - */
195   -class ForestInductionTransform : public ForestTransform
196   -{
197   - Q_OBJECT
198   - Q_PROPERTY(bool useRegressionValue READ get_useRegressionValue WRITE set_useRegressionValue RESET reset_useRegressionValue STORED false)
199   - BR_PROPERTY(bool, useRegressionValue, false)
200   -
201   - int totalSize;
202   - QList< QList<const CvDTreeNode*> > nodes;
203   -
204   - void fillNodes()
205   - {
206   - for (int i=0; i<forest.get_tree_count(); i++) {
207   - nodes.append(QList<const CvDTreeNode*>());
208   - const CvDTreeNode* node = forest.get_tree(i)->get_root();
209   -
210   - // traverse the tree and save all the nodes in depth-first order
211   - for(;;)
212   - {
213   - CvDTreeNode* parent;
214   - for(;;)
215   - {
216   - if( !node->left )
217   - break;
218   - node = node->left;
219   - }
220   -
221   - nodes.last().append(node);
222   -
223   - for( parent = node->parent; parent && parent->right == node;
224   - node = parent, parent = parent->parent )
225   - ;
226   -
227   - if( !parent )
228   - break;
229   -
230   - node = parent->right;
231   - }
232   -
233   - totalSize += nodes.last().size();
234   - }
235   - }
236   -
237   - void train(const TemplateList &data)
238   - {
239   - trainForest(data);
240   - if (!useRegressionValue) fillNodes();
241   - }
242   -
243   - void project(const Template &src, Template &dst) const
244   - {
245   - dst = src;
246   -
247   - Mat responses;
248   -
249   - if (useRegressionValue) {
250   - responses = Mat::zeros(forest.get_tree_count(),1,CV_32F);
251   - for (int i=0; i<forest.get_tree_count(); i++) {
252   - responses.at<float>(i,0) = forest.get_tree(i)->predict(src.m().reshape(1,1))->value;
253   - }
254   - } else {
255   - responses = Mat::zeros(totalSize,1,CV_32F);
256   - int offset = 0;
257   - for (int i=0; i<nodes.size(); i++) {
258   - int index = nodes[i].indexOf(forest.get_tree(i)->predict(src.m().reshape(1,1)));
259   - responses.at<float>(offset+index,0) = 1;
260   - offset += nodes[i].size();
261   - }
262   - }
263   -
264   - dst.m() = responses;
265   - }
266   -
267   - void load(QDataStream &stream)
268   - {
269   - OpenCVUtils::loadModel(forest,stream);
270   - if (!useRegressionValue) fillNodes();
271   -
272   - }
273   -
274   - void store(QDataStream &stream) const
275   - {
276   - OpenCVUtils::storeModel(forest,stream);
277   - }
278   -};
279   -
280   -BR_REGISTER(Transform, ForestInductionTransform)
281   -
282   -} // namespace br
283   -
284   -#include "classification/forest.moc"
openbr/plugins/cmake/opencv4.cmake deleted
1   -set(BR_EXCLUDED_PLUGINS ${BR_EXCLUDED_PLUGINS} plugins/classification/forest.cpp
2   - plugins/imgproc/custom_sift.cpp
3   - plugins/imgproc/keypointdescriptor.cpp
4   - plugins/metadata/keypointdetector.cpp)
openbr/plugins/imgproc/custom_sift.cpp deleted
1   -/*M///////////////////////////////////////////////////////////////////////////////////////
2   -//
3   -// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4   -//
5   -// By downloading, copying, installing or using the software you agree to this license.
6   -// If you do not agree to this license, do not download, install,
7   -// copy or use the software.
8   -//
9   -//
10   -// License Agreement
11   -// For Open Source Computer Vision Library
12   -//
13   -// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
14   -// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
15   -// Third party copyrights are property of their respective owners.
16   -//
17   -// Redistribution and use in source and binary forms, with or without modification,
18   -// are permitted provided that the following conditions are met:
19   -//
20   -// * Redistribution's of source code must retain the above copyright notice,
21   -// this list of conditions and the following disclaimer.
22   -//
23   -// * Redistribution's in binary form must reproduce the above copyright notice,
24   -// this list of conditions and the following disclaimer in the documentation
25   -// and/or other materials provided with the distribution.
26   -//
27   -// * The name of the copyright holders may not be used to endorse or promote products
28   -// derived from this software without specific prior written permission.
29   -//
30   -// This software is provided by the copyright holders and contributors "as is" and
31   -// any express or implied warranties, including, but not limited to, the implied
32   -// warranties of merchantability and fitness for a particular purpose are disclaimed.
33   -// In no event shall the Intel Corporation or contributors be liable for any direct,
34   -// indirect, incidental, special, exemplary, or consequential damages
35   -// (including, but not limited to, procurement of substitute goods or services;
36   -// loss of use, data, or profits; or business interruption) however caused
37   -// and on any theory of liability, whether in contract, strict liability,
38   -// or tort (including negligence or otherwise) arising in any way out of
39   -// the use of this software, even if advised of the possibility of such damage.
40   -//
41   -//M*/
42   -
43   -/**********************************************************************************************\
44   - Implementation of SIFT is based on the code from http://blogs.oregonstate.edu/hess/code/sift/
45   - Below is the original copyright.
46   -
47   -// Copyright (c) 2006-2010, Rob Hess <hess@eecs.oregonstate.edu>
48   -// All rights reserved.
49   -
50   -// The following patent has been issued for methods embodied in this
51   -// software: "Method and apparatus for identifying scale invariant features
52   -// in an image and use of same for locating an object in an image," David
53   -// G. Lowe, US Patent 6,711,293 (March 23, 2004). Provisional application
54   -// filed March 8, 1999. Asignee: The University of British Columbia. For
55   -// further details, contact David Lowe (lowe@cs.ubc.ca) or the
56   -// University-Industry Liaison Office of the University of British
57   -// Columbia.
58   -
59   -// Note that restrictions imposed by this patent (and possibly others)
60   -// exist independently of and may be in conflict with the freedoms granted
61   -// in this license, which refers to copyright of the program, not patents
62   -// for any methods that it implements. Both copyright and patent law must
63   -// be obeyed to legally use and redistribute this program and it is not the
64   -// purpose of this license to induce you to infringe any patents or other
65   -// property right claims or to contest validity of any such claims. If you
66   -// redistribute or use the program, then this license merely protects you
67   -// from committing copyright infringement. It does not protect you from
68   -// committing patent infringement. So, before you do anything with this
69   -// program, make sure that you have permission to do so not merely in terms
70   -// of copyright, but also in terms of patent law.
71   -
72   -// Please note that this license is not to be understood as a guarantee
73   -// either. If you use the program according to this license, but in
74   -// conflict with patent law, it does not mean that the licensor will refund
75   -// you for any losses that you incur if you are sued for your patent
76   -// infringement.
77   -
78   -// Redistribution and use in source and binary forms, with or without
79   -// modification, are permitted provided that the following conditions are
80   -// met:
81   -// * Redistributions of source code must retain the above copyright and
82   -// patent notices, this list of conditions and the following
83   -// disclaimer.
84   -// * Redistributions in binary form must reproduce the above copyright
85   -// notice, this list of conditions and the following disclaimer in
86   -// the documentation and/or other materials provided with the
87   -// distribution.
88   -// * Neither the name of Oregon State University nor the names of its
89   -// contributors may be used to endorse or promote products derived
90   -// from this software without specific prior written permission.
91   -
92   -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
93   -// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
94   -// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
95   -// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
96   -// HOLDER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
97   -// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
98   -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
99   -// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
100   -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
101   -// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
102   -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103   -\**********************************************************************************************/
104   -
105   -#include <iostream>
106   -#include <stdarg.h>
107   -#include <opencv2/imgproc/imgproc.hpp>
108   -#include <opencv2/nonfree/nonfree.hpp>
109   -
110   -using namespace cv;
111   -
112   -/******************************* Defs and macros *****************************/
113   -
114   -// determines the size of a single descriptor orientation histogram
115   -static const float SIFT_DESCR_SCL_FCTR = 3.f;
116   -
117   -// threshold on magnitude of elements of descriptor vector
118   -static const float SIFT_DESCR_MAG_THR = 0.2f;
119   -
120   -// factor used to convert floating-point descriptor to unsigned char
121   -static const float SIFT_INT_DESCR_FCTR = 512.f;
122   -
123   -// intermediate type used for DoG pyramids
124   -typedef short sift_wt;
125   -static const int SIFT_FIXPT_SCALE = 48;
126   -
127   -static inline void unpackOctave(const KeyPoint &kpt, int &octave, int &layer, float &scale)
128   -{
129   - octave = kpt.octave & 255;
130   - layer = (kpt.octave >> 8) & 255;
131   - octave = octave < 128 ? octave : (-128 | octave);
132   - scale = octave >= 0 ? 1.f/(1 << octave) : (float)(1 << -octave);
133   -}
134   -
135   -static Mat createInitialImage( const Mat& img, bool doubleImageSize, float sigma)
136   -{
137   - Mat gray, gray_fpt;
138   - if( img.channels() == 3 || img.channels() == 4 )
139   - cvtColor(img, gray, COLOR_BGR2GRAY);
140   - else
141   - img.copyTo(gray);
142   - gray.convertTo(gray_fpt, DataType<sift_wt>::type, SIFT_FIXPT_SCALE, 0);
143   -
144   - float sig_diff;
145   -
146   - if( doubleImageSize )
147   - {
148   - sig_diff = sqrtf( std::max(sigma * sigma, 0.01f) );
149   - Mat dbl;
150   - resize(gray_fpt, dbl, Size(gray.cols*2, gray.rows*2), 0, 0, INTER_LINEAR);
151   - GaussianBlur(dbl, dbl, Size(), sig_diff, sig_diff);
152   - return dbl;
153   - }
154   - else
155   - {
156   - sig_diff = sqrtf( std::max(sigma * sigma, 0.01f) );
157   - GaussianBlur(gray_fpt, gray_fpt, Size(), sig_diff, sig_diff);
158   - return gray_fpt;
159   - }
160   -}
161   -
162   -
163   -static void buildGaussianPyramid( const Mat& base, vector<Mat>& pyr, int nOctaves, int nOctaveLayers, double sigma )
164   -{
165   - vector<double> sig(nOctaveLayers + 3);
166   - pyr.resize(nOctaves*(nOctaveLayers + 3));
167   -
168   - // precompute Gaussian sigmas using the following formula:
169   - // \sigma_{total}^2 = \sigma_{i}^2 + \sigma_{i-1}^2
170   - sig[0] = sigma;
171   - double k = pow( 2., 1. / nOctaveLayers );
172   - for( int i = 1; i < nOctaveLayers + 3; i++ )
173   - {
174   - double sig_prev = pow(k, (double)(i-1))*sigma;
175   - double sig_total = sig_prev*k;
176   - sig[i] = std::sqrt(sig_total*sig_total - sig_prev*sig_prev);
177   - }
178   -
179   - for( int o = 0; o < nOctaves; o++ )
180   - {
181   - for( int i = 0; i < nOctaveLayers + 3; i++ )
182   - {
183   - Mat& dst = pyr[o*(nOctaveLayers + 3) + i];
184   - if( o == 0 && i == 0 )
185   - dst = base;
186   - // base of new octave is halved image from end of previous octave
187   - else if( i == 0 )
188   - {
189   - const Mat& src = pyr[(o-1)*(nOctaveLayers + 3) + nOctaveLayers];
190   - resize(src, dst, Size(src.cols/2, src.rows/2),
191   - 0, 0, INTER_NEAREST);
192   - }
193   - else
194   - {
195   - const Mat& src = pyr[o*(nOctaveLayers + 3) + i-1];
196   - GaussianBlur(src, dst, Size(), sig[i], sig[i]);
197   - }
198   - }
199   - }
200   -}
201   -
202   -
203   -static void buildDoGPyramid( const vector<Mat>& gpyr, vector<Mat>& dogpyr, int nOctaveLayers )
204   -{
205   - int nOctaves = (int)gpyr.size()/(nOctaveLayers + 3);
206   - dogpyr.resize( nOctaves*(nOctaveLayers + 2) );
207   -
208   - for( int o = 0; o < nOctaves; o++ )
209   - {
210   - for( int i = 0; i < nOctaveLayers + 2; i++ )
211   - {
212   - const Mat& src1 = gpyr[o*(nOctaveLayers + 3) + i];
213   - const Mat& src2 = gpyr[o*(nOctaveLayers + 3) + i + 1];
214   - Mat& dst = dogpyr[o*(nOctaveLayers + 2) + i];
215   - subtract(src2, src1, dst, noArray(), DataType<sift_wt>::type);
216   - }
217   - }
218   -}
219   -
220   -static void calcSIFTDescriptor( const Mat& img, Point2f ptf, float ori, float scl,
221   - int d, int n, float* dst )
222   -{
223   - Point pt(cvRound(ptf.x), cvRound(ptf.y));
224   - float cos_t = cosf(ori*(float)(CV_PI/180));
225   - float sin_t = sinf(ori*(float)(CV_PI/180));
226   - float bins_per_rad = n / 360.f;
227   - float exp_scale = -1.f/(d * d * 0.5f);
228   - float hist_width = SIFT_DESCR_SCL_FCTR * scl;
229   - int radius = cvRound(hist_width * 1.4142135623730951f * (d + 1) * 0.5f);
230   - // Clip the radius to the diagonal of the image to avoid autobuffer too large exception
231   - radius = std::min(radius, (int) sqrt((double) img.cols*img.cols + img.rows*img.rows));
232   - cos_t /= hist_width;
233   - sin_t /= hist_width;
234   -
235   - int i, j, k, len = (radius*2+1)*(radius*2+1), histlen = (d+2)*(d+2)*(n+2);
236   - int rows = img.rows, cols = img.cols;
237   -
238   - AutoBuffer<float> buf(len*6 + histlen);
239   - float *X = buf, *Y = X + len, *Mag = Y, *Ori = Mag + len, *W = Ori + len;
240   - float *RBin = W + len, *CBin = RBin + len, *hist = CBin + len;
241   -
242   - for( i = 0; i < d+2; i++ )
243   - {
244   - for( j = 0; j < d+2; j++ )
245   - for( k = 0; k < n+2; k++ )
246   - hist[(i*(d+2) + j)*(n+2) + k] = 0.;
247   - }
248   -
249   - for( i = -radius, k = 0; i <= radius; i++ )
250   - for( j = -radius; j <= radius; j++ )
251   - {
252   - // Calculate sample's histogram array coords rotated relative to ori.
253   - // Subtract 0.5 so samples that fall e.g. in the center of row 1 (i.e.
254   - // r_rot = 1.5) have full weight placed in row 1 after interpolation.
255   - float c_rot = j * cos_t - i * sin_t;
256   - float r_rot = j * sin_t + i * cos_t;
257   - float rbin = r_rot + d/2 - 0.5f;
258   - float cbin = c_rot + d/2 - 0.5f;
259   - int r = pt.y + i, c = pt.x + j;
260   -
261   - if( rbin > -1 && rbin < d && cbin > -1 && cbin < d &&
262   - r > 0 && r < rows - 1 && c > 0 && c < cols - 1 )
263   - {
264   - float dx = (float)(img.at<sift_wt>(r, c+1) - img.at<sift_wt>(r, c-1));
265   - float dy = (float)(img.at<sift_wt>(r-1, c) - img.at<sift_wt>(r+1, c));
266   - X[k] = dx; Y[k] = dy; RBin[k] = rbin; CBin[k] = cbin;
267   - W[k] = (c_rot * c_rot + r_rot * r_rot)*exp_scale;
268   - k++;
269   - }
270   - }
271   -
272   - len = k;
273   - fastAtan2(Y, X, Ori, len, true);
274   - magnitude(X, Y, Mag, len);
275   - exp(W, W, len);
276   -
277   - for( k = 0; k < len; k++ )
278   - {
279   - float rbin = RBin[k], cbin = CBin[k];
280   - float obin = (Ori[k] - ori)*bins_per_rad;
281   - float mag = Mag[k]*W[k];
282   -
283   - int r0 = cvFloor( rbin );
284   - int c0 = cvFloor( cbin );
285   - int o0 = cvFloor( obin );
286   - rbin -= r0;
287   - cbin -= c0;
288   - obin -= o0;
289   -
290   - if( o0 < 0 )
291   - o0 += n;
292   - if( o0 >= n )
293   - o0 -= n;
294   -
295   - // histogram update using tri-linear interpolation
296   - float v_r1 = mag*rbin, v_r0 = mag - v_r1;
297   - float v_rc11 = v_r1*cbin, v_rc10 = v_r1 - v_rc11;
298   - float v_rc01 = v_r0*cbin, v_rc00 = v_r0 - v_rc01;
299   - float v_rco111 = v_rc11*obin, v_rco110 = v_rc11 - v_rco111;
300   - float v_rco101 = v_rc10*obin, v_rco100 = v_rc10 - v_rco101;
301   - float v_rco011 = v_rc01*obin, v_rco010 = v_rc01 - v_rco011;
302   - float v_rco001 = v_rc00*obin, v_rco000 = v_rc00 - v_rco001;
303   -
304   - int idx = ((r0+1)*(d+2) + c0+1)*(n+2) + o0;
305   - hist[idx] += v_rco000;
306   - hist[idx+1] += v_rco001;
307   - hist[idx+(n+2)] += v_rco010;
308   - hist[idx+(n+3)] += v_rco011;
309   - hist[idx+(d+2)*(n+2)] += v_rco100;
310   - hist[idx+(d+2)*(n+2)+1] += v_rco101;
311   - hist[idx+(d+3)*(n+2)] += v_rco110;
312   - hist[idx+(d+3)*(n+2)+1] += v_rco111;
313   - }
314   -
315   - // finalize histogram, since the orientation histograms are circular
316   - for( i = 0; i < d; i++ )
317   - for( j = 0; j < d; j++ )
318   - {
319   - int idx = ((i+1)*(d+2) + (j+1))*(n+2);
320   - hist[idx] += hist[idx+n];
321   - hist[idx+1] += hist[idx+n+1];
322   - for( k = 0; k < n; k++ )
323   - dst[(i*d + j)*n + k] = hist[idx+k];
324   - }
325   - // copy histogram to the descriptor,
326   - // apply hysteresis thresholding
327   - // and scale the result, so that it can be easily converted
328   - // to byte array
329   - float nrm2 = 0;
330   - len = d*d*n;
331   - for( k = 0; k < len; k++ )
332   - nrm2 += dst[k]*dst[k];
333   - float thr = std::sqrt(nrm2)*SIFT_DESCR_MAG_THR;
334   - for( i = 0, nrm2 = 0; i < k; i++ )
335   - {
336   - float val = std::min(dst[i], thr);
337   - dst[i] = val;
338   - nrm2 += val*val;
339   - }
340   - nrm2 = SIFT_INT_DESCR_FCTR/std::max(std::sqrt(nrm2), FLT_EPSILON);
341   -
342   -#if 1
343   - for( k = 0; k < len; k++ )
344   - {
345   - dst[k] = saturate_cast<uchar>(dst[k]*nrm2);
346   - }
347   -#else
348   - float nrm1 = 0;
349   - for( k = 0; k < len; k++ )
350   - {
351   - dst[k] *= nrm2;
352   - nrm1 += dst[k];
353   - }
354   - nrm1 = 1.f/std::max(nrm1, FLT_EPSILON);
355   - for( k = 0; k < len; k++ )
356   - {
357   - dst[k] = std::sqrt(dst[k] * nrm1);//saturate_cast<uchar>(std::sqrt(dst[k] * nrm1)*SIFT_INT_DESCR_FCTR);
358   - }
359   -#endif
360   -}
361   -
362   -static void calcDescriptors(const vector<Mat>& gpyr, const vector<KeyPoint>& keypoints,
363   - Mat& descriptors, int nOctaveLayers, int firstOctave, int n /* bins */, int d /* width */)
364   -{
365   - for( size_t i = 0; i < keypoints.size(); i++ )
366   - {
367   - KeyPoint kpt = keypoints[i];
368   - int octave, layer;
369   - float scale;
370   - unpackOctave(kpt, octave, layer, scale);
371   - CV_Assert(octave >= firstOctave && layer <= nOctaveLayers+2);
372   - float size=kpt.size*scale;
373   - Point2f ptf(kpt.pt.x*scale, kpt.pt.y*scale);
374   - const Mat& img = gpyr[(octave - firstOctave)*(nOctaveLayers + 3) + layer];
375   -
376   - float angle = 360.f - kpt.angle;
377   - if(std::abs(angle - 360.f) < FLT_EPSILON)
378   - angle = 0.f;
379   - calcSIFTDescriptor(img, ptf, angle, size*0.5f, d, n, descriptors.ptr<float>((int)i));
380   - }
381   -}
382   -
383   -static int descriptorSize(int bins, int width)
384   -{
385   - return width*width*bins;
386   -}
387   -
388   -static void extractSIFT(const Mat &image, vector<KeyPoint> &keypoints, Mat &descriptors, int nOctaveLayers, double sigma, int bins, int width)
389   -{
390   - if( image.empty() || image.depth() != CV_8U )
391   - CV_Error( CV_StsBadArg, "image is empty or has incorrect depth (!=CV_8U)" );
392   -
393   - int firstOctave = 0, actualNOctaves = 0, actualNLayers = 0, maxOctave = INT_MIN;
394   - for (size_t i=0; i<keypoints.size(); i++) {
395   - int octave, layer;
396   - float scale;
397   - unpackOctave(keypoints[i], octave, layer, scale);
398   - firstOctave = std::min(firstOctave, octave);
399   - maxOctave = std::max(maxOctave, octave);
400   - actualNLayers = std::max(actualNLayers, layer-2);
401   - }
402   -
403   - firstOctave = std::min(firstOctave, 0);
404   - CV_Assert( firstOctave >= -1 && actualNLayers <= nOctaveLayers );
405   - actualNOctaves = maxOctave - firstOctave + 1;
406   -
407   - const Mat base = createInitialImage(image, firstOctave < 0, (float)sigma);
408   - const int nOctaves = actualNOctaves > 0 ? actualNOctaves : cvRound(log( (double)std::min( base.cols, base.rows ) ) / log(2.) - 2) - firstOctave;
409   -
410   - vector<Mat> gpyr, dogpyr;
411   - buildGaussianPyramid(base, gpyr, nOctaves, nOctaveLayers, sigma);
412   - buildDoGPyramid(gpyr, dogpyr, nOctaveLayers);
413   -
414   - descriptors.create((int)keypoints.size(), descriptorSize(bins, width), CV_32F);
415   - calcDescriptors(gpyr, keypoints, descriptors, nOctaveLayers, firstOctave, bins, width);
416   -}
417   -
418   -#include "openbr/plugins/openbr_internal.h"
419   -
420   -namespace br
421   -{
422   -
423   -/*!
424   - * \ingroup transforms
425   - * \brief Specialize wrapper OpenCV SIFT wrapper
426   - * \author Josh Klontz \cite jklontz
427   - */
428   -class CustomSIFTTransform : public UntrainableTransform
429   -{
430   - Q_OBJECT
431   - Q_PROPERTY(int size READ get_size WRITE set_size RESET reset_size STORED false)
432   - Q_PROPERTY(QList<int> sizes READ get_sizes WRITE set_sizes RESET reset_sizes STORED false)
433   - Q_PROPERTY(int bins READ get_bins WRITE set_bins RESET reset_bins STORED false)
434   - Q_PROPERTY(int width READ get_width WRITE set_width RESET reset_width STORED false)
435   - BR_PROPERTY(int, size, 1)
436   - BR_PROPERTY(QList<int>, sizes, QList<int>())
437   - BR_PROPERTY(int, bins, 8)
438   - BR_PROPERTY(int, width, 4)
439   -
440   - void init()
441   - {
442   - if (sizes.empty())
443   - sizes.append(size);
444   - }
445   -
446   - void project(const Template &src, Template &dst) const
447   - {
448   - std::vector<KeyPoint> keyPoints;
449   - foreach (const QPointF &val, src.file.points())
450   - foreach (const int sz, sizes)
451   - keyPoints.push_back(KeyPoint(val.x(), val.y(), sz));
452   -
453   - Mat m;
454   - extractSIFT(src, keyPoints, m, 3, 1.6f, bins, width);
455   - m.setTo(0, m<0); // SIFT returns large negative values when it goes off the edge of the image.
456   - dst += m;
457   - }
458   -};
459   -
460   -BR_REGISTER(Transform, CustomSIFTTransform)
461   -
462   -}
463   -
464   -#include "custom_sift.moc"
openbr/plugins/imgproc/keypointdescriptor.cpp deleted
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/features2d/features2d.hpp>
18   -
19   -#include <openbr/plugins/openbr_internal.h>
20   -
21   -using namespace cv;
22   -
23   -namespace br
24   -{
25   -
26   -/*!
27   - * \ingroup transforms
28   - * \brief Wraps OpenCV Key Point Descriptor
29   - * \br_link http://docs.opencv.org/modules/features2d/doc/common_interfaces_of_feature_detectors.html
30   - * \author Josh Klontz \cite jklontz
31   - */
32   -class KeyPointDescriptorTransform : public UntrainableTransform
33   -{
34   - Q_OBJECT
35   - Q_PROPERTY(QString descriptor READ get_descriptor WRITE set_descriptor RESET reset_descriptor STORED false)
36   - Q_PROPERTY(int size READ get_size WRITE set_size RESET reset_size STORED false)
37   - BR_PROPERTY(QString, descriptor, "SIFT")
38   - BR_PROPERTY(int, size, -1)
39   -
40   - Ptr<DescriptorExtractor> descriptorExtractor;
41   -
42   - void init()
43   - {
44   - descriptorExtractor = DescriptorExtractor::create(descriptor.toStdString());
45   - if (descriptorExtractor.empty())
46   - qFatal("Failed to create DescriptorExtractor: %s", qPrintable(descriptor));
47   - }
48   -
49   - void project(const Template &src, Template &dst) const
50   - {
51   - std::vector<KeyPoint> keyPoints;
52   - if (size == -1)
53   - foreach (const QRectF &ROI, src.file.rects())
54   - keyPoints.push_back(KeyPoint(ROI.x()+ROI.width()/2, ROI.y()+ROI.height()/2, (ROI.width() + ROI.height())/2));
55   - else
56   - foreach (const QPointF &landmark, src.file.points())
57   - keyPoints.push_back(KeyPoint(landmark.x(), landmark.y(), size));
58   - if (keyPoints.empty()) return;
59   - descriptorExtractor->compute(src, keyPoints, dst);
60   - }
61   -};
62   -
63   -BR_REGISTER(Transform, KeyPointDescriptorTransform)
64   -
65   -} // namespace br
66   -
67   -#include "imgproc/keypointdescriptor.moc"
openbr/plugins/metadata/keypointdetector.cpp deleted
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/features2d/features2d.hpp>
18   -
19   -#include <openbr/plugins/openbr_internal.h>
20   -#include <openbr/core/opencvutils.h>
21   -
22   -using namespace cv;
23   -
24   -namespace br
25   -{
26   -
27   -/*!
28   - * \ingroup transforms
29   - * \brief Wraps OpenCV Key Point Detector
30   - * \br_link http://docs.opencv.org/modules/features2d/doc/common_interfaces_of_feature_detectors.html
31   - * \author Josh Klontz \cite jklontz
32   - */
33   -class KeyPointDetectorTransform : public UntrainableTransform
34   -{
35   - Q_OBJECT
36   - Q_PROPERTY(QString detector READ get_detector WRITE set_detector RESET reset_detector STORED false)
37   - BR_PROPERTY(QString, detector, "SIFT")
38   -
39   - Ptr<FeatureDetector> featureDetector;
40   -
41   - void init()
42   - {
43   - featureDetector = FeatureDetector::create(detector.toStdString());
44   - if (featureDetector.empty())
45   - qFatal("Failed to create KeyPointDetector: %s", qPrintable(detector));
46   - }
47   -
48   - void project(const Template &src, Template &dst) const
49   - {
50   - dst = src;
51   -
52   - std::vector<KeyPoint> keyPoints;
53   - try {
54   - featureDetector->detect(src, keyPoints);
55   - } catch (...) {
56   - qWarning("Key point detection failed for file %s", qPrintable(src.file.name));
57   - dst.file.fte = true;
58   - }
59   -
60   - QList<Rect> rects;
61   - foreach (const KeyPoint &keyPoint, keyPoints)
62   - rects.append(Rect(keyPoint.pt.x-keyPoint.size/2, keyPoint.pt.y-keyPoint.size/2, keyPoint.size, keyPoint.size));
63   - dst.file.setRects(OpenCVUtils::fromRects(rects));
64   - }
65   -};
66   -
67   -BR_REGISTER(Transform, KeyPointDetectorTransform)
68   -
69   -} // namespace br
70   -
71   -#include "metadata/keypointdetector.moc"