PARP Research Group University of Murcia, Spain


examples/OpenCV/delaunay/delaunay.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 
00044 #include <stdio.h>
00045 #include <stdlib.h>
00046 #include <iostream>
00047 #include <math.h>
00048 
00049 #include <QDebug>
00050 #include <QThread>
00051 
00052 #include <QVApplication>
00053 #include <QVMPlayerCamera>
00054 #include <QVDefaultGUI>
00055 #include <QVImageCanvas>
00056 #include <QVPolylineF>
00057 
00058 #include <QVHarrisPointDetector>
00059 #include <qvio.h>
00060 #include <qvip.h>
00061 
00062 #ifndef DOXYGEN_IGNORE_THIS
00063 
00064 #ifdef OPENCV
00065 #include <opencv/cv.h>
00066 QList<QVPolylineF> map2polyline(const QHash<QPointF, QPointF> &map)
00067         {
00068         QList<QVPolylineF> polylines;
00069 
00070         QHashIterator<QPointF, QPointF> iterator(map);
00071 
00072         while (iterator.hasNext())
00073                 {
00074                 iterator.next();
00075                 QVPolylineF polyline;
00076                 polyline.append(iterator.key());
00077                 polyline.append(iterator.value());
00078                 polylines.append(polyline);
00079                 }
00080 
00081         return polylines;
00082         }
00083 
00084 class DelaunayWorker: public QVWorker
00085         {
00086         public:
00087                 DelaunayWorker(const QString name): QVWorker(name)
00088                         {
00089                         addProperty< QList < QPointF > >("Feature locations", inputFlag|outputFlag);
00090                         addProperty< QList<QVPolylineF> >("Delaunay edges", outputFlag);
00091                         }
00092 
00093                 // Inspired in Roman Stanchak's Delaunay triangulation code for OpenCV.
00094                 //      http://opencv.willowgarage.com/wiki/RomanStanchak
00095                 QHash<QPointF, QPointF> delaunayTriangulation(const QList<QPointF> &selectedPoints) const
00096                         {
00097                         // STORAGE AND STRUCTURE FOR DELAUNAY SUBDIVISION
00098                         CvMemStorage*   storage = cvCreateMemStorage(0);                //Storage for the Delaunay subdivsion
00099 
00100                         // The subdivision itself
00101                         CvSubdiv2D* subdiv = cvCreateSubdiv2D(  CV_SEQ_KIND_SUBDIV2D,
00102                                                                 sizeof(*subdiv),
00103                                                                 sizeof(CvSubdiv2DPoint),
00104                                                                 sizeof(CvQuadEdge2D),
00105                                                                 storage);
00106 
00107                         // Set boundaries for the Delaunay triangulation algorithm.
00108                         double  minX = std::numeric_limits<double>::max(),
00109                                 minY = std::numeric_limits<double>::max(),
00110                                 maxX = std::numeric_limits<double>::min(),
00111                                 maxY = std::numeric_limits<double>::min();
00112 
00113                         foreach(QPointF point, selectedPoints)
00114                                 {
00115                                 minX = MIN(minX, point.x());
00116                                 minY = MIN(minY, point.y());
00117                                 maxX = MAX(maxX, point.x());
00118                                 maxY = MAX(maxY, point.y());
00119                                 }
00120 
00121                         cvInitSubdivDelaunay2D(subdiv, (CvRect){ minX, minY, maxX, maxY });
00122 
00123                         // Add points to the Delaunay subdivision structure.
00124                         foreach(QPointF point, selectedPoints)
00125                                 cvSubdivDelaunay2DInsert(subdiv, (CvPoint2D32f){ point.x(), point.y() });
00126 
00127                         // Transverse Delaunay partition, adding Delaunay triangulation edges.
00128                         CvSeqReader reader;
00129                         QHash <QPointF, QPointF> correspondences;
00130                         cvStartReadSeq((CvSeq *)subdiv->edges, &reader);
00131 
00132                         for(int i=0; i<subdiv->edges->total; i++)
00133                                 {
00134                                 CvQuadEdge2D * edge = (CvQuadEdge2D *) reader.ptr;
00135                                 if(CV_IS_SET_ELEM(edge))
00136                                         {
00137                                         CvSubdiv2DPoint * org = cvSubdiv2DEdgeOrg( (CvSubdiv2DEdge) edge );
00138                                         CvSubdiv2DPoint * dst = cvSubdiv2DEdgeDst( (CvSubdiv2DEdge) edge );
00139                                         if(org && dst && (CV_IS_SET_ELEM(org) && ((org)->flags & CV_SUBDIV2D_VIRTUAL_POINT_FLAG)==0))
00140                                                 if ( (org->pt.x > minX) && (org->pt.x < maxX) && (dst->pt.y > minY) && (dst->pt.y < maxY) )
00141                                                         correspondences.insertMulti(QPointF(org->pt.x, org->pt.y), QPointF(dst->pt.x, dst->pt.y));
00142                                         }
00143                                 CV_NEXT_SEQ_ELEM(subdiv->edges->elem_size, reader);
00144                                 }
00145 
00146                         return correspondences;
00147                         }
00148 
00149                 void iterate()
00150                         {
00151                         // 0. Read input property values.
00152                         const QList<QPointF> selectedPoints = getPropertyValue< QList< QPointF > >("Feature locations");
00153                         timeFlag("Read data");
00154 
00155                         // Get boundaries for the Delaunay triangulation algorithm.
00156                         QHash<QPointF, QPointF> correspondences = delaunayTriangulation(selectedPoints);
00157                         timeFlag("Generated edges");
00158 
00159                         QList<QVPolylineF> delaunayEdges = map2polyline(correspondences);
00160                         timeFlag("From correspondences to polylines");
00161 
00162                         setPropertyValue< QList<QVPolylineF> >("Delaunay edges", delaunayEdges);
00163                         }
00164         };
00165 
00166 #include <QVYUV4MPEG2Recorder>
00167 #include <QVNumericPlot>
00168 int main(int argc, char *argv[])
00169         {
00170         QVApplication app(argc, argv,
00171                 "Example program for QVision library. Obtains intrinsic and extrinsic camera parameters."
00172                 );
00173 
00174         QVMPlayerCamera camera("Video");
00175 
00176         QVHarrisPointDetector pointDetector("Harris corners detector");
00177         camera.linkProperty(&pointDetector,"Input image");
00178 
00179         // Camera calibrator.
00180         DelaunayWorker delaunayWorker("Delaunay");
00181         pointDetector.linkProperty("Feature locations", delaunayWorker, QVWorker::SynchronousLink);
00182 
00183         // Image outputs
00184         QVImageCanvas imageCanvas("Delaunay regions");
00185         pointDetector.linkProperty("Input image", imageCanvas);
00186         delaunayWorker.linkProperty("Feature locations", imageCanvas);
00187         delaunayWorker.linkProperty("Delaunay edges", imageCanvas);
00188         imageCanvas.setColor("Delaunay edges", Qt::red);
00189 
00190         QVDefaultGUI interface;
00191 
00192         return app.exec();
00193         }
00194 #else
00195 int main(int argc, char *argv[])
00196         {
00197         std::cout << "ERROR: OpenCV compatibility was not activated in QVision compilation." << std::endl;
00198         return -1;
00199         }
00200 #endif  // OPENCV
00201 #endif  // DOXIGEN_IGNORE_THIS
00202 



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