| OpenCV 3.4.7 Open Source Computer Vision

Structured forest training

## Introduction

In this tutorial we show how to train your own structured forest using author's initial Matlab implementation.

## Training pipeline

1. Download "Piotr's Toolbox" from link and put it into separate directory, e.g. PToolbox
2. Download BSDS500 dataset from link <http://www.eecs.berkeley.edu/Research/Projects/CS/vision/grouping/BSR/> and put it into separate directory named exactly BSR
3. Add both directory and their subdirectories to Matlab path.
4. Download detector code from link <http://research.microsoft.com/en-us/downloads/389109f6-b4e8-404c-84bf-239f7cbf4e3d/> and put it into root directory. Now you should have :
   .
   BSR
   PToolbox
   models
   private
   Contents.m
   edgesChns.m
   edgesDemo.m
   edgesDemoRgbd.m
   edgesDetect.m
   edgesEval.m
   edgesEvalDir.m
   edgesEvalImg.m
   edgesEvalPlot.m
   edgesSweeps.m
   edgesTrain.m
   license.txt
   readme.txt
5. Rename models/forest/modelFinal.mat to models/forest/modelFinal.mat.backup
6. Open edgesChns.m and comment lines 26–41. Add after commented lines the following:
   shrink=opts.shrink;
   chns = single(getFeatures( im2double(I) ));
7. Now it is time to compile promised getFeatures. I do with the following code:
   #include <cv.h>
   #include <highgui.h>
   #include <mat.h>
   #include <mex.h>
   #include "MxArray.hpp" // https://github.com/kyamagu/mexopencv
   class NewRFFeatureGetter : public cv::RFFeatureGetter
   {
   public:
   NewRFFeatureGetter() : name("NewRFFeatureGetter"){}
   virtual void getFeatures(const cv::Mat &src, NChannelsMat &features,
   const int gnrmRad, const int gsmthRad,
   const int shrink, const int outNum, const int gradNum) const
   {
   // here your feature extraction code, the default one is:
   // resulting features Mat should be n-channels, floating point matrix
   }
   protected:
   cv::String name;
   };
   MEXFUNCTION_LINKAGE void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
   {
   if (nlhs != 1) mexErrMsgTxt("nlhs != 1");
   if (nrhs != 1) mexErrMsgTxt("nrhs != 1");
   cv::Mat src = MxArray(prhs[0]).toMat();
   src.convertTo(src, cv::DataType<float>::type);
   std::string modelFile = MxArray(prhs[1]).toString();
   NewRFFeatureGetter *pDollar = createNewRFFeatureGetter();
   cv::Mat edges;
   pDollar->getFeatures(src, edges, 4, 0, 2, 13, 4);
   // you can use other numbers here
   edges.convertTo(edges, cv::DataType<double>::type);
   plhs[0] = MxArray(edges);
   }
8. Place compiled mex file into root dir and run edgesDemo. You will need to wait a couple of hours after that the new model will appear inside models/forest/.
9. The final step is converting trained model from Matlab binary format to YAML which you can use with our ocv::StructuredEdgeDetection. For this purpose run opencv_contrib/ximpgroc/tutorials/scripts/modelConvert(model, "model.yml")

## How to use your model

Just use expanded constructor with above defined class NewRFFeatureGetter

cv::StructuredEdgeDetection pDollar
= cv::createStructuredEdgeDetection( modelName, makePtr<NewRFFeatureGetter>() );