src/qvworkers/qvcannyborderdetector.cpp

Go to the documentation of this file.
00001 /*
00002  *      Copyright (C) 2007, 2008. 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 
00024 
00025 #include <qvdta.h>
00026 #include <qvip.h>
00027 #include <QVPolyline>
00028 #include <QVCannyBorderDetector>
00029 
00030 #ifndef DOXYGEN_IGNORE_THIS
00031 QVCannyBorderDetector::QVCannyBorderDetector(QString name): QVWorker(name)
00032         {
00033         addProperty<double>("cannyHigh", inputFlag, 150, "High threshold for Canny operator", 50, 1000);
00034         addProperty<double>("cannyLow", inputFlag, 50, "Low threshold for Canny operator", 10, 500);
00035         addProperty<bool>("applyIPE", inputFlag, TRUE, "If we want to apply the IPE algorithm");
00036         addProperty<double>("paramIPE", inputFlag, 5.0, "IPE parameter (max. allowed distance to line)", 1.0, 25.0);
00037         addProperty<bool>("intersectLines", inputFlag, TRUE, "If we want IPE to postprocess polyline (intersecting lines)");
00038         addProperty<int>("minLengthContour", inputFlag, 25, "Minimal length of a contour to be considered", 1, 150);
00039         addProperty<int>("showNothingCannyImage", inputFlag, 0, "If we want nothing|Canny|original image to be shown",0,2);
00040         addProperty<bool>("showContours", inputFlag, TRUE, "If we want contours to be shown");
00041 
00042         addProperty< QVImage<uChar,1> >("Output image", outputFlag);
00043         addProperty< QVImage<uChar,3> >("Input image", inputFlag|outputFlag);
00044         addProperty< QList<QVPolyline> >("Output contours", outputFlag);
00045         }
00046 
00047 void QVCannyBorderDetector::iterate()
00048         {
00049         // 0. Read input parameters
00050         const double cannyHigh = getPropertyValue<double>("cannyHigh");
00051         const double cannyLow = getPropertyValue<double>("cannyLow");
00052         const bool applyIPE = getPropertyValue<bool>("applyIPE");
00053         const double paramIPE = getPropertyValue<double>("paramIPE");
00054         const bool intersectLines = getPropertyValue<bool>("intersectLines");
00055         const int minLengthContour = getPropertyValue<int>("minLengthContour");
00056         const int showNothingCannyImage = getPropertyValue<int>("showNothingCannyImage");
00057         const bool showContours = getPropertyValue<bool>("showContours");
00058         const QVImage<uChar,1> image = getPropertyValue< QVImage<uChar,3> >("Input image");
00059         const uInt cols = image.getCols(), rows = image.getRows();
00060 
00061         QVImage<sFloat> imageFloat(cols, rows), dX(cols, rows), dY(cols, rows), dXNeg(cols, rows);
00062         QVImage<uChar> canny(cols, rows), buffer;
00063 
00064         // 1. Convert image from uChar to sShort
00065         Convert(image, imageFloat);
00066         timeFlag("Convert image from uChar to sShort");
00067 
00068         // 2. Obtain horizontal and vertical gradients from image
00069         FilterSobelHorizMask(imageFloat,dY);
00070         FilterSobelVertMask(imageFloat,dX);
00071         MulC(dX, -1, dXNeg);
00072         timeFlag("Obtain horizontal and vertical gradients from image");
00073 
00074         // 3. Apply Canny operator
00075         CannyGetSize(canny, buffer);
00076         Canny(dXNeg, dY, canny, cannyLow,cannyHigh, buffer);
00077         timeFlag("Apply Canny operator");
00078 
00079         // 4. Get contours
00080         const QList<QVPolyline> contourList = getLineContoursThreshold8Connectivity(canny, 128);
00081         timeFlag("Get contours");
00082 
00083         QList<QVPolyline> outputList;
00084         foreach(QVPolyline contour,contourList)
00085                 {
00086                 if(contour.size() > minLengthContour)
00087                         {
00088                         if(applyIPE)
00089                                 {
00090                                 QVPolyline IPEcontour;
00091                                 IterativePointElimination(contour,IPEcontour,paramIPE,FALSE,intersectLines);
00092                                 outputList.append(IPEcontour);
00093                                 }
00094                         else
00095                                 outputList.append(contour);
00096                         }
00097                 }
00098         timeFlag("IPE on contours");
00099 
00100         // 5. Publish resulting data
00101         if(showNothingCannyImage == 1)
00102                 setPropertyValue< QVImage<uChar,1> >("Output image",canny);
00103         else if(showNothingCannyImage == 2)
00104                 setPropertyValue< QVImage<uChar,1> >("Output image",image);
00105         else    {
00106                 QVImage<uChar> whiteImage(cols, rows);
00107                 Set(255, whiteImage);
00108                 setPropertyValue< QVImage<uChar,1> >("Output image",whiteImage);
00109                 }
00110         if(showContours)
00111                 setPropertyValue< QList< QVPolyline> >("Output contours",outputList);
00112         else
00113                 setPropertyValue< QList< QVPolyline> >("Output contours",QList<QVPolyline>());
00114 
00115         timeFlag("Publish results");
00116         }
00117 
00118 #endif