用于 Opencv 的 groupRectangles 的 Mex

Posted

技术标签:

【中文标题】用于 Opencv 的 groupRectangles 的 Mex【英文标题】:Mex for Opencv's groupRectangles 【发布时间】:2015-12-31 03:39:22 【问题描述】:

我正在使用 matlab 的 mexopencv,但是我注意到 groupRectangles Matlab 包装器仅支持 3 个输入参数,而源有 3 个不同的版本。

我不懂 C++,但我尝试遵循指南和编写的代码,但我无法编译它;它给出了一个特殊的错误。

如果有人能提供帮助,我将不胜感激,我需要为我的项目返回最终边界框的分数。

所以!我在网上找到了一个非常相似的问题和答案:

在 OpenCV 的 cascadedetect.cpp 中,groupRectangles 函数有几种变体: 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); 但是在 OpenCV 文档中,只清楚地记录了第一个变体,提到了第二个变体但没有解释权重参数。甚至没有提到第三个。

我们想要获得分组矩形的分数,groupRectangles 的文档变体对我们没有帮助。我们必须使用第三个,将rejectLevels 设置为零: 矢量级别(wins.size(),0); groupRectangles(wins, levels, scores, groupThreshold, eps); 其中 score 是获胜的分数。它们的大小相同。

所以我一直在尝试使用 -Developing a new MEX function- 以与 Kyamagu 的 mexopencv 类似的方式编写包装器 - 如此处所述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);

我得到的错误是:

src/+cv/fullgroupRectangles.cpp:52:16: 错误:重新定义 'std::vectorTp> MxArray::toVector() const [with T = cv::Scalar]' src/+cv/fullgroupRectangles.cpp:34:16: 错误: 'std::vectorTp> MxArray::toVector() const [with T = cv::Scalar]' 之前在这里声明过 src/+cv/fullgroupRectangles.cpp: 在函数'void mexFunction(int, mxArray**, int, const mxArray**)’: src/+cv/fullgroupRectangles.cpp:123:62: 错误:没有匹配函数 调用‘groupRectangles(std::vector >&, 标准::向量>&,标准::向量

&, int&, double&)' src/+cv/fullgroupRectangles.cpp:123:62: 注意:候选者是:在文件中包含 /usr/local/include/opencv2/opencv.hpp:54:0, 来自 include/MxArray.hpp:14, 来自 include/mexopencv.hpp:14, 来自 src/+cv/fullgroupRectangles.cpp:7: /usr/local/include/opencv2/objdetect/objdetect.hpp:330:17: 注意: void cv::groupRectangles(std::vector >&, int, double) /usr/local/include/opencv2/objdetect/objdetect.hpp:330:17:注意: 候选人期望 3 个参数,提供 5 个参数 /usr/local/include/opencv2/objdetect/objdetect.hpp:331:19:注意:无效 cv::groupRectangles(std::vector >&, std::vector&, 整数,双) /usr/local/include/opencv2/objdetect/objdetect.hpp:331:19:注意: 候选人需要 4 个参数,提供 5 个 /usr/local/include/opencv2/opencv.hpp:54:0, 来自 include/MxArray.hpp:14, 来自 include/mexopencv.hpp:14, 从 src/+cv/fullgroupRectangles.cpp:7:/usr/local/include/opencv2/objdetect/objdetect.hpp:332:17: 注意:无效 cv::groupRectangles(std::vector >&, int, double, 标准::向量, 标准::向量) /usr/local/include/opencv2/objdetect/objdetect.hpp:332:17:注意:否 来自‘std::vector 的参数 2 的已知转换 ' 到 'int' /usr/local/include/opencv2/objdetect/objdetect.hpp:333:17: 注意: void cv::groupRectangles(std::vector >&, std::vector&, std::vector&, int, double) /usr/local/include/opencv2/objdetect/objdetect.hpp:333:17:注意:否 来自‘std::vector 的参数 2 的已知转换 ’到‘std::vector&’

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

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

非常感谢,谢谢!

【问题讨论】:

【参考方案1】:

groupRectangles() 带有 5 个参数,采用向量级别和向量分数。只是需要修复。

  /**
   * @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);

  

【讨论】:

【参考方案2】:

谢谢,不过这会返回一个实例值。每次我执行返回的值都会发生变化。我相信我需要以某种方式访问​​我从 matlab 发送的所有元素并将它们添加到向量中。

【讨论】:

以上是关于用于 Opencv 的 groupRectangles 的 Mex的主要内容,如果未能解决你的问题,请参考以下文章

OpenCV groupRectangles - 获取分组和未分组的矩形

如何将边界框与 groupRectangle 合并?

OpenCV——级联分类器(CascadeClassifier)

有效地对重叠的矩形进行分组

用于 openCV 的 CMake

演示需要用于网络摄像头图像的 OpenCV。(已安装 opencv 并设置 opencv4=1)