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
相关产品推荐
相关产品推荐

