OpenCV  4.5.3
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

Note
binarization techniques like Canny edge detector are applicable to edges produced by both algorithms (Sobel and StructuredEdgeDetection::detectEdges).

Source Code

1 /**************************************************************************************
2 The structered edge 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"
10 #include <iostream>
11 
12 using namespace cv;
13 using namespace cv::ximgproc;
14 
15 const char* keys =
16 {
17  "{i || input image name}"
18  "{m || model name}"
19  "{o || output image name}"
20 };
21 
22 int main( int argc, const char** argv )
23 {
24  bool printHelp = ( argc == 1 );
25  printHelp = printHelp || ( argc == 2 && String(argv[1]) == "--help" );
26  printHelp = printHelp || ( argc == 2 && String(argv[1]) == "-h" );
27 
28  if ( printHelp )
29  {
30  std::cout << "\nThis sample demonstrates structured forests for fast edge detection\n"
31  "Call:\n"
32  " structured_edge_detection -i=in_image_name -m=model_name [-o=out_image_name]\n\n";
33  return 0;
34  }
35 
36  CommandLineParser parser(argc, argv, keys);
37  if ( !parser.check() )
38  {
39  parser.printErrors();
40  return -1;
41  }
42 
43  String modelFilename = parser.get<String>("m");
44  String inFilename = parser.get<String>("i");
45  String outFilename = parser.get<String>("o");
46 
47  Mat image = imread(inFilename, 1);
48  if ( image.empty() )
49  CV_Error(Error::StsError, String("Cannot read image file: ") + inFilename);
50 
51  if ( modelFilename.size() == 0)
52  CV_Error(Error::StsError, String("Empty model name"));
53 
54  image.convertTo(image, DataType<float>::type, 1/255.0);
55 
56  Mat edges(image.size(), image.type());
57 
59  createStructuredEdgeDetection(modelFilename);
60  pDollar->detectEdges(image, edges);
61 
62  // computes orientation from edge map
63  Mat orientation_map;
64  pDollar->computeOrientation(edges, orientation_map);
65 
66  // suppress edges
67  Mat edge_nms;
68  pDollar->edgesNms(edges, orientation_map, edge_nms, 2, 0, 1, true);
69 
70  if ( outFilename.size() == 0 )
71  {
72  namedWindow("edges", 1);
73  imshow("edges", edges);
74  namedWindow("edges nms", 1);
75  imshow("edges nms", edge_nms);
76  waitKey(0);
77  }
78  else
79  imwrite(outFilename, 255*edges);
80 
81  return 0;
82 }
Designed for command line parsing.
Definition: utility.hpp:800
Template "trait" class for OpenCV primitive data types.
Definition: traits.hpp:113
n-dimensional dense array class
Definition: mat.hpp:802
std::string String
Definition: cvstd.hpp:150
std::shared_ptr< _Tp > Ptr
Definition: cvstd_wrapper.hpp:23
#define CV_Error(code, msg)
Call the error handler.
Definition: base.hpp:320
void imshow(const String &winname, InputArray mat)
Displays an image in the specified window.
int waitKey(int delay=0)
Waits for a pressed key.
void namedWindow(const String &winname, int flags=WINDOW_AUTOSIZE)
Creates a window.
CV_EXPORTS_W bool imwrite(const String &filename, InputArray img, const std::vector< int > &params=std::vector< int >())
Saves an image to a specified file.
CV_EXPORTS_W Mat imread(const String &filename, int flags=IMREAD_COLOR)
Loads an image from a file.
Ptr< StructuredEdgeDetection > createStructuredEdgeDetection(const String &model, Ptr< const RFFeatureGetter > howToGetFeatures=Ptr< RFFeatureGetter >())
@ StsError
unknown /unspecified error
Definition: base.hpp:71
Definition: brightedges.hpp:47
"black box" representation of the file storage associated with a file on disk.
Definition: affine.hpp:52

Explanation

  1. Load source color image
    cv::Mat image = cv::imread(inFilename, 1);
    if ( image.empty() )
    {
    printf("Cannot read image file: %s\n", inFilename.c_str());
    return -1;
    }
    bool empty() const
    Returns true if the array has no elements.
  2. Convert source image to [0;1] range
    image.convertTo(image, cv::DataType<float>::type, 1/255.0);
    void convertTo(OutputArray m, int rtype, double alpha=1, double beta=0) const
    Converts an array to another data type with optional scaling.
  3. Run main algorithm
    cv::Mat edges(image.size(), image.type());
    pDollar->detectEdges(image, edges);
    MatSize size
    Definition: mat.hpp:2129
    int type() const
    Returns the type of a matrix element.
  4. Show results
    if ( outFilename == "" )
    {
    cv::namedWindow("edges", 1);
    cv::imshow("edges", edges);
    }
    else
    cv::imwrite(outFilename, 255*edges);

Literature

For more information, refer to the following papers : [Dollar2013] [Lim2013]