Skip to content

Crash in connectedComponentsWithStats #16410

@arnaudbrejeon

Description

@arnaudbrejeon

OpenCV 4.1.1
OS: OSX
Compiler: clang

I found a crash in connectedComponentsWithStats on very specific images. It is a bit difficult reproduce because it depends on the number of threads (16 on my machine).
See the code below to reproduce systematically.

From my understanding, the problem comes from the colliding labels.
I will try to provide a fix this week.

cv::Mat createCrashMat(int numThreads) {
    const int h = numThreads * 4 * 2 + 8;
    const double nParallelStripes = std::max(1, std::min(h / 2, numThreads * 4));
    const int w = 4;

    const int nstripes = cvRound(nParallelStripes <= 0 ? h : MIN(MAX(nParallelStripes, 1.), h));
    const cv::Range stripeRange(0, nstripes);
    const cv::Range wholeRange(0, h);

    cv::Mat m(h, w, CV_8U);
    m = 0;

    // Look for a range that starts with odd value and ends with even value
    cv::Range bugRange;
    for (int s = stripeRange.start; s < stripeRange.end; s++) {
        cv::Range sr(s, s + 1);
        cv::Range r;
        r.start = (int) (wholeRange.start +
                         ((uint64) sr.start * (wholeRange.end - wholeRange.start) + nstripes / 2) / nstripes);
        r.end = sr.end >= nstripes ?
                    wholeRange.end :
                    (int) (wholeRange.start +
                           ((uint64) sr.end * (wholeRange.end - wholeRange.start) + nstripes / 2) / nstripes);

        if (r.start > 0 && r.start % 2 == 1 && r.end % 2 == 0 && r.end >= r.start + 2) {
            bugRange = r;
            break;
        }
    }

    if (bugRange.empty()) {
        std::cout << "Could not find a buggy range\n";
        return m;
    }

    // Fill in bug Range
    for (int x = 1; x < w; x++) {
        m.at<char>(bugRange.start - 1, x) = 1;
    }

    m.at<char>(bugRange.start + 0, 0) = 1;
    m.at<char>(bugRange.start + 0, 1) = 1;
    m.at<char>(bugRange.start + 0, 3) = 1;
    m.at<char>(bugRange.start + 1, 1) = 1;
    m.at<char>(bugRange.start + 2, 1) = 1;
    m.at<char>(bugRange.start + 2, 3) = 1;
    m.at<char>(bugRange.start + 3, 0) = 1;
    m.at<char>(bugRange.start + 3, 1) = 1;

    return m;
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions