检测直线FastLineDetector类 LineSegmentDetector类

https://blog.csdn.net/guoyunfei20/article/details/78754526

在OpenCV3.0 以上版本的contrib模块中,有一个cv::ximgproc::FastLineDetector类。定义位置:

  1. // 需要下载contrib模块  
  2. opencv_contrib/modules/ximgproc/include/opencv2/ximgproc/fast_line_detector.hpp  
所谓Fast,是相对于正式模块中的 cv::imgproc::LineSegmentDetector类来说,速度更快。FastLineDetector类依据下边的论文实现:
  1. // 论文  
  2. Outdoor Place Recognition in Urban Environments using Straight Lines  
  3. // 下载地址:  
  4. http://cvlab.hanyang.ac.kr/~jwlim/files/icra14linerec.pdf  
大致的原理是:

先在输入图像上,应用canny边缘检测;然后根据在canny边缘图像上进行分析,找到直线。


例程:

该例程对比了上述俩直线检测算子的运行耗时情况。

  1. #include <iostream>  
  2. #include <stdio.h>  
  3. #include <unistd.h>  
  4. #include <stdlib.h>  
  5. #include <string.h>  
  6. #include <string>  
  7. #include <dirent.h>  
  8. #include <unistd.h>  
  9. #include <vector>  
  10. #include <sstream>  
  11. #include <fstream>  
  12. #include <sys/io.h>  
  13. #include <sys/times.h>  
  14. #include <iomanip>  
  15. #include <tuple>  
  16. #include <cstdlib>  
  17. using namespace std;  
  18.   
  19. #include "opencv2/imgproc.hpp"  
  20. #include "opencv2/ximgproc.hpp"  
  21. #include "opencv2/imgcodecs.hpp"  
  22. #include "opencv2/highgui.hpp"  
  23. using namespace cv;  
  24. using namespace cv::ximgproc;  
  25.   
  26. int main(int argc, char** argv)  
  27. {  
  28.     std::string in;  
  29.     cv::CommandLineParser parser(argc, argv, "{@input|../samples/data/corridor.jpg|input image}{help h||show help message}");  
  30.     if (parser.has("help"))  
  31.     {  
  32.         parser.printMessage();  
  33.         return 0;  
  34.     }  
  35.     in = parser.get<string>("@input");  
  36.     Mat image = imread(in, IMREAD_GRAYSCALE);  
  37.     if( image.empty() )  
  38.     {  
  39.         return -1;  
  40.     }  
  41.     // Create LSD detector  
  42.     Ptr<LineSegmentDetector> lsd = createLineSegmentDetector();  
  43.     vector<Vec4f> lines_lsd;  
  44.     // Create FLD detector  
  45.     // Param               Default value   Description  
  46.     // length_threshold    10            - Segments shorter than this will be discarded  
  47.     // distance_threshold  1.41421356    - A point placed from a hypothesis line  
  48.     //                                     segment farther than this will be  
  49.     //                                     regarded as an outlier  
  50.     // canny_th1           50            - First threshold for  
  51.     //                                     hysteresis procedure in Canny()  
  52.     // canny_th2           50            - Second threshold for  
  53.     //                                     hysteresis procedure in Canny()  
  54.     // canny_aperture_size 3             - Aperturesize for the sobel  
  55.     //                                     operator in Canny()  
  56.     // do_merge            false         - If true, incremental merging of segments  
  57.     //                                     will be perfomred  
  58.     int    length_threshold    = 10;  
  59.     float  distance_threshold  = 1.41421356f;  
  60.     double canny_th1           = 50.0;  
  61.     double canny_th2           = 50.0;  
  62.     int    canny_aperture_size = 3;  
  63.     bool   do_merge            = false;  
  64.     Ptr<FastLineDetector> fld = createFastLineDetector(  
  65.             length_threshold,  
  66.             distance_threshold,   
  67.             canny_th1,   
  68.             canny_th2,   
  69.             canny_aperture_size,  
  70.             do_merge);  
  71.     vector<Vec4f> lines_fld;  
  72.     // Because of some CPU's power strategy, it seems that the first running of  
  73.     // an algorithm takes much longer. So here we run both of the algorithmes 10  
  74.     // times to see each algorithm's processing time with sufficiently warmed-up  
  75.     // CPU performance.  
  76.     for(int run_count = 0; run_count < 10; run_count++) {  
  77.         lines_lsd.clear();  
  78.         int64 start_lsd = getTickCount();  
  79.         lsd->detect(image, lines_lsd);  
  80.         // Detect the lines with LSD  
  81.         double freq = getTickFrequency();  
  82.         double duration_ms_lsd = double(getTickCount() - start_lsd) * 1000 / freq;  
  83.         std::cout << "Elapsed time for LSD: "   
  84.                   << setw(10) << setiosflags(ios::right) << setiosflags(ios::fixed) << setprecision(2)   
  85.                   << duration_ms_lsd << " ms." << std::endl;  
  86.         lines_fld.clear();  
  87.         int64 start = getTickCount();  
  88.         // Detect the lines with FLD  
  89.         fld->detect(image, lines_fld);  
  90.         double duration_ms = double(getTickCount() - start) * 1000 / freq;  
  91.         std::cout << "Ealpsed time for FLD: "   
  92.                   << setw(10) << setiosflags(ios::right) << setiosflags(ios::fixed) << setprecision(2)  
  93.                   << duration_ms << " ms." << std::endl;  
  94.     }  
  95.       
  96.     // Show found lines with LSD  
  97.     Mat line_image_lsd(image);  
  98.     lsd->drawSegments(line_image_lsd, lines_lsd);  
  99.     imshow("LSD result", line_image_lsd);  
  100.     // Show found lines with FLD  
  101.     Mat line_image_fld(image);  
  102.     fld->drawSegments(line_image_fld, lines_fld);  
  103.     imshow("FLD result", line_image_fld);  
  104.     waitKey();  
  105.       
  106.     return 0;  
  107. }  
结果:



可以看出,俩算法的效果差不多;但FLD要更快!

猜你喜欢

转载自blog.csdn.net/danmeng8068/article/details/80685403