0
votes

I am using mexopencv from matlab, however I have noticed that groupRectangles Matlab wrapper there supports only 3 input arguments while the source has 3 different versions.

I don't know C++ but I tried to follow the guidelines and the written code but I was not able to compile it; it gives a peculiar error.

I would appreciate if anyone can help with this, I need to return scores of the final bounding boxes for my project.

SO ! I have found a very similar question & answer online:

In cascadedetect.cpp in OpenCV, there are several variants of groupRectangles function: void groupRectangles(std::vector& rectList, int groupThreshold, double eps); void groupRectangles(std::vector& rectList, std::vector& weights, int groupThreshold, double eps); void groupRectangles(std::vector& rectList, std::vector& rejectLevels, std::vector& levelWeights, int groupThreshold, double eps); But in the OpenCV document, only the first variant is documented clearly, the second variant is mentioned but the weights argument is not explained. The third isn't even mentioned.

we want to get the scores of grouped rectangles, the documented variant of groupRectangles won't help us.We must use the third one, with rejectLevels set to zeros: vector levels(wins.size(), 0); groupRectangles(wins, levels, scores, groupThreshold, eps); In which scores is the scores of wins. They have same size.

So I have been trying to write the wrapper in a similar fashion to Kyamagu's mexopencv using the -Developing a new MEX function- as mentioned here https://github.com/kyamagu/mexopencv

/**
 * @file groupRectangles.cpp
 * @brief mex interface for groupRectangles //manual 
 * @author Kota Yamaguchi
 * @date 2011
 */
#include "mexopencv.hpp"
using namespace std;
using namespace cv;

template <>
vector<Rect> MxArray::toVector<Rect>() const
{
    vector<Rect> vr;
    if (isNumeric())
        vr.push_back(toRect());
    else if (isCell()) {
        int n = numel();
        vector<MxArray> vm(toVector<MxArray>());
        vr.reserve(n);
        for (int i=0; i<n; ++i)
            vr.push_back(vm[i].toRect());
    }
    else
        mexErrMsgIdAndTxt("mexopencv:error","Invalid input");
    return vr;
}

/*
* edit start
*/

template <>
vector<Scalar> MxArray::toVector<Scalar>() const
{
    vector<Scalar> levels;
    if (isNumeric())
        levels.push_back(toScalar());
    else if (isCell()) {
        int n = numel();
        vector<MxArray> vm(toVector<MxArray>());
        levels.reserve(n);
        for (int i=0; i<n; ++i)
            levels.push_back(vm[i].toScalar());
    }
    else
        mexErrMsgIdAndTxt("mexopencv:error","Invalid input");
    return levels;
}

template <>
vector<Scalar> MxArray::toVector<Scalar>() const
{
    vector<Scalar> scores;
    if (isNumeric())
        scores.push_back(toScalar());
    else if (isCell()) {
        int n = numel();
        vector<MxArray> vm(toVector<MxArray>());
        scores.reserve(n);
        for (int i=0; i<n; ++i)
            scores.push_back(vm[i].toScalar());
    }
    else
        mexErrMsgIdAndTxt("mexopencv:error","Invalid input");
    return scores;
}





/*
* edit end
*/



/**
 * Main entry called from Matlab
 * @param nlhs number of left-hand-side arguments
 * @param plhs pointers to mxArrays in the left-hand-side
 * @param nrhs number of right-hand-side arguments
 * @param prhs pointers to mxArrays in the right-hand-side
 */
void mexFunction( int nlhs, mxArray *plhs[],
                  int nrhs, const mxArray *prhs[] )
{
    // Check the number of arguments
    if (nrhs<2 || (nrhs%2)!=0 || nlhs>1)
        mexErrMsgIdAndTxt("mexopencv:error","Wrong number of arguments");

    // Argument vector
    vector<MxArray> rhs(prhs,prhs+nrhs);
    vector<Rect> rectList(rhs[0].toVector<Rect>());



/*
* edit start
*/

  vector<Scalar> levels(rhs[1].toVector<Scalar>());
  vector<Scalar> scores(rhs[2].toVector<Scalar>());

/*
* edit end
*/

/*
* edited
*/


    int groupThreshold = rhs[3].toInt();
    double eps=0.2;

    for (int i=4; i<nrhs; i+=2) {
        string key(rhs[i].toString());
        if (key=="EPS")
            eps = rhs[i+1].toDouble();
        else
            mexErrMsgIdAndTxt("mexopencv:error","Unrecognized option %s", key.c_str());
    }

    groupRectangles(rectList,levels,scores,groupThreshold,eps);
    plhs[0] = MxArray(rectList);
}

and the error I am getting as is:

src/+cv/fullgroupRectangles.cpp:52:16: error: redefinition of ‘std::vector<Tp> MxArray::toVector() const [with T = cv::Scalar]’ src/+cv/fullgroupRectangles.cpp:34:16: error: ‘std::vector<Tp> MxArray::toVector() const [with T = cv::Scalar]’ previously declared here src/+cv/fullgroupRectangles.cpp: In function ‘void mexFunction(int, mxArray**, int, const mxArray**)’: src/+cv/fullgroupRectangles.cpp:123:62: error: no matching function for call to ‘groupRectangles(std::vector >&, std::vector >&, std::vector

&, int&, double&)’ src/+cv/fullgroupRectangles.cpp:123:62: note: candidates are: In file included from /usr/local/include/opencv2/opencv.hpp:54:0, from include/MxArray.hpp:14, from include/mexopencv.hpp:14, from src/+cv/fullgroupRectangles.cpp:7: /usr/local/include/opencv2/objdetect/objdetect.hpp:330:17: note: void cv::groupRectangles(std::vector >&, int, double) /usr/local/include/opencv2/objdetect/objdetect.hpp:330:17: note:
candidate expects 3 arguments, 5 provided /usr/local/include/opencv2/objdetect/objdetect.hpp:331:19: note: void cv::groupRectangles(std::vector >&, std::vector&, int, double) /usr/local/include/opencv2/objdetect/objdetect.hpp:331:19: note:
candidate expects 4 arguments, 5 provided In file included from /usr/local/include/opencv2/opencv.hpp:54:0, from include/MxArray.hpp:14, from include/mexopencv.hpp:14, from src/+cv/fullgroupRectangles.cpp:7: /usr/local/include/opencv2/objdetect/objdetect.hpp:332:17: note: void cv::groupRectangles(std::vector >&, int, double, std::vector, std::vector) /usr/local/include/opencv2/objdetect/objdetect.hpp:332:17: note: no known conversion for argument 2 from ‘std::vector ’ to ‘int’ /usr/local/include/opencv2/objdetect/objdetect.hpp:333:17: note: void cv::groupRectangles(std::vector >&, std::vector&, std::vector&, int, double) /usr/local/include/opencv2/objdetect/objdetect.hpp:333:17: note: no known conversion for argument 2 from ‘std::vector ’ to ‘std::vector&’

mex: compile of ' "src/+cv/fullgroupRectangles.cpp"' failed.

make: *** [+cv/fullgroupRectangles.mexa64] Error 255

I really appreciate, THANK YOU !

2

2 Answers

0
votes

groupRectangles() with 5 arguments takes vector levels, and vector scores. Just that need to be fixed.

  /**
   * @file groupRectangles.cpp
   * @brief mex interface for groupRectangles //manual 
   * @author Kota Yamaguchi
   * @date 2011
   */
  #include "mexopencv.hpp"
  using namespace std;
  using namespace cv;


  /*
  * edit end
  */



  /**
   * Main entry called from Matlab
   * @param nlhs number of left-hand-side arguments
   * @param plhs pointers to mxArrays in the left-hand-side
   * @param nrhs number of right-hand-side arguments
   * @param prhs pointers to mxArrays in the right-hand-side
   */
  void mexFunction( int nlhs, mxArray *plhs[],
                    int nrhs, const mxArray *prhs[] )
  {
      // Check the number of arguments
      if (nrhs<2 || (nrhs%2)!=0 || nlhs>1)
          mexErrMsgIdAndTxt("mexopencv:error","Wrong number of arguments");

      // Argument vector
      vector<MxArray> rhs(prhs,prhs+nrhs);
      vector<Rect> rectList(rhs[0].toVector<Rect>());



  /*
  * edit start
  */

    vector<int> levels(rhs[1].toVector<int>());
    vector<double> scores(rhs[2].toVector<double>());

  /*
  * edit end
  */

  /*
  * edited
  */


      int groupThreshold = rhs[3].toInt();
      double eps=0.2;

      for (int i=4; i<nrhs; i+=2) {
          string key(rhs[i].toString());
          if (key=="EPS")
              eps = rhs[i+1].toDouble();
          else
              mexErrMsgIdAndTxt("mexopencv:error","Unrecognized option %s", key.c_str());
      }

      groupRectangles(rectList,levels, scores,groupThreshold,eps);
      plhs[0] = MxArray(rectList);

  }
0
votes

Thank you, this returns a single instance value however. And every time I execute the returned values change. I believe I need to somehow visit all the elements I send from matlab and add them in the vector.