Ask Your Question

Devansh Dalal's profile - activity

2016-06-13 00:41:15 -0500 received badge  Student (source)
2015-07-02 04:30:39 -0500 received badge  Organizer (source)
2015-06-30 20:52:50 -0500 received badge  Supporter (source)
2015-06-29 01:29:50 -0500 asked a question 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 ...
(more)
2015-06-28 19:40:21 -0500 received badge  Scholar (source)
2015-06-23 03:06:35 -0500 asked a question Non maximum suppression output from raw edgemap.

Problem I have a program which gives the edgemap of an image without non maximum suppression of edge pixels. I am trying to apply NMS on this edgemap. So Is there any opencv c++ implemetation of NMS online ? Please provide any link if any. I have searched but haven't found any suitable for my requirements.

The representation of image is different in my case. Its data type is float and every pixel value lies in [0...1] . If the value of a pixel is large, it means higher chance of that pixel be in some edge in the original image.

Thanks

2015-06-23 00:00:02 -0500 received badge  Enthusiast
2015-06-22 21:21:40 -0500 asked a question Non maximum suppression of edges..

Currently I am working on a project on edgeBoxes algorithm which requires the Non maximum suppression of edges during pre-processing for further steps. For this I am looking the into the repository

https://github.com/pdollar/edges

I am unable to understand how and what kind of NMS is applied on the detected edges in this project(in file: https://github.com/pdollar/edges/blob... )

Please explain what bilinear interpolation, nms supr, supr boundaries etc mean in the same file.

Thanks

EDIT: The file from pDollar's matlab implementation.

    /*******************************************************************************
* Structured Edge Detection Toolbox      Version 3.01
* Code written by Piotr Dollar, 2014.
* Licensed under the MSR-LA Full Rights License [see license.txt]
*******************************************************************************/
#include <mex.h>
#include <math.h>
#ifdef USEOMP
#include <omp.h>
#endif

// return I[x,y] via bilinear interpolation
inline float interp( float *I, int h, int w, float x, float y ) {
  x = x<0 ? 0 : (x>w-1.001 ? w-1.001 : x);
  y = y<0 ? 0 : (y>h-1.001 ? h-1.001 : y);
  int x0=int(x), y0=int(y), x1=x0+1, y1=y0+1;
  float dx0=x-x0, dy0=y-y0, dx1=1-dx0, dy1=1-dy0;
  return I[x0*h+y0]*dx1*dy1 + I[x1*h+y0]*dx0*dy1 +
    I[x0*h+y1]*dx1*dy0 + I[x1*h+y1]*dx0*dy0;
}

// E = mexFunction(E,O,r,s,m,nThreads)
void mexFunction( int nl, mxArray *pl[], int nr, const mxArray *pr[] )
{
  float *E0 = (float*) mxGetData(pr[0]);    // original edge map
  float *O = (float*) mxGetData(pr[1]);     // orientation map
  int r = (int) mxGetScalar(pr[2]);         // radius for nms supr
  int s = (int) mxGetScalar(pr[3]);         // radius for supr boundaries
  float m = (float) mxGetScalar(pr[4]);     // multiplier for conservative supr
  int nThreads = (int) mxGetScalar(pr[5]);  // number of threads for evaluation

  int h=(int) mxGetM(pr[0]), w=(int) mxGetN(pr[0]);
  pl[0] = mxCreateNumericMatrix(h,w,mxSINGLE_CLASS,mxREAL);
  float *E = (float*) mxGetData(pl[0]);

  // suppress edges where edge is stronger in orthogonal direction
  #ifdef USEOMP
  nThreads = nThreads<omp_get_max_threads() ? nThreads : omp_get_max_threads();
  #pragma omp parallel for num_threads(nThreads)
  #endif
  for( int x=0; x<w; x++ ) for( int y=0; y<h; y++ ) {
    float e=E[x*h+y]=E0[x*h+y]; if(!e) continue; e*=m;
    float coso=cos(O[x*h+y]), sino=sin(O[x*h+y]);
    for( int d=-r; d<=r; d++ ) if( d ) {
      float e0 = interp(E0,h,w,x+d*coso,y+d*sino);
      if(e < e0) { E[x*h+y]=0; break; }
    }
  }

  // suppress noisy edge estimates near boundaries
  s=s>w/2?w/2:s; s=s>h/2? h/2:s;
  for( int x=0; x<s; x++ ) for( int y=0; y<h; y++ ) {
    E[x*h+y]*=x/float(s); E[(w-1-x)*h+y]*=x/float(s); }
  for( int x=0; x<w; x++ ) for( int y=0; y<s; y++ ) {
    E[x*h+y]*=y/float(s); E[x*h+(h-1-y)]*=y/float(s); }
}

EDIT: I have asked the same question on stackoverflow as well.

link : http://stackoverflow.com/questions/30...

2015-06-18 20:59:18 -0500 asked a question std::vector of cv::Mat causing memory corruption

I am using opencv_contrib's ximgproc moule's structural edge detector's code in my visual studio project . But it giving _CrtIsValidHeapPointer(pUserData) error expression . With some debugging I realized that Actually the error is caused when a function getFeatures defined in structured_edge_detector.cpp tries to push cv::Mat in a std::vector as shown below

virtual void getFeatures(const Mat &src, Mat &features, const int gnrmRad, const int gsmthRad,
                         const int shrink, const int outNum, const int gradNum) const
{
    cv::Mat luvImg = rgb2luv(src);

    std::vector <cv::Mat> featureArray;

    cv::Size nSize = src.size() / float(shrink);
    split( imresize(luvImg, nSize), featureArray );

    CV_INIT_VECTOR(scales, float, {1.0f, 0.5f});

    for (size_t i = 0; i < scales.size(); ++i)
    {
        int pSize = std::max( 1, int(shrink*scales[i]) );
    }
    mixChannels(featureArray, features, fromTo);
}

Please tell me what is the reason of such fault in program and any possible solution. My Opencv version is 2.4.10 so I am actually using the ximgproc's structured edge detector's code within my project.

Thanks

2015-06-18 01:13:11 -0500 commented question CV_Assert fail error in ximgproc module

Thanks @berak , it worked for me also. So Is there any good explanation or tutorial online to learn how this structured edge detection works?

2015-06-17 00:39:39 -0500 commented question CV_Assert fail error in ximgproc module

So Is it a bug or something is wrong with my approach or model or image due to which cvRound is required to change to cvCeil ? And if not a bug can you provide the correct way for doing it ?

2015-06-16 05:06:00 -0500 commented question CV_Assert fail error in ximgproc module

So what is the solution ? Changing the input image(where width < height) doesn't improves the situation .

2015-06-16 04:00:16 -0500 commented question CV_Assert fail error in ximgproc module

You mean this code is running properly on your system?

2015-06-16 02:04:34 -0500 received badge  Editor (source)
2015-06-16 02:02:31 -0500 asked a question CV_Assert fail error in ximgproc module

Problem : I have opencv 3.0 configured with extra modules on my system. I want to use the structured edge detector implemented in module ximgproc module. link : http://docs.opencv.org/trunk/d0/da5/t...

But it is giving following assert fail error on every image I tried till now.

512 512
OpenCV Error: Assertion failed (y == 0 || (data && dims >= 1 && (unsigned)y < (unsigned)size.p[0])) in cv::Mat::ptr, file C:\Program Files\OpenCV\opencv3.0\sources\modules\core\include\opencv2/core/mat.inl.hpp, line 750
Press any key to continue . . .

This error is caused by the function

detectEdges(src,dst)

Actual file path on my system is opencv3.0\sources\modules\core\include\opencv2/core/mat.inl.hpp . I am using the model file given in samples ('model.yml.gz')

Thanks

Code used:

#include <algorithm>
#include <vector>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"

#include "opencv2/core/utility.hpp"
#include "ximgproc/include/opencv2/ximgproc.hpp"
#include "ximgproc\include\opencv2\ximgproc\structured_edge_detection.hpp"

using namespace std;
using namespace cv;
using namespace cv::ximgproc;

int main(int argc, const char** argv)
{
    std::string modelFilename = "model.yml.gz";
    std::string inFilename = "01.png"; // "lena.jpg"
    std::string outFilename = "" ;//parser.get<std::string>("o");
    Mat image = imread(inFilename,1);
    if (image.empty())
    {
        printf("Cannot read image file: %s\n", inFilename.c_str());
        return -1;
    }
    Size size = image.size();
    std::cout << size.height << " " << size.width << std::endl;
    if ((size.height < 31) || (size.width < 20)) {
        if (size.height < 31)
            size.height = 31;
        if (size.width < 15)
            size.width = 15;
        resize(image, image, size, 0.0, 0.0, INTER_AREA);
    }
    size.width = 400;
    size.height = 213;
    resize(image, image, size, 0.0, 0.0, INTER_AREA);
    image.convertTo(image, DataType<float>::type, 1.0 / 255.0);

    Mat edges = Mat(image.rows,image.cols , image.type(), float(0.0));
    Ptr<RFFeatureGetter> rfptr = createRFFeatureGetter();

    Ptr<StructuredEdgeDetection> pDollar =
        createStructuredEdgeDetection(modelFilename, rfptr);
    //cerr << "reaching till here " << endl;

    pDollar->detectEdges((const Mat)image , edges);
    //cerr << " unreached " << endl;
    if (outFilename == "")
    {
        namedWindow("edges", 1);
        imshow("edges", edges);
        waitKey(0);
    }
    else
        imwrite(outFilename, 255 * edges);
    return 0;
}
2015-06-15 01:36:02 -0500 asked a question How to use opencv extra modules with opencv 2.4.X ?

I successfully configured opencv3.0 with opencv extra modules on my windows 7 laptop .

But I have to use the extra modulues with version 2.4.X opencv as my previous code is written in opencv 2.4.10 .

I want to know Is it possible ? and if yes then please guide how things will be different as compared to opencv 3.0.0 ?

Thanks