OpenCV  3.4.19
Open Source Computer Vision
Structured forests for fast edge detection

Introduction

In this tutorial you will learn how to use structured forests for the purpose of edge detection in an image.

Examples

01.jpg
image
02.jpg
image
03.jpg
image
04.jpg
image
05.jpg
image
06.jpg
image
07.jpg
image
08.jpg
image
09.jpg
image
10.jpg
image
11.jpg
image
12.jpg
image
Note
binarization techniques like Canny edge detector are applicable to edges produced by both algorithms (Sobel and StructuredEdgeDetection::detectEdges).

Source Code

1 /**************************************************************************************
2 The structured forests for fast edge detection demo requires you to provide a model.
3 This model can be found at the opencv_extra repository on Github on the following link:
4 https://github.com/opencv/opencv_extra/blob/master/testdata/cv/ximgproc/model.yml.gz
5 ***************************************************************************************/
6 
7 #include <opencv2/ximgproc.hpp>
8 #include "opencv2/highgui.hpp"
9 #include <iostream>
10 
11 using namespace cv;
12 using namespace cv::ximgproc;
13 
14 const char* keys =
15 {
16  "{i || input image file name}"
17  "{m || model file name}"
18  "{o || output image file name}"
19 };
20 
21 int main( int argc, const char** argv )
22 {
23  CommandLineParser parser(argc, argv, keys);
24  parser.about("This sample demonstrates usage of structured forests for fast edge detection");
25  parser.printMessage();
26 
27  if ( !parser.check() )
28  {
29  parser.printErrors();
30  return -1;
31  }
32 
33  String modelFilename = parser.get<String>("m");
34  String inFilename = parser.get<String>("i");
35  String outFilename = parser.get<String>("o");
36 
38  Mat image = imread(inFilename, IMREAD_COLOR);
39  if ( image.empty() )
40  CV_Error(Error::StsError, String("Cannot read image file: ") + inFilename);
42 
43  if ( modelFilename.size() == 0)
44  CV_Error(Error::StsError, String("Empty model name"));
45 
47  image.convertTo(image, DataType<float>::type, 1/255.0);
49 
50  TickMeter tm;
51  tm.start();
54  createStructuredEdgeDetection(modelFilename);
56 
57  tm.stop();
58  std::cout << "createStructuredEdgeDetection() time : " << tm << std::endl;
59 
60  tm.reset();
61  tm.start();
63  Mat edges;
64  pDollar->detectEdges(image, edges);
66  tm.stop();
67  std::cout << "detectEdges() time : " << tm << std::endl;
68 
69  tm.reset();
70  tm.start();
72  // computes orientation from edge map
73  Mat orientation_map;
74  pDollar->computeOrientation(edges, orientation_map);
75 
76  // suppress edges
77  Mat edge_nms;
78  pDollar->edgesNms(edges, orientation_map, edge_nms, 2, 0, 1, true);
80 
81  tm.stop();
82  std::cout << "nms time : " << tm << std::endl;
83 
85  if ( outFilename.size() == 0 )
86  {
87  imshow("edges", edges);
88  imshow("edges nms", edge_nms);
89  waitKey(0);
90  }
91  else
92  imwrite(outFilename, 255*edges);
94 
95  return 0;
96 }
bool imwrite(const String &filename, InputArray img, const std::vector< int > &params=std::vector< int >())
Saves an image to a specified file.
unknown /unspecified error
Definition: base.hpp:71
virtual void edgesNms(cv::InputArray edge_image, cv::InputArray orientation_image, cv::OutputArray dst, int r=2, int s=0, float m=1, bool isParallel=true) const =0
The function edgenms in edge image and suppress edges where edge is stronger in orthogonal direction...
Mat imread(const String &filename, int flags=IMREAD_COLOR)
Loads an image from a file.
#define CV_Error(code, msg)
Call the error handler.
Definition: base.hpp:333
void imshow(const String &winname, InputArray mat)
Displays an image in the specified window.
Definition: affine.hpp:51
Designed for command line parsing.
Definition: utility.hpp:812
void reset()
resets internal values.
Definition: utility.hpp:372
If set, always convert image to the 3 channel BGR color image.
Definition: imgcodecs.hpp:71
Ptr< StructuredEdgeDetection > createStructuredEdgeDetection(const String &model, Ptr< const RFFeatureGetter > howToGetFeatures=Ptr< RFFeatureGetter >())
a Class to measure passing time.
Definition: utility.hpp:292
Definition: brightedges.hpp:47
Template class for smart pointers with shared ownership.
Definition: cvstd.hpp:261
void stop()
stops counting ticks.
Definition: utility.hpp:308
void start()
starts counting ticks.
Definition: utility.hpp:302
virtual void detectEdges(cv::InputArray src, cv::OutputArray dst) const =0
The function detects edges in src and draw them to dst.
Template "trait" class for OpenCV primitive data types.
Definition: traits.hpp:112
Definition: cvstd.hpp:458
size_t size() const
n-dimensional dense array class
Definition: mat.hpp:822
virtual void computeOrientation(cv::InputArray src, cv::OutputArray dst) const =0
The function computes orientation from edge image.
int waitKey(int delay=0)
Waits for a pressed key.

Explanation

  1. Load source color image

    Mat image = imread(inFilename, IMREAD_COLOR);
    if ( image.empty() )
    CV_Error(Error::StsError, String("Cannot read image file: ") + inFilename);
  2. Convert source image to float [0;1] range

    image.convertTo(image, DataType<float>::type, 1/255.0);
  3. Run main algorithm

    Ptr<StructuredEdgeDetection> pDollar =
    Mat edges;
    pDollar->detectEdges(image, edges);
    // computes orientation from edge map
    Mat orientation_map;
    pDollar->computeOrientation(edges, orientation_map);
    // suppress edges
    Mat edge_nms;
    pDollar->edgesNms(edges, orientation_map, edge_nms, 2, 0, 1, true);
  4. Show results

    if ( outFilename.size() == 0 )
    {
    imshow("edges", edges);
    imshow("edges nms", edge_nms);
    waitKey(0);
    }
    else
    imwrite(outFilename, 255*edges);

    Literature

For more information, refer to the following papers : [56] [135]