有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何在图片/矩阵中递归地旅行

我正在尝试制作一个函数,通过获取每个像素并递归搜索,将图片分割成多个区域

如果8个黑眼圈中的任何一个相似(通过比较它们的色调值),然后用相同的颜色在它们上面画画

我从(0,0)开始简单,并尝试“旅行”递归到任何类似的像素,并将它们全部涂成红色,直到卡住为止

它在55x55图片上运行良好,但当我尝试300x55时,我得到了著名的StackOverflow异常

行程函数(经过一些编辑后,添加布尔矩阵以标记访问的像素):

     private static void area( int x, int y){
        //img and visited[][] are global variables
        int height = img.getHeight();
        int width = img.getWidth();
        visited[x][y] = true;
        int color = img.getRGB(x,y); // store before painting


      //  if(img.getRGB(x,y) != Color.RED.getRGB())
            img.setRGB(x, y, Color.RED.getRGB());
     //   else
     //       return;


        //spread to 8 directions clockwise
        //top
        if ((y - 1) >= 0)
            if(!visited[x][y-1] && hsbSimilarity(color,img.getRGB(x,y - 1)))
                area( x, y - 1);
        //top right
        if ((x + 1) < width && (y - 1) >= 0)
            if(!visited[x+1][y-1] && hsbSimilarity(color, img.getRGB(x + 1,y - 1)))
                area( x + 1, y - 1);
        //right
        if((x + 1) < width)
            if(!visited[x+1][y] && hsbSimilarity(color, img.getRGB(x + 1,y)))
                area( x + 1, y);
        //bot right
        if((x + 1) < width && (y + 1) < height)
            if(!visited[x+1][y+1] && hsbSimilarity(color, img.getRGB(x + 1,y + 1)))
                area(x + 1, y + 1);
        //bot
        if((y + 1) < height)
            if(!visited[x][y+1] && hsbSimilarity(color, img.getRGB(x,y + 1)))
                area(x, y + 1);
        //bot left
        if((x - 1) >= 0 && (y + 1) < height)
            if(!visited[x-1][y+1] && hsbSimilarity(color, img.getRGB(x - 1,y + 1)))
                area(x - 1, y + 1);
        //left
        if((x - 1) >= 0)
            if(!visited[x-1][y] && hsbSimilarity(color, img.getRGB(x - 1,y)))
                area( x - 1, y);
        //top left
        if((x - 1) >= 0 && (y - 1) >= 0)
            if(!visited[x-1][y-1] && hsbSimilarity(color, img.getRGB(x - 1,y - 1)))
                area(x - 1, y - 1);
    }

比较功能:

    private static boolean hsbSimilarity( int rgb1, int rgb2){
        Color color1 = new Color(rgb1);
        Color color2 = new Color(rgb2);
        float[] hsb1 = new float[3];
        float[] hsb2 = new float[3];
        color1.RGBtoHSB(color1.getRed(), color1.getGreen(), color1.getBlue(), hsb1);
        color2.RGBtoHSB(color2.getRed(), color2.getGreen(), color2.getBlue(), hsb2);
        int hue1 = (int)(hsb1[0] * 360);
        int hue2 = (int)(hsb2[0] * 360);
        int hueDistance = Math.abs(hue1 - hue2);

        return hueDistance < 5 || hueDistance > 355 ; //circle concept where 0 equals to 360
    }

共 (1) 个答案

  1. # 1 楼答案

    你似乎有周期问题。这意味着您的代码可能正在循环运行(例如0 | 0 0 | 1 0 | 0等,或类似的东西)。此外,这与尺寸无关,所以我非常确定,对于一张巨大的噪音图片来说,一切都是好的,对于一张完全红色的图片来说,一切都是好的。为了避免这个问题,我建议不要回到你已经检查过的像素,所以可以尝试填充一个包含你已经访问过的像素的列表,然后检查你要去的像素是否已经在里面,如果已经在里面,就不要去那里