用于 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 - 获取分组和未分组的矩形