ArrayLists的堆栈溢出错误

| 我正在尝试编写一些代码来浏览图像文件中的相同颜色的像素组。 我这样做的方法是逐像素遍历图像(以具有颜色的哈希码的1d整数数组的形式),以查找要搜索的颜色的像素。找到一个像素后,我会执行dfs来查找相同颜色的相邻像素,并将其添加到一个称为Blob的新对象中。我使用布尔数组来跟踪已经添加了哪些像素,因此我不会添加相同的斑点。 我为每个Blob对象使用ArrayList来跟踪像素数。然后,我使用另一个Blob的ArrayList来存储不同的组。 当我尝试在一个简单的示例(具有上半部白色和下半部底部的图片)上运行时,当尝试使用太大的图片时出现堆栈溢出错误。具体来说,当我尝试使用320x240的图像执行此操作时,将2752像素添加到Blob后,就会出现stackoverflow。 我只是在为自己想做的事情使用正确的数据结构吗?我读到ArrayLists可以在其中存储Integer.maxValue对象。 我的代码粘贴在下面。任何帮助是极大的赞赏。
//blobfind tests code to find similar pixels of a minimum size and groups them together for analysis later  
//purpose is to identify color coded objects through the webcam  

//util for ArrayList  
import java.util.*;  
import java.awt.Color;  
import java.io.*;  

public class Blobfind2 {  

  //width and height of image in pixels  
  private int width;  
  private int height;  
  //hash code for the color being searched for  
  private int colorCode;  
  //minimum blob size to be added  
  private int minPixels;  
  //image in form of array of hashcodes for each pixel  
  private int[] img;  
  //keeping track of which pixels have been added to a blob  
  private boolean[] added;  
  //keeping track of which pixels have been visited when looking for a new blob  
  private boolean[] visited;  

  //debugging variable  
  private int count;  

  public Blobfind2(int inwidth, int inheight, int inCCode, int inminPixels, int[] inimage)   {
    width = inwidth;  
    height = inheight;  
    colorCode = inCCode;  
    minPixels = inminPixels;  
    img = inimage;  
    count = 0;  
  }    

  //takes hashCodeof color, minimum pixel number, and an image in the form of integer array  
  public ArrayList findColor() {  
    //makes an arraylist of \"blobs\"  
    ArrayList bloblist = new ArrayList();  
    //keep track of which pixels have been added to a blob  
    boolean[] added = new boolean[width * height];  
    //checks through each pixel  
    for (int i = 0; i < img.length; i++) {  
      //if it matches and is not part of a blob, we run dfs to collect all the pixels in   that blob
      if ((img[i] == colorCode) && (added[i] == false)) {  
        //visited keeps track of which pixels in the blob have been visited  
        //refreshed each time a new blob is made  
        boolean[] visited = new boolean[width*height];  
        Blob currBlob = new Blob();  
        dfs(img, currBlob, i, Color.white.hashCode(), added, visited);  
        //adds the blob to the bloblist if it is of a certain size  
        if (currBlob.mass() >= minPixels) {  
          bloblist.add(currBlob);                          
        }  
      }  
    }  
    return bloblist;  
  }  

  //recursive algorithm to find other members of a blob  
  public void dfs (int[] img, Blob blob, int currPixel, int colorCode, boolean[] added,    boolean[] visited) {  
    //System.out.print(currPixel + \" - \" + count + \" \");   
    count++;  
    //check current pixel, this only happens on the first pixel  
    if (visited[currPixel] == false) {  
      blob.add(img[currPixel]);  
      added[currPixel] = true;  
      visited[currPixel] = true;  
    }  
    //checks down pixel  
    if ((currPixel + width < height*width) && (visited[currPixel + width] == false)) {  
      if (img[currPixel + width] == colorCode) {  
        blob.add(img[currPixel + width]);  
        currPixel = currPixel + width;  
        added[currPixel] = true;  
        visited[currPixel] = true;  
        dfs(img, blob, currPixel, colorCode, added, visited);  
      }  
    }  
    //checks up pixel  
    if ((currPixel - width > 0) && (visited[currPixel - width] == false)) {  
      if (img[currPixel - width] == colorCode) {  
        blob.add(img[currPixel - width]);  
        currPixel = currPixel - width;  
        added[currPixel] = true;  
        visited[currPixel] = true;  
        dfs (img, blob, currPixel, colorCode, added, visited);  
      }  
    }  
    //checks right pixel  
    if ((currPixel + 1 < width * height) && (visited[currPixel + 1] == false) && (((currPixel + 1) % width) != 0)) {  
      if (img[currPixel + 1] == colorCode) {  
        blob.add(img[currPixel + 1]);  
        currPixel = currPixel + 1;  
        added[currPixel] = true;  
        visited[currPixel] = true;  
        dfs(img, blob, currPixel, colorCode, added, visited);  
      }  
    }  
    //checks left pixel  
    if ((currPixel - 1 > 0) && (visited[currPixel - 1] == false) && (((currPixel - 1) % width) != width - 1)) {  
      if (img[currPixel - 1] == colorCode) {  
        blob.add(img[currPixel - 1]);  
        currPixel = currPixel - 1;  
        added[currPixel] = true;  
        visited[currPixel] = true;  
        dfs(img, blob, currPixel, colorCode, added, visited);  
      }  
    }  
    return;  
  }  

  //test case, makes a new image thats half black and half white  
  //should only return one blob of size width*height/2  
  public static void main(String[] args) {  
   int width = 320;  
   int height = 240;  
   //builds the image  
   int[] img = new int[width * height];  
   for (int i = 0; i < img.length; i++) {  
     if (i < img.length/4) {  
       img[i] = Color.white.hashCode();  
     } else {  
       img[i] = Color.black.hashCode();  
     }  
   }  

   //runs blobfind  
   Blobfind2 bf = new Blobfind2(width, height, Color.white.hashCode(), 1, img);  
   ArrayList bloblist = bf.findColor();  
   System.out.println(bloblist.size());  
   //need to typecast things coming out of arraylists  
   Blob firstblob = (Blob)bloblist.get(0);  
   System.out.println(firstblob.mass());  
  }  

 private class Blob {  
   private ArrayList pixels = new ArrayList();  
   private Blob() {  
   }  
   private int mass() {  
     return pixels.size();  
   }  
   private void add(int i) {  
     pixels.add(i);  
   }  
   private ArrayList getBlob() {  
     return pixels;  
   }  
 }  

}   
    
已邀请:
堆栈溢出错误与是否使用
List
Map
或任何其他特定数据结构无关。这些构造在堆上分配。您正在看到堆栈溢出错误,因为您进行了递归函数调用。每个递归函数调用都会在堆栈上分配内存。您可以增加-Xss值
(e.g java -Xss8m HelloWorld)
,也可以将算法重写为非递归算法(假设算法正确)。     
这看起来非常类似于泛洪算法。递归实现可能会使大型Blob崩溃(例如进行过多的递归调用),仅因为您必须为每个像素探索4个邻居。最坏的情况是图像全部在同一斑点中! 我会尝试使堆栈明确。您要避免递归,而应使用基于循环的简单方法。
public void dfs () {
     Stack<Pixel> pixels = new Stack<Pixel>();
     pixels.push(currentPixel);

     while (!pixels.isEmpty()) {
         Pixel x = pixels.pop();

         // Do whatever processing on this pixel
         Pixel upPixel = getUpPixel();
         if (upPixel == colorCode) {
             pixels.push(upPixel);
         }

         // And so on
     }

}
    

要回复问题请先登录注册