【问题标题】:"no matching function for call to min_element" when using a vector of CvPoints (opencv)使用 CvPoints (opencv) 向量时,“没有调用 min_element 的匹配函数”
【发布时间】:2012-03-12 14:47:36
【问题描述】:

这是我检索矩形角的函数,输入是一个阈值图像(上面有一个车牌),我希望输出是一个带有板角点的向量(在向量内)。排序:left_up、right_up、right_bottom、left_bottom。

我使用 openCV 来查找轮廓(效果很好);经过一些过滤器后,我使用 approxPoly 来查找矩形。我找到了四个点,这很好,但我想订购它们。我认为以下方法会起作用: 把所有的点放在一个向量中

找到比较函数Left指定的min_element并从向量中擦除

找到另一个左元素并擦除,然后确定哪个在上,哪个在下。

剩下的两点是正确的点。

bool left(CvPoint &pt1, CvPoint &pt2) {
    return pt1.x < pt2.x;
}

bool up(CvPoint &pt1, CvPoint &pt2) {
    return pt1.y < pt2.y;
}

std::vector<std::vector<CvPoint> > findNumberPlate(IplImage* img) {

vector<CvPoint> numberplate;
vector<vector<CvPoint> > numberplates_output;

CvMemStorage* storage = cvCreateMemStorage(0);
CvMemStorage* storage2 = cvCreateMemStorage(0);
CvSeq* contour = 0;
cvFindContours(img, storage, &contour, sizeof (CvContour), CV_RETR_EXTERNAL);
CvSeq* result = 0;

for (CvSeq* c = contour; c != NULL; c = c->h_next) {

    double area_contour = cvContourArea(c, CV_WHOLE_SEQ);
    CvBox2D c_box = cvMinAreaRect2(c);
    double area_box = c_box.size.height * c_box.size.width;

    if (area_contour / area_box > 0.83 && area_contour > 2000) {

        if (!storage2 == 0) cvClearMemStorage(storage2);
        else storage2 = cvCreateMemStorage(0);
        result = cvApproxPoly(c, sizeof (CvContour), storage2, CV_POLY_APPROX_DP, cvContourPerimeter(c)*0.03, 0);

        if (result->total == 4) {

            //find up/bottom & left/right                
            vector<CvPoint> points;

            for (int i = 0; i < 4; i++) {
                CvPoint* tempPoint = (CvPoint*) cvGetSeqElem(result, i);
                points.push_back(cvPoint(tempPoint->x,tempPoint->y));
            }

            vector<CvPoint>::iterator itLeft1 = std::min_element(points.begin(), points.end(), left);
            points.erase(itLeft1);
            vector<CvPoint>::iterator itLeft2 = std::min_element(points.begin(), points.end(), left);
            points.erase(itLeft2);

            vector<CvPoint>::iterator itLeftUp = std::min(itLeft1, itLeft2, left);
            vector<CvPoint>::iterator itLeftBottom = std::max(itLeft1, itLeft2, left);
            CvPoint left_up = *itLeftUp;
            CvPoint left_bottom = *itLeftBottom;

            vector<CvPoint>::iterator itRightUp = std::min(points.begin(), points.end(), up);
            vector<CvPoint>::iterator itRightBottom = std::max(points.begin(), points.end(), up);
            CvPoint right_up = *itRightUp;
            CvPoint right_bottom = *itRightBottom;

//etc
}

但是,当使用函数 min_element & max_element 时,我遇到了几个我不明白的错误。

findNumberPlate.cpp:57: error: no matching function for call to ‘min_element(__gnu_cxx::__normal_iterator<CvPoint*, std::vector<CvPoint, std::allocator<CvPoint> > >, __gnu_cxx::__normal_iterator<CvPoint*, std::vector<CvPoint, std::allocator<CvPoint> > >, <unresolved overloaded function type>)’
findNumberPlate.cpp:59: error: no matching function for call to ‘min_element(__gnu_cxx::__normal_iterator<CvPoint*, std::vector<CvPoint, std::allocator<CvPoint> > >, __gnu_cxx::__normal_iterator<CvPoint*, std::vector<CvPoint, std::allocator<CvPoint> > >, <unresolved overloaded function type>)’
findNumberPlate.cpp:62: error: no matching function for call to ‘min(__gnu_cxx::__normal_iterator<CvPoint*, std::vector<CvPoint, std::allocator<CvPoint> > >&, __gnu_cxx::__normal_iterator<CvPoint*, std::vector<CvPoint, std::allocator<CvPoint> > >&, <unresolved overloaded function type>)’
findNumberPlate.cpp:63: error: no matching function for call to ‘max(__gnu_cxx::__normal_iterator<CvPoint*, std::vector<CvPoint, std::allocator<CvPoint> > >&, __gnu_cxx::__normal_iterator<CvPoint*, std::vector<CvPoint, std::allocator<CvPoint> > >&, <unresolved overloaded function type>)’

我不能将 CvPoints 与 min_element 一起使用吗?或者……谁能帮帮我?

谢谢!

【问题讨论】:

  • 首先,您使用的是 cpp 而不是新的 opencv c++ 接口。第二:你导入#include &lt;algorithm&gt;了吗?
  • 我包含:#include #include #include #include #include #include
  • 对不起,我相信我给了你错误的答案。

标签: c++ opencv


【解决方案1】:

从错误消息中,很明显有 another overloaded function 同名 left,因此当您将 left 作为第三个参数传递给 std::min_element 时,编译器无法解析您的意思。

所以解决方案是帮助编译器消除歧义:

auto min = std::min_element(points.begin(), 
                            points.end(), 
                            static_cast<bool(*)(CvPoint&,CvPoint&)>(left) );

看起来很麻烦,所以您可以将其简化为:

bool (*leftptr)(CvPoint&,CvPoint&) = left; //compiler chooses the correct overload
auto min = std::min_element(points.begin(), points.end(), leftptr);

或者,这个:

typedef bool (*left_type)(CvPoint&,CvPoint&);

left_type leftptr = left; //compiler chooses the correct overload
auto min = std::min_element(points.begin(), points.end(), leftptr);

在所有这些情况下,编译器都会根据 target 类型选择正确的重载,无论是在 static_cast 还是在 leftptr 声明中。

【讨论】:

  • 感谢您的回答!你为什么使用“自动”?只是为了检查我是否理解你:我也可以“只是”更改我的比较函数的名称吗? (即左点)
  • 它适用于 min_element!但是,对于 min(),当输入两个 cvPoints 时,它不起作用。从‘const CvPoint’转换为非标量类型‘__gnu_cxx::__normal_iterator > >’请求
  • @Rogier:使用min,您想要比较值,而不是迭代器。 CvPoint left_up = std::min(*itLeft1, *itLeft2, left);
  • @MikeSeymour 谢谢!我试过了,但它给出了一个错误:在 /usr/include/c++/4.4/algorithm:61 包含的文件中,来自 /usr/local/include/opencv2/core/core.hpp:56,来自 /usr/local /include/opencv/cv.h:64,来自 findNumberPlate.h:11,来自 findNumberPlate.cpp:1:/usr/include/c++/4.4/bits/stl_algobase.h:235:错误:类型引用的初始化无效'CvPoint&' 来自 'const CvPoint' 类型的表达式
  • @Rogier:那是因为您的比较器通过非常量引用获取参数。将它们更改为 bool(CvPoint const &amp;pt1, CvPoint const &amp;pt2) 应该可以解决这个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-09
  • 1970-01-01
  • 2013-05-10
  • 1970-01-01
  • 2018-01-08
  • 1970-01-01
相关资源
最近更新 更多