00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00024
00025 #include <qvip.h>
00026 #include <qvipp.h>
00027 #include <QVPolyline>
00028 #include <QVCannyEdgeDetector>
00029
00030 #ifndef DOXYGEN_IGNORE_THIS
00031 QVCannyEdgeDetector::QVCannyEdgeDetector(QString name): QVProcessingBlock(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, FALSE, "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
00040
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 QVCannyEdgeDetector::iterate()
00048 {
00049
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
00057
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
00065 Convert(image, imageFloat);
00066 timeFlag("Convert image from uChar to sShort");
00067
00068
00069 FilterSobelHorizMask(imageFloat,dY);
00070 FilterSobelVertMask(imageFloat,dX);
00071 MulC(dX, -1, dXNeg);
00072 timeFlag("Obtain horizontal and vertical gradients from image");
00073
00074
00075 CannyGetSize(canny, buffer);
00076 Canny(dXNeg, dY, canny, cannyLow,cannyHigh, buffer);
00077 timeFlag("Apply Canny operator");
00078
00079
00080 const QList<QVPolyline> contourList = getLineContoursThreshold8Connectivity(canny, 128);
00081 timeFlag("Get contours");
00082
00083 QList<QVPolyline> outputList;
00084 foreach(QVPolyline contour,contourList)
00085 if(contour.size() > minLengthContour)
00086 {
00087 #ifdef QVMATRIXALGEBRA_AVAILABLE
00088 if(applyIPE)
00089 {
00090 QVPolyline IPEcontour;
00091 IterativePointElimination(contour, IPEcontour, paramIPE, FALSE, intersectLines);
00092 outputList.append(IPEcontour);
00093 }
00094 else
00095 #endif // QVMATRIXALGEBRA_AVAILABLE
00096 outputList.append(contour);
00097 }
00098
00099 timeFlag("IPE on contours");
00100
00101
00102
00103
00104 setPropertyValue< QVImage<uChar,1> >("Output image",canny);
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116 setPropertyValue< QList< QVPolyline> >("Output contours",outputList);
00117
00118
00119
00120 timeFlag("Publish results");
00121 }
00122
00123 #endif