PARP Research Group University of Murcia, Spain


examples/OpenCV/siftDetector/siftDetector.cpp

Go to the documentation of this file.
00001 /*
00002  *      Copyright (C) 2007, 2008, 2009. PARP Research Group.
00003  *      <http://perception.inf.um.es>
00004  *      University of Murcia, Spain.
00005  *
00006  *      This file is part of the QVision library.
00007  *
00008  *      QVision is free software: you can redistribute it and/or modify
00009  *      it under the terms of the GNU Lesser General Public License as
00010  *      published by the Free Software Foundation, version 3 of the License.
00011  *
00012  *      QVision is distributed in the hope that it will be useful,
00013  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  *      GNU Lesser General Public License for more details.
00016  *
00017  *      You should have received a copy of the GNU Lesser General Public
00018  *      License along with QVision. If not, see <http://www.gnu.org/licenses/>.
00019  */
00020 
00040 #include <stdio.h>
00041 #include <stdlib.h>
00042 #include <iostream>
00043 #include <QDebug>
00044 
00045 #include <QVApplication>
00046 #include <QVMPlayerCameraWorker>
00047 #include <QVDefaultGUI>
00048 #include <QVImageCanvas>
00049 
00050 #include <qvipp.h>
00051 
00052 #include <sift.h>
00053 #include <imgfeatures.h>
00054 #include <utils.h>
00055 #include <highgui.h>
00056 #include <unistd.h>
00057 #include <cxcore.h>
00058 #include <cv.h>
00059 
00060 #include <QVector>
00061 #include <QList>
00062 
00063 #ifndef DOXYGEN_IGNORE_THIS
00064 
00065 // QVSIFTDescriptor
00066 // should have:
00067 //      - parameters for the ellipse
00068 //      - scale of a Lowe-style feature
00069 //      - orientation of a Lowe-style feature
00070 //      - DESCRIPTOR (array of doubles)
00071 //      - Type (Oxford or Lowe)
00078 class QVSIFTDescriptor
00079         {
00080         public:
00081                 double x, y, a, b, c, scale, orientation;
00082                 QVector<double> descriptor;
00083                 int type;
00084 
00085                 QVSIFTDescriptor(struct feature f)
00086                         {
00087                         this->x = f.x;
00088                         this->y = f.y;
00089                         this->a = f.a;
00090                         this->b = f.b;
00091                         this->c = f.c;
00092                         this->orientation = f.ori;
00093                         this->scale = f.scl;
00094                         Q_ASSERT_X(f.type == FEATURE_LOWE, "QVSIFTDescriptor", "Feature type not Lowe");
00095                         this->type = f.type;
00096                         for (int i = 0; i< FEATURE_MAX_D; i++)
00097                                 descriptor.append(f.descr[i]);
00098                         }
00099         };
00100 
00101 /*
00102 @brief Find SIFT features in an image using user-specified parameter values.  All detected features are stored in the array pointed to by \a feat.
00103 
00104 @param img the image in which to detect features
00105 @param feat a pointer to an array in which to store detected features
00106 @param intvls the number of intervals sampled per octave of scale space
00107 @param sigma the amount of Gaussian smoothing applied to each image level before building the scale space representation for an octave
00108 @param contr_thr a threshold on the value of the scale space function
00109         \f$\left|D(\hat{x})\right|\f$
00110 where \f$\hat{x}\f$ is a vector specifying feature location and scale, used to reject unstable features;  assumes pixel values in the range [0, 1]
00111 @param curv_thr threshold on a feature's ratio of principle curvatures used to reject features that are too edge-like
00112 @param img_dbl should be 1 if image doubling prior to scale space construction is desired or 0 if not
00113 @param descr_width the width, \f$n\f$, of the \f$n \times n\f$ array of orientation histograms used to compute a feature's descriptor
00114 @param descr_hist_bins the number of orientations in each of the histograms in the array used to compute a feature's descriptor
00115 @return Returns the number of keypoints stored in \a feat or -1 on failure
00116 */
00117 const QList<QVSIFTDescriptor>   getSIFTDescriptors(const QVImage<uChar, 3> &image,
00118                                 int intvls = SIFT_INTVLS, double sigma = SIFT_SIGMA, double contr_thr = SIFT_CONTR_THR,
00119                                 int curv_thr = SIFT_CURV_THR, int img_dbl = SIFT_IMG_DBL, int descr_width = SIFT_DESCR_WIDTH,
00120                                 int descr_hist_bins = SIFT_DESCR_HIST_BINS)
00121         {
00122         IplImage *imageIPL = image;
00123         
00124         struct feature * feat;
00125         const int n = _sift_features(imageIPL, &feat, intvls, sigma, contr_thr, curv_thr, img_dbl, descr_width, descr_hist_bins);
00126 
00127         QList<QVSIFTDescriptor> result;
00128         for (int i = 0; i < n; i++)
00129                 result.append(QVSIFTDescriptor(feat[i]));
00130 
00131         cvReleaseImage(&imageIPL);
00132 
00133         free(feat);
00134         return result;
00135         }
00136 
00137 class SIFTDetectorWorker: public QVWorker
00138         {
00139                 
00140         public:
00141                 SIFTDetectorWorker(QString name): QVWorker(name)
00142                         {
00143                         addProperty< QVImage<uChar,3> >("Input image", inputFlag|outputFlag);
00144                         addProperty< QList<QVPolyline> >("SIFT ellipses", outputFlag);
00145                         }
00146 
00147                 void iterate()
00148                         {
00149                         // 0. Get input image
00150                         const QVImage<uChar,3> image = getPropertyValue< QVImage<uChar,3> >("Input image");
00151                         timeFlag("Image grab");
00152 
00153                         // 1. Get SIFT descriptors
00154                         QList<QVSIFTDescriptor> descriptors = getSIFTDescriptors(image);
00155                         timeFlag("Get SIFT descriptors");
00156 
00157                         // 2. Get SIFT features as ellipses
00158                         QList<QVPolyline> SIFTEllipses;
00159                         foreach (QVSIFTDescriptor descriptor, descriptors)
00160                                 SIFTEllipses.append(    QVPolyline::ellipse(
00161                                                                         20, descriptor.x, descriptor.y,
00162                                                                         sqrt(descriptor.scale)*5,
00163                                                                         sqrt(descriptor.scale)*2.5,
00164                                                                         -descriptor.orientation)
00165                                                                         );
00166 
00167                         timeFlag("Draw SIFT descriptors");
00168 
00169                         // 3. Publish ellipses
00170                         setPropertyValue< QList<QVPolyline> >("SIFT ellipses", SIFTEllipses);
00171                         timeFlag("Publish SIFT ellipses");
00172                         }
00173         };
00174 
00175 int main(int argc, char *argv[])
00176         {
00177         QVApplication app(argc, argv,
00178                 "Example program for QVision library. Gets SIFT descriptors from image."
00179                 );
00180         
00181         QVMPlayerCameraWorker camera("Video");
00182         SIFTDetectorWorker worker("SIFT Worker");
00183         camera.linkProperty(&worker,"Input image");
00184 
00185         QVDefaultGUI interface;
00186 
00187         QVImageCanvas imageCanvas("Sift image");
00188         worker.linkProperty("Input image", imageCanvas);
00189         worker.linkProperty("SIFT ellipses", imageCanvas);
00190 
00191         return app.exec();
00192         }
00193 #endif



QVision framework. PARP research group, copyright 2007, 2008.