OpenCV: 寻找轮廓函数错误

5

我正在使用opencv的2.4.3版本,并尝试在进行Canny边缘检测后使用“findContours”函数,如下所示:

struct Component
{
    cv::Rect boundingBox;
    double area;
    double circularity;
}

cv::vector < Component > components;
cv::vector < cv::Vec4i > hierarchy;
cv::findContours ( cannyEdges, components, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_NONE);

然后它在“cv::findContours”这一行抛出错误,就像这样:
OpenCV Error: Assertion failed (mtype == type0 || ( CV_MAT_CN(mtype) == CV_MAT_CN(type0) && ((1((type0) & fixedDepthMask) != 0 )) in unknown function, file ...\opencv\modeuls\core\src\matrix.cpp, line 1421

如何解决这个问题?

1
我们无法通过您提供的内容重现错误。请提供一个简短、自包含、正确(可编译)的示例 - karlphillip
@karlphillip:对于那个链接点赞 - Abid Rahman K
1个回答

11

cv::findContours函数返回每个轮廓作为点的向量(请参见http://docs.opencv.org/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html#findcontours)。

您需要自己将这些向量转换为您的数据结构(Component),就像我创建的这个最小示例一样:

#include <opencv2/opencv.hpp>
#include <iostream>
struct Component
{
    cv::Rect boundingBox;
    double area;
    double circularity;
};
int main()
{
    // Create a small image with a circle in it.
    cv::Mat image(256, 256, CV_8UC3, cv::Scalar(0, 0, 0));
    cv::circle(image, cv::Point(80, 110), 42, cv::Scalar(255,127, 63), -1);

    // Find canny edges.
    cv::Mat cannyEdges;
    cv::Canny(image, cannyEdges, 80, 60);

    // Show the images.
    cv::imshow("img", image);
    cv::imshow("cannyEdges", cannyEdges);

    // Find the contours in the canny image.
    cv::vector<cv::Vec4i> hierarchy;

    // "Each contour is stored as a vector of points."
    // http://docs.opencv.org/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html#findcontours
    typedef cv::vector<cv::vector<cv::Point> > TContours;
    TContours contours;
    cv::findContours(cannyEdges, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_NONE);
    // cannyEdges is destroyed after calling cv::findContours

    // Print number of found contours.
    std::cout << "Found " << contours.size() << " contours." << std::endl;

    // Convert contours to Components.
    typedef cv::vector<Component> TComponents;
    TComponents components;
    for (TContours::const_iterator it( contours.begin() ); it != contours.end(); ++it)
    {
        Component c;
        c.area = cv::contourArea(*it);
        c.boundingBox = cv::boundingRect(*it);
        c.circularity = 0.0; // Insert whatever you mean by circularity;
        components.push_back(c);
    }

    for (TComponents::const_iterator it( components.begin() ); it != components.end(); ++it)
        std::cout << it->area << std::endl; // and whatever you want.

    // Wait for user input.
    cv::waitKey();
}

亲爱的Dobi: 非常感谢您的回答。我尝试了您的代码,但是当执行 "typedef cv::vector(...)" 这一行时出现错误,报告说 "Error: argument list for class template "std::vector" is missing"。很抱歉我回复晚了,因为网络连接问题。 - E_learner
我猜你正在使用一个较旧的编译器,它不支持模板类型中的“>>”。我在上面的代码中进行了更正,即我将“typedef cv::vector<cv::vectorcv::Point> TContours;”更改为“typedef cv::vector<cv::vectorcv::Point > TContours;”。请再试一次。 - Tobias Hermann

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接