OpenCV:arcLength 断言失败 cv::Mat

OpenCV: arcLength assert fails with cv::Mat

我尝试使用 arcLength 计算轮廓周长。轮廓从文件中读取到 Mat 中,它只是轮廓的黑白图片。 但是,当我将此 Mat 传递给函数时,它会抛出一个错误:

Assertion failed (curve.checkVector(2) >= 0 && (curve.depth() == CV_32F || curve.depth() == CV_32S)) in arcLength

我发现真正的原因是 curve.checkVector(2) returns -1。虽然我已经阅读了有关此方法的文档,但我仍然不明白如何修复此错误。
这是带有角点 (1,1), (1,21), (21,21), (21,1)

的测试图像

轮廓应该是(来自OpenCV doc):

Input vector of 2D points, stored in std::vector or Mat.

不是 b/w 图片。

你可以用不同的方法计算周长。最稳健的方法是使用 findContours 仅查找外部轮廓 (RETR_EXTERNAL),然后在该轮廓上调用 arcLength

举几个例子:

#include <opencv2\opencv.hpp>
#include <vector>

using namespace std;
using namespace cv;

int main()
{
    Mat1b img = imread("path_to_image", IMREAD_GRAYSCALE);

    // Method 1: length of unsorted points
    // NOTE: doesn't work!

    vector<Point> points;
    findNonZero(img, points);
    double len1 = arcLength(points, true);
    // 848.78

    // Method 2: length of the external contour

    vector<vector<Point>> contours;
    findContours(img.clone(), contours, RETR_EXTERNAL, CHAIN_APPROX_NONE); // Retrieve only external contour
    double len2 = arcLength(contours[0], true);
    // 80



    // Method 3: length of convex hull of contour
    // NOTE: convex hull based methods work reliably only for convex shapes.

    vector<Point> hull1;
    convexHull(contours[0], hull1);
    double len3 = arcLength(hull1, true);
    // 80

    // Method 4: length of convex hull of unsorted points
    // NOTE: convex hull based methods work reliably only for convex shapes.

    vector<Point> hull2;
    convexHull(points, hull2);
    double len4 = arcLength(hull2, true);
    // 80


    // Method 5: number of points in the contour
    // NOTE: this will simply count the number of points in the contour.
    // It works only if: 
    //     1) findContours was used with option CHAIN_APPROX_NONE.
    //     2) the contours is thin (has thickness of 1 pixel).

    double len5 = contours[0].size(); 
    // 80

    return 0;
}