00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00055 #include <stdio.h>
00056 #include <stdlib.h>
00057 #include <iostream>
00058 #include <QDebug>
00059 
00060 #include <QVApplication>
00061 #include <QVVideoReaderBlock>
00062 #include <QVDefaultGUI>
00063 #include <QVImageCanvas>
00064 
00065 #include <qvipp.h>
00066 #include <qvsiftgpu.h>
00067 
00068 #ifndef DOXYGEN_IGNORE_THIS
00069 
00070 class SIFTGPUMatcher: public QVProcessingBlock
00071         {
00072         private:
00073                 QVImage<uChar, 3> referenceFrame;
00074                 QList<QVSIFTFeature> referenceFrameFeatures;
00075 
00076         public:
00077                 SIFTGPUMatcher(QString name): QVProcessingBlock(name),
00078                         referenceFrame(1,1)
00079                         {
00080                         addProperty< QVImage<uChar,3> >("Actual frame", inputFlag|outputFlag);
00081                         addProperty< QList<QPointF> >("Actual features", outputFlag);
00082                         addProperty< QList<QVPolylineF> >("Actual features orientations", outputFlag);
00083 
00084                         
00085                         addProperty< QVImage<uChar,3> >("Matching images", outputFlag);
00086                         addProperty< QList<QPointFMatching> >("Matching correspondences", outputFlag);
00087 
00088                         addTrigger("Grab reference frame");
00089                         }
00090 
00091                 
00092                 void processTrigger(const QString triggerName)
00093                         {
00094                         referenceFrame = getPropertyValue< QVImage<uChar,3> >("Actual frame");
00095                         referenceFrameFeatures = getSiftGPUFeatures(referenceFrame, CUDA_METHOD);
00096                         
00097                         }
00098 
00099                 void iterate()
00100                         {
00101                         
00102                         const QVImage<sFloat,3> actualFrame = getPropertyValue< QVImage<uChar,3> >("Actual frame");
00103                         timeFlag("Read input image");
00104 
00105                         
00106                         const QList<QVSIFTFeature> actualFrameFeatures = getSiftGPUFeatures(actualFrame, CUDA_METHOD);
00107                         timeFlag("Get SIFT features");
00108 
00109                         
00110                         QList<QPointF> points;
00111                         QList<QVPolylineF> orientations;
00112                         foreach(QVSIFTFeature feature, actualFrameFeatures)
00113                                 {
00114                                 QVPolylineF orientation;
00115                                 orientation << feature.keypoint.location();
00116                                 orientation << feature.keypoint.location() + 3.0 * ABS(feature.keypoint.scale()) * QPointF(     sin(feature.keypoint.orientation()),
00117                                                                                                                                                                                                                                         cos(feature.keypoint.orientation()));
00118                                 orientations << orientation;
00119                                 points << feature.keypoint.location();
00120                                 }
00121                         setPropertyValue< QList<QPointF> >("Actual features", points);
00122                         setPropertyValue< QList<QVPolylineF> >("Actual features orientations", orientations);
00123                         timeFlag("Show SIFT features");
00124 
00125                         if (referenceFrame.getCols() == 1 and referenceFrame.getRows() == 1)
00126                                 return;
00127 
00128                         
00129                         const QList< QPair<int, int> > matchings = matchSiftGPUFeatures(actualFrameFeatures, referenceFrameFeatures);
00130                         timeFlag("Match with reference frame");
00131 
00132                         
00133                         const QPointF offset(referenceFrame.getCols(), 0);
00134                         QList<QPointFMatching> matchingCorrespondences;
00135                         for(int i = 0; i < matchings.count(); i++)
00136                                 {
00137                                 const QPointF   sourcePoint = referenceFrameFeatures[matchings[i].second].keypoint.location(),
00138                                                                 destinationPoint = actualFrameFeatures[matchings[i].first].keypoint.location();
00139 
00140                                 matchingCorrespondences << QPointFMatching(     sourcePoint,
00141                                                                                                                         destinationPoint + offset);
00142                                 }
00143 
00144                         QVImage<uChar, 3> matchingImages = referenceFrame;
00145                         Copy(actualFrame, matchingImages, QPoint(referenceFrame.getCols(), 0));
00146                         matchingImages.resetROI();
00147 
00148                         setPropertyValue< QVImage<uChar,3> >("Matching images", matchingImages);
00149                         setPropertyValue< QList<QPointFMatching> >("Matching correspondences", matchingCorrespondences);
00150                         timeFlag("Show matchings");
00151                         }
00152         };
00153 
00154 int main(int argc, char *argv[])
00155         {
00156         QVApplication app(argc, argv,
00157                 "Example program for QVision library. Performs SIFT feature detection and matching on an input video sequence."
00158                 );
00159 
00160         SIFTGPUMatcher SIFTMatcher("SIFT matcher");
00161 
00162         QVVideoReaderBlock videoReader("Video");
00163         videoReader.linkProperty(&SIFTMatcher,"Actual frame");
00164 
00165         QVDefaultGUI interface;
00166 
00167         
00168         QVImageCanvas actualFrame("Actual frame");
00169         SIFTMatcher.linkProperty("Actual frame", actualFrame);
00170         SIFTMatcher.linkProperty("Actual features", actualFrame);
00171         SIFTMatcher.linkProperty("Actual features orientations", actualFrame);
00172         actualFrame.setRadius("Actual features", 2);
00173         actualFrame.setColor("Actual features orientations", Qt::blue);
00174 
00175         
00176         QVImageCanvas referenceFrame("Matchings");
00177         SIFTMatcher.linkProperty("Matching images", referenceFrame);
00178         SIFTMatcher.linkProperty("Matching correspondences", referenceFrame);
00179         referenceFrame.setRadius("Matching correspondences", 2);
00180 
00181         return app.exec();
00182         }
00183 
00184 #endif