# Problem understanding the code of SE detector

**Problem** I am trying to understand and hence improve the function predictEdges of structured edge detector from the ximgproc module of opencv_conrib . I have understood the "Structured forests for fast edge detection" paper on the same topic. I know that the function predictEdges pedicts the edges from the information available in the learnt "model" using some ensemble model of the output of various decision trees. But I don't know what each loop of the function is doing ?

Please explain the predictEdges, if possible ..

Also as from my experiments it appears that this implementation of SE detector takes at least 2 seconds for processing each image which may be slow for real time algorithms. So please suggest any improvement if possible

Thanks

One approach I am trying is to use openMP parallel for loop, It is almost reducing the runtime to half , but this is not a fundamental optimization. I am looking for other conceptual optimizations even at the cost of accuracy .

```
void predictEdges(const NChannelsMat &features, cv::Mat &dst) const
{
int shrink = __rf.options.shrinkNumber;
int rfs = __rf.options.regFeatureSmoothingRadius;
int sfs = __rf.options.ssFeatureSmoothingRadius;
int nTreesEval = __rf.options.numberOfTreesToEvaluate;
int nTrees = __rf.options.numberOfTrees;
int nTreesNodes = __rf.numberOfTreeNodes;
const int nchannels = features.channels();
int pSize = __rf.options.patchSize;
int nFeatures = CV_SQR(pSize/shrink)*nchannels;
int outNum = __rf.options.numberOfOutputChannels;
int stride = __rf.options.stride;
int ipSize = __rf.options.patchInnerSize;
int gridSize = __rf.options.selfsimilarityGridSize;
const int height = cvCeil( double(features.rows*shrink - pSize) / stride );
const int width = cvCeil( double(features.cols*shrink - pSize) / stride );
// image size in patches with overlapping
//-------------------------------------------------------------------------
NChannelsMat regFeatures = imsmooth(features, cvRound(rfs / float(shrink)));
NChannelsMat ssFeatures = imsmooth(features, cvRound(sfs / float(shrink)));
NChannelsMat indexes(height, width, CV_MAKETYPE(DataType<int>::type, nTreesEval));
std::vector <int> offsetI(/**/ CV_SQR(pSize/shrink)*nchannels, 0);
for (int i = 0; i < CV_SQR(pSize/shrink)*nchannels; ++i)
{
int z = i / CV_SQR(pSize/shrink);
int y = ( i % CV_SQR(pSize/shrink) )/(pSize/shrink);
int x = ( i % CV_SQR(pSize/shrink) )%(pSize/shrink);
offsetI[i] = x*features.cols*nchannels + y*nchannels + z;
}
// lookup table for mapping linear index to offsets
std::vector <int> offsetE(/**/ CV_SQR(ipSize)*outNum, 0);
for (int i = 0; i < CV_SQR(ipSize)*outNum; ++i)
{
int z = i / CV_SQR(ipSize);
int y = ( i % CV_SQR(ipSize) )/ipSize;
int x = ( i % CV_SQR(ipSize) )%ipSize;
offsetE[i] = x*dst.cols*outNum + y*outNum + z;
}
// lookup table for mapping linear index to offsets
std::vector <int> offsetX( CV_SQR(gridSize)*(CV_SQR(gridSize) - 1)/2 * nchannels, 0);
std::vector <int> offsetY( CV_SQR(gridSize)*(CV_SQR(gridSize) - 1)/2 * nchannels, 0);
int hc = cvRound( (pSize/shrink) / (2.0*gridSize) );
// half of cell
std::vector <int> gridPositions;
for(int i = 0; i < gridSize; i++)
gridPositions.push_back( int( (i+1)*(pSize/shrink + 2*hc - 1)/(gridSize + 1.0) - hc + 0.5f ) );
for (int i = 0, n = 0; i < CV_SQR(gridSize)*nchannels; ++i)
for (int j = (i%CV_SQR(gridSize)) + 1; j < CV_SQR(gridSize); ++j, ++n)
{
int z = i / CV_SQR(gridSize);
int x1 = gridPositions[i%CV_SQR(gridSize)%gridSize];
int y1 = gridPositions[i%CV_SQR(gridSize)/gridSize ...
```