Problem understanding the code of SE detector

asked 2015-06-29 01:29:50 -0600

Devansh Dalal gravatar image

updated 2015-07-02 04:30:39 -0600

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 ...
(more)
edit retag flag offensive close merge delete