2013-08-05 3 views
3

Я работаю над некоторым примером кода для OpenCV2 & C++ и я застрял. Компилятор (MinGW, g ++ 4.7.2 на Win7) говорит, что вызов перегруженного «Point_ (cv :: Point2f &)» неоднозначен, но я не могу найти что-то нехорошо. Вот ошибка:вызов перегруженного «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; 
} 

Что я делаю неправильно?

EDIT: Я хотел бы, чтобы некоторые из тех, кто дал мне подавать заявку, попытаются решить эту проблему. Здесь речь идет не только о таком типе, но и о моем голосовании уже три раза проголосовали?

Кроме того, это пример из книги, написанной профессором из Канады (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 минут я получил три голоса?

ОБНОВЛЕНИЕ: Как указано мне сообществом OpenCV, на самом деле должно быть разрешено преобразовывать Point to 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)

+0

Есть линия 99, резюме :: строка (результат, * и.т.п., * (и.т.п. + 1), резюме :: Скалярное (0), 2) ;? – doctorlove

+0

Ответ указан в сообщении об ошибке. Почему бы вам не внимательно прочитать его и посмотреть, что произойдет. :-) –

+0

@doctorlove no, ошибка в строке: \t cv :: circle (result, cv :: Point (center), static_cast (radius), cv :: Scalar (0), 2); // <--- ОШИБКА ЗДЕСЬ –

ответ

1

Как уже отмечалось выше, проблема заключалась в том, что вы делаете cv::Point с cv::Point2f. cv::Point объявлен как typedef Point2i Point;, что означает, что это эквивалентно cv::Point2i. Поэтому, по сути, вы пытаетесь сделать cv::Point2i из cv::Point2f, что недействительно.

Кроме того, рад слышать это работает для вас

+0

Еще раз спасибо, я потратил целый день на программирование и прочитал эти руководства. Когда я смотрю на это сейчас, то смешно, какой надзор я сделал, настолько простой, но такой хлопотный. Cheers :) –

+1

alrikai, я должен не согласиться. перегруженный конструктор Pont2i (Point2f) неоднозначен, но назначение Point2f на Pont2i совершенно справедливо. – berak

+1

@berak Это правда. Но обратите внимание, что я никогда не упоминал о назначении, только что создание 'cv :: Point2i' из' cv :: Point2f' недопустимо. Хотя в ретроспективе мое утверждение довольно неоднозначно, я думаю, что вы раскалываете волосы. Но не стесняйтесь редактировать это в ответ, если считаете, что он добавляет значение – alrikai