OpenARK-SDK.exe 中 0x00007FF74F27A526 处未处理的异常:0xC00000FD:堆栈溢出(参数:0x0000000000000001、0x000000EEC5803FD8)

Unhandled exception at 0x00007FF74F27A526 in OpenARK-SDK.exe: 0xC00000FD: Stack overflow (parameters: 0x0000000000000001, 0x000000EEC5803FD8)

以下代码片段会导致 Whosebug。

Unhandled exception at 0x00007FF74F27A526 in OpenARK-SDK.exe: 0xC00000FD: Stack overflow (parameters: 0x0000000000000001, 0x000000EEC5803FD8).

我该如何解决?这是我正在贡献的 open-source repository 的一部分,我希望不要在这里做重大改变:

/***
Recursively performs floodfill on depthMap
***/
void DepthCamera::floodFill(int x, int y, cv::Mat& depthMap, cv::Mat& mask, double max_distance)
{
    if (x < 0 || x >= depthMap.cols || y < 0 || y >= depthMap.rows || depthMap.at<cv::Vec3f>(y, x)[2] == 0.0)
        return;
    if (closeEnough(x, y, depthMap, 4, max_distance)) {
        mask.at<cv::Vec3f>(y, x) = depthMap.at<cv::Vec3f>(y, x);
        depthMap.at<cv::Vec3f>(y, x)[0] = 0;
        depthMap.at<cv::Vec3f>(y, x)[1] = 0;
        depthMap.at<cv::Vec3f>(y, x)[2] = 0;
    }
    else {
        return;
    }

    floodFill(x + 1, y, depthMap, mask, max_distance);
    floodFill(x - 1, y, depthMap, mask, max_distance);
    floodFill(x, y + 1, depthMap, mask, max_distance);
    floodFill(x, y - 1, depthMap, mask, max_distance);
}

/***
Check whether candidate point is close enough to neighboring points
***/
bool DepthCamera::closeEnough(int x, int y, cv::Mat& depthMap, int num_neighbors, double max_distance)
{
    int num_close = 0;
    if (x - 1 < 0 || depthMap.at<cv::Vec3f>(y, x - 1)[2] == 0 || Util::euclidianDistance3D(depthMap.at<cv::Vec3f>(y, x), depthMap.at<cv::Vec3f>(y, x - 1)) < max_distance) {
        num_close++;
    }
    if (x + 1 >= depthMap.cols || depthMap.at<cv::Vec3f>(y, x + 1)[2] == 0 || Util::euclidianDistance3D(depthMap.at<cv::Vec3f>(y, x), depthMap.at<cv::Vec3f>(y, x + 1)) < max_distance) {
        num_close++;
    }
    if (y - 1 < 0 || depthMap.at<cv::Vec3f>(y - 1, x)[2] == 0 || Util::euclidianDistance3D(depthMap.at<cv::Vec3f>(y, x), depthMap.at<cv::Vec3f>(y - 1, x)) < max_distance) {
        num_close++;
    }
    if (y + 1 >= depthMap.rows || depthMap.at<cv::Vec3f>(y + 1, x)[2] == 0 || Util::euclidianDistance3D(depthMap.at<cv::Vec3f>(y, x), depthMap.at<cv::Vec3f>(y + 1, x)) < max_distance) {
        num_close++;
    }

    if (num_close >= num_neighbors) {
        return true;
    }

    return false;
}

double Util::euclidianDistance3D(cv::Vec3f pt1, cv::Vec3f pt2)
{
    double dx = pt1[0] - pt2[0];
    double dy = pt1[1] - pt2[1];
    double dz = pt1[2] - pt2[2];

    return sqrtf(dx*dx + dy*dy + dz*dz);
}

调用者:

void DepthCamera::computeClusters(double max_distance, double min_size)
{
    clusters.clear();
    cv::Mat depthMap = cv::Mat::zeros(depthMap.rows, depthMap.cols, depthMap.type());
    cv::medianBlur(xyzMap, depthMap, 3);
    cv::Mat mask = cv::Mat::zeros(depthMap.rows, depthMap.cols, depthMap.type());
    for (int r = depthMap.rows - 1; r >= 0; r--) {
        for (int c = 0; c < depthMap.cols; c++) {
            if (depthMap.at<cv::Vec3f>(r, c)[2] > 0.2) {
                mask = cv::Mat::zeros(depthMap.rows, depthMap.cols, depthMap.type());
                floodFill(c, r, depthMap, mask, max_distance);
                cv::Mat channels[3];
                cv::split(mask, channels);
                if (cv::countNonZero(channels[2]) > min_size) {
                    cv::medianBlur(mask, mask, 3);
                    clusters.push_back(mask.clone());
                }
            }
        }
    }
}

如果需要更多信息,请告诉我。基本上,当我靠近相机时,就会发生 Whosebug 异常。

这是调用堆栈的屏幕截图:

这是我 screencast 尝试 run without debugging 的照片。

您的递归结束条件不完整或不正确。

如果您查看 floodfill,两种情况 return 和一种触发递归。这告诉我们递归块是不正确的。具体来说,closeEnough() 没有按预期工作,因为您触发了一个从未 return 为真的案例。

您会查看传递给 closeEnough 的变量,以了解为什么它们从不满足它。只要看一下代码,我就可以知道堆栈溢出的情况永远不会是这样:

  if (num_close >= num_neighbors) {

我可以猜出哪些条件没有得到满足,但您可以通过查看传递给 closeEnough 的值来更轻松地做到这一点。

如果这还不够,请给我们数值。

虽然我认为这不是最好的解决方法,但至少对我来说是一种解决方法。

欢迎分享其他答案。