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