【问题标题】:call of overloaded ‘Point_(cv::Point2f&)’ is ambiguous重载“Point_(cv::Point2f&)”的调用不明确
【发布时间】:2013-08-05 16:21:34
【问题描述】:

我正在为 OpenCV2 和 C++ 编写一些示例代码,但我被卡住了。编译器(Win7 上的 MinGW,g++ 4.7.2)说 调用重载的“Point_(cv::Point2f&)”是模棱两可的,但我找不到确切的问题所在。这是错误:

18:09:33 **** Incremental Build of configuration Debug for project Blobs ****
Info: Internal Builder is used for build
g++ "-IC:\\OpenCV246PC\\build\\include" -O0 -g3 -Wall -c -fmessage-length=0 -o blobs.o "..\\blobs.cpp" 
..\blobs.cpp: In function ‘int main()’:
..\blobs.cpp:65:21: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
..\blobs.cpp:65:43: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
..\blobs.cpp:99:37: error: call of overloaded ‘Point_(cv::Point2f&)’ is ambiguous
..\blobs.cpp:99:37: note: candidates are:
In file included from ..\blobs.cpp:20:0:
C:\OpenCV246PC\build\include/opencv2/core/core.hpp:740:5: note: cv::Point_<_Tp>::Point_(const CvPoint2D32f&) [with _Tp = int; CvPoint2D32f = CvPoint2D32f]
C:\OpenCV246PC\build\include/opencv2/core/core.hpp:739:5: note: cv::Point_<_Tp>::Point_(const CvPoint&) [with _Tp = int; CvPoint = CvPoint]
C:\OpenCV246PC\build\include/opencv2/core/core.hpp:738:5: note: cv::Point_<_Tp>::Point_(const cv::Point_<_Tp>&) [with _Tp = int; cv::Point_<_Tp> = cv::Point_<int>]

// ERROR IS HERE
// It god mixed up when I pasted, so line number is not the one compiler complains.
    cv::circle(result, cv::Point(center), static_cast<int>(radius), cv::Scalar(0), 2);

这里是代码:

#include <iostream>
#include <vector>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>

int main()
{
    // Read input binary image
    cv::Mat image = cv::imread("binaryGroup.bmp", 0);
    if (!image.data)
        return 0;

    cv::namedWindow("Binary Image");
    cv::imshow("Binary Image", image);

    // Get the contours of the connected components
    std::vector<std::vector<cv::Point> > contours;
    cv::findContours(image, contours, // a vector of contours
            CV_RETR_EXTERNAL, // retrieve the external contours
            CV_CHAIN_APPROX_NONE); // retrieve all pixels of each contours

    // Print contours' length
    std::cout << "Contours: " << contours.size() << std::endl;
    std::vector<std::vector<cv::Point> >::const_iterator itContours = contours.begin();
    for (; itContours != contours.end(); ++itContours)
    {

        std::cout << "Size: " << itContours->size() << std::endl;
    }

    // draw black contours on white image
    cv::Mat result(image.size(), CV_8U, cv::Scalar(255));
    cv::drawContours(result, contours, -1, // draw all contours
            cv::Scalar(0), // in black
            2); // with a thickness of 2

    cv::namedWindow("Contours");
    cv::imshow("Contours", result);

    // Eliminate too short or too long contours
    int cmin = 100;  // minimum contour length
    int cmax = 1000; // maximum contour length
    std::vector<std::vector<cv::Point> >::iterator itc = contours.begin();
    while (itc != contours.end())
    {

        if (itc->size() < cmin || itc->size() > cmax)
            itc = contours.erase(itc);
        else
            ++itc;
    }

    // draw contours on the original image
    cv::Mat original = cv::imread("group.jpg");
    cv::drawContours(original, contours, -1, // draw all contours
            cv::Scalar(255, 255, 255), // in white
            2); // with a thickness of 2

    cv::namedWindow("Contours on Animals");
    cv::imshow("Contours on Animals", original);

    // Let's now draw black contours on white image
    result.setTo(cv::Scalar(255));
    cv::drawContours(result, contours, -1, // draw all contours
            cv::Scalar(0), // in black
            1); // with a thickness of 1
    image = cv::imread("binaryGroup.bmp", 0);

    // testing the bounding box
    cv::Rect r0 = cv::boundingRect(cv::Mat(contours[0]));
    cv::rectangle(result, r0, cv::Scalar(0), 2);

    // testing the enclosing circle
    float radius;
    cv::Point2f center;

    // http://opencv.willowgarage.com/documentation/cpp/structural_analysis_and_shape_descriptors.html#cv-minenclosingcircle
    // void minEnclosingCircle(const Mat& points, Point2f& center, float& radius)
    cv::minEnclosingCircle(cv::Mat(contours[1]), center, radius);

    // http://opencv.willowgarage.com/documentation/cpp/drawing_functions.html#cv-circle
    // void circle(Mat& img, Point center, int radius, const Scalar& color, int thickness=1, int lineType=8, int shift=0)

// ERROR IS HERE
        cv::circle(result, cv::Point(center), static_cast<int>(radius), cv::Scalar(0), 2); // <--- ERROR IS HERE

//  cv::RotatedRect rrect= cv::fitEllipse(cv::Mat(contours[1]));
//  cv::ellipse(result,rrect,cv::Scalar(0),2);

    // testing the approximate polygon
    std::vector<cv::Point> poly;
    cv::approxPolyDP(cv::Mat(contours[2]), poly, 5, true);

    std::cout << "Polygon size: " << poly.size() << std::endl;

    // Iterate over each segment and draw it
    std::vector<cv::Point>::const_iterator itp = poly.begin();
    while (itp != (poly.end() - 1))
    {
        cv::line(result, *itp, *(itp + 1), cv::Scalar(0), 2);
        ++itp;
    }
    // last point linked to first point
    cv::line(result, *(poly.begin()), *(poly.end() - 1), cv::Scalar(20), 2);

    // testing the convex hull
    std::vector<cv::Point> hull;
    cv::convexHull(cv::Mat(contours[3]), hull);

    // Iterate over each segment and draw it
    std::vector<cv::Point>::const_iterator it = hull.begin();
    while (it != (hull.end() - 1))
    {
        cv::line(result, *it, *(it + 1), cv::Scalar(0), 2);
        ++it;
    }
    // last point linked to first point
    cv::line(result, *(hull.begin()), *(hull.end() - 1), cv::Scalar(20), 2);

    // testing the moments

    // iterate over all contours
    itc = contours.begin();
    while (itc != contours.end())
    {

        // compute all moments
        cv::Moments mom = cv::moments(cv::Mat(*itc++));

        // draw mass center
        cv::circle(result,
        // position of mass center converted to integer
                cv::Point(mom.m10 / mom.m00, mom.m01 / mom.m00), 2, cv::Scalar(0), 2); // draw black dot
    }

    cv::namedWindow("Some Shape descriptors");
    cv::imshow("Some Shape descriptors", result);

    // New call to findContours but with CV_RETR_LIST flag
    image = cv::imread("binaryGroup.bmp", 0);

    // Get the contours of the connected components
    cv::findContours(image, contours, // a vector of contours
            CV_RETR_LIST, // retrieve the external and internal contours
            CV_CHAIN_APPROX_NONE); // retrieve all pixels of each contours

    // draw black contours on white image
    result.setTo(cv::Scalar(255));
    cv::drawContours(result, contours, -1, // draw all contours
            cv::Scalar(0), // in black
            2); // with a thickness of 2
    cv::namedWindow("All Contours");
    cv::imshow("All Contours", result);

    cv::waitKey();
    return 0;
}

我做错了什么?

编辑:我希望一些投反对票的人尝试解决这个问题。 这不是这种类型的唯一问题,但我的已经被否决了 3 次?

此外,这是来自加拿大教授 (http://www.laganiere.name/opencvCookbook/) 所写书籍的示例,他同时教授 OpenCV,我应该比他更擅长这方面吗?我应该为我问这个感到羞耻吗?我是 C++ 和 OpenCV 的新手?我是否应该在其他十个论坛上提问,然后,如果我在 Stackoverflow 上找不到答案,请在此处提问?

此外,我并不懒惰,我帮助这个人重写了他的代码(OpenCV: record footage in one window and Display the same video in 2nd window but with contours only)。我帮助了一个比我了解少的人。但是,在这种情况下,我只是不知道如何在这段代码中解决这个问题,但在 30 分钟内我得到了 3 票否决票?

更新:正如 OpenCV 社区向我指出的那样,实际上应该允许将 Point 转换为 Point2f,反之亦然,但是 2.4.3 版(http://code.opencv.org/issues/2616#note-1)中的错误阻止了它这样做。这就解释了为什么几年前这段代码是为原作者编译的,而不是为我编译的。 无论如何,用户@alrikai为此提供了正确的答案和解决方法。

错误被纠正为:cv::circle(result, cv::Point2f(center), static_cast(radius), cv::Scalar(0), 2);所以 cv::Point(center) 变成了这个 cv::Point2f(center)

【问题讨论】:

  • 是第 99 行,cv::line(result, *itp, *(itp + 1), cv::Scalar(0), 2);?
  • 答案在错误信息中。你为什么不仔细阅读它,看看会发生什么。 :-)
  • 我说先仔细阅读。根据错误,它期望中心或诸如 cvPoint、CvPoint2D32f 或 int 类型的 Point_ 之类的东西,但事实并非如此。所以问题是中心的类型是什么。
  • 问题很可能是您从cv::Point2f 生成cv::Pointcv::Point 被声明为typedef Point2i Point;,这意味着它等同于cv::Point2i。所以本质上,你是在尝试从cv::Point2f 中创建一个cv::Point2i,这(应该)是无效的
  • Downvote 撤回现在你已经告诉我有错误的那一行:-)

标签: c++ opencv g++-4.7


【解决方案1】:

如上所述,问题在于您正在从cv::Point2f 制作cv::Pointcv::Point 被声明为typedef Point2i Point;,这意味着它等同于cv::Point2i。所以本质上,你是在尝试从 cv::Point2f 中创建一个 cv::Point2i,这是无效的。

另外,很高兴听到它对你有用

【讨论】:

  • alrikai,我不同意。重载的构造函数 Pont2i(Point2f) 是不明确的,但是将 Point2f 分配给 Pont2i 是完全有效的。
  • @berak 是的。但请注意,我从未提到分配,只是从 cv::Point2f 创建 cv::Point2i 是无效的。虽然回想起来我的陈述相当模棱两可,但我认为你正在分裂头发。但是,如果您认为它增加了价值,请随时将其编辑到答案中
  • alrikai,这不是关于分裂头发,而是关于找到解决方案。 'cv::circle(result, center, static_cast(radius), cv::Scalar(0), 2);'完美运行(省略模棱两可的 ctor,并进行分配)
  • @berak 如果您想在我的回答中澄清这一点,请随时对其进行编辑或提出新的答案。但我仍然认为你在分裂头发,因为问题是关于他为什么会收到“重载'Point_(cv::Point2f&)' 的调用是模棱两可的”错误。这是因为他试图从 cv::Point2f 中创建一个 cv::Point,这就是我的回答。
  • @berak 似乎从 2.4.3 版开始影响 OpenCV 的错误阻止了从 Point 到 Point2f 的转换,反之亦然。这就是为什么它是为原作者而不是在他编写代码几年后为我编译的原因。 (code.opencv.org/issues/2616#note-1)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-08
  • 2014-11-13
  • 1970-01-01
相关资源
最近更新 更多