You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Studio中Java无外部库轮廓检测:DFS调用崩溃求助

问题分析与解决

你的程序崩溃大概率是递归DFS引发的栈溢出(StackOverflowError)。当处理较大的图像或者较长的轮廓时,递归调用的深度会超过JVM默认的栈容量,直接导致程序崩溃。

修复方案:改用迭代式DFS

把递归的DFS实现改成基于栈的迭代实现,彻底避免递归深度限制的问题。修改后的代码如下:

public static List<Contour> findContours(Bitmap edgeImage) {
    List<Contour> contours = new ArrayList<>();

    int width = edgeImage.getWidth();
    int height = edgeImage.getHeight();

    boolean[][] visited = new boolean[width][height];

    for (int x = 0; x < width; x++) {
        for (int y = 0; y < height; y++) {
            if (!visited[x][y] && isEdgePixel(edgeImage, x, y)) {
                Contour contour = traceContour(edgeImage, visited, x, y);
                contours.add(contour);
            }
        }
    }

    return contours;
}

private static Contour traceContour(Bitmap edgeImage, boolean[][] visited, int startX, int startY) {
    List<Point> contourPoints = new ArrayList<>();

    // 迭代式DFS,用栈存储待访问的点
    Stack<Point> stack = new Stack<>();
    stack.push(new Point(startX, startY));
    visited[startX][startY] = true;

    int width = edgeImage.getWidth();
    int height = edgeImage.getHeight();

    while (!stack.isEmpty()) {
        Point current = stack.pop();
        int x = current.x;
        int y = current.y;

        // 确认当前点是有效边缘点(防止栈中残留已被标记的无效点)
        if (x < 0 || x >= width || y < 0 || y >= height || !isEdgePixel(edgeImage, x, y)) {
            continue;
        }

        contourPoints.add(current);

        // 按相反顺序压栈,保证遍历顺序和原递归一致(可选,不影响结果)
        stack.push(new Point(x, y - 1));
        stack.push(new Point(x, y + 1));
        stack.push(new Point(x - 1, y));
        stack.push(new Point(x + 1, y));

        // 标记已访问,避免重复入栈
        visited[x][y] = true;
    }

    return new Contour(contourPoints);
}

private static boolean isEdgePixel(Bitmap edgeImage, int x, int y) {
    int pixelValue = edgeImage.getPixel(x, y);
    return Color.red(pixelValue) == 0; // 假设黑色为边缘像素
}

额外检查点

  • 确认Contour和Point类已正确实现,没有空指针或其他逻辑错误
  • 如果图像尺寸极大,可考虑优化visited数组的内存占用(比如用BitSet代替二维boolean数组)
  • 检查isEdgePixel逻辑是否符合你的边缘图像实际情况(比如是否应该同时检查绿、蓝通道,或者判断是否为白色边缘等)

内容的提问来源于stack exchange,提问作者Sai Ganesh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 18:12:33