Я работаю над примером кода для OpenCV2 & С ++ и я застрял. Компилятор (MinGW, g ++ 4.7.2 на Win7) говорит, что вызов перегруженного ‘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;
}
Что я делаю не так?
РЕДАКТИРОВАТЬ: Я хотел бы, чтобы некоторые из тех, кто дал мне голосование, попытаться решить эту проблему.
Это не единственный вопрос такого рода, но за мой голос уже проголосовали трижды?
Более того, это пример из книги, написанной профессором из Канады ( http://www.laganiere.name/opencvCookbook/ ), кто преподает оба OpenCV, я должен быть лучше, чем он? Мне должно быть стыдно, что я спрашиваю это? Я новичок в C ++ и OpenCV? Должен ли я спросить на десяти других форумах, а затем, только тогда, если я не найду ответ, спросите здесь на Stackoverflow?
Более того, я не ленивый, я помог этому человеку переписав его код ( OpenCV: запись видео в одном окне и отображение того же видео во втором окне, но только с контурами ). Я помог тому, кто знает меньше меня. Но в этом случае я просто не знаю, как решить эту проблему в этом коде, и все же в течение 30 минут я получил три отрицательных голоса?
ОБНОВЛЕНИЕ: Как указало мне сообщество OpenCV, на самом деле должно быть разрешено конвертировать Point в Point2f и наоборот, но ошибка в версии 2.4.3 ( http://code.opencv.org/issues/2616#note-1 ) препятствует этому. Это объясняет, почему этот код компилировался для оригинального автора несколько лет назад, а не для меня.
В любом случае, пользователь @alrikai предоставил правильный ответ и обходной путь для этого.
Ошибка была исправлена как: cv :: circle (результат, cv :: Point2f (центр), static_cast (радиус), cv :: Scalar (0), 2); поэтому cv :: Point (центр) становится этим cv :: Point2f (центр)
Как указано выше, проблема заключалась в том, что вы делаете cv::Point
из cv::Point2f
, cv::Point
объявлен как typedef Point2i Point;
Это означает, что это эквивалентно cv::Point2i
, Итак, по сути, вы пытаетесь сделать cv::Point2i
из cv::Point2f
, который является недействительным.
Кроме того, рад слышать, что это сработало для вас
Других решений пока нет …