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