Java 代码卡在循环中
我制作了一个脚本,可以拍照,从左上角开始(在我的测试图像中是一个白色像素),然后像魔杖工具一样通过图像,选择颜色足够相似的像素 但即使循环次数超过图像中的像素数,脚本也不会完成执行 测试图像约为160K像素Java 代码卡在循环中,java,Java,我制作了一个脚本,可以拍照,从左上角开始(在我的测试图像中是一个白色像素),然后像魔杖工具一样通过图像,选择颜色足够相似的像素 但即使循环次数超过图像中的像素数,脚本也不会完成执行 测试图像约为160K像素Tools.loadImage()是一种自行编写的方法。我在其他地方用过,很可能有用。下面不是我的全部代码,而是与问题相关的部分 static int[][][] image; public static void main(String[] args) { image = Tool
Tools.loadImage()
是一种自行编写的方法。我在其他地方用过,很可能有用。下面不是我的全部代码,而是与问题相关的部分
static int[][][] image;
public static void main(String[] args) {
image = Tools.loadImage(path1);
int height = image.length;
int width = image[0].length;
int[][][] newImage = new int[height][width][4];
ArrayList<Integer> toCheck = new ArrayList<Integer>();
ArrayList<Integer> checked = new ArrayList<Integer>();
int[] baseColor = image[0][0];
toCheck.add(0);
while (!toCheck.isEmpty()) {
i++;
int coords = toCheck.get(0);
int x = coords % width;
int y = coords / width;
if (check(x, y, baseColor, 128)) {
coords = y * width + x - 1;
if (x > 0 && !(checked.contains(coords) || toCheck.contains(coords))) {
toCheck.add(coords);
}
coords = y * width + x + 1;
if (x < width - 1 && !(checked.contains(coords) || toCheck.contains(coords))) {
toCheck.add(coords);
}
coords = (y - 1) * width + x;
if (y > 0 && !(checked.contains(coords) || toCheck.contains(coords))) {
toCheck.add(coords);
}
coords = (y + 1) * width + x;
if (y < height - 1 && !(checked.contains(coords) || toCheck.contains(coords))) {
toCheck.add(coords);
}
}
checked.add(coords);
toCheck.remove(0);
}
}
static boolean check(int x, int y, int[] color, int threshold) {
for (int i = 0; i < 3; i++) {
if (Math.abs(image[y][x][i] - color[i]) > threshold) {
return false;
}
}
return true;
}
静态int[][]图像;
公共静态void main(字符串[]args){
image=Tools.loadImage(路径1);
int height=image.length;
int width=图像[0]。长度;
int[][]newImage=newint[height][width][4];
ArrayList toCheck=新建ArrayList();
选中ArrayList=新建ArrayList();
int[]baseColor=图像[0][0];
toCheck.add(0);
而(!toCheck.isEmpty()){
i++;
int coords=toCheck.get(0);
int x=坐标%width;
int y=坐标/宽度;
如果(勾选(x,y,基色,128)){
坐标=y*宽度+x-1;
如果(x>0&&!(选中.contains(coords)| | toCheck.contains(coords))){
toCheck.add(坐标);
}
坐标=y*宽度+x+1;
如果(x0&&!(选中.contains(coords)| | toCheck.contains(coords))){
toCheck.add(坐标);
}
坐标=(y+1)*宽度+x;
如果(y阈值){
返回false;
}
}
返回true;
}
如果你想指出一些明显的方法来加快这个循环,那也会很感激。添加到复选框的位置不正确
while (!toCheck.isEmpty()) {
i++;
int coords = toCheck.get(0);
checked.add(coords); // important
toCheck.remove(0); // might as well do this here too
int x = coords % width;
int y = coords / width;
coords在循环中被重复覆盖,因此当前像素不会被添加,而是四个相邻像素中的最后一个。因此,某些条件稍后会失败,并且会添加一些错误的像素进行检查 您正在覆盖循环体中的
coords
,因此在每次迭代结束时,您标记了错误的像素。在弹出下一个点进行检查后,立即移动标记非常安全
Excel,考虑使用<代码> BITSET <代码>检查< /COD>(按@ JB NIZET的建议)和< <代码> ArrayDeque <代码> >代码>检查< <代码> .< /P> <代码>时间,这样您就可以使用HashSet了,这将是检查坐标输入的最佳方法。好的,哇,速度提高了一千倍,谢谢。不过仍然卡在这个循环中。@nhouser9,因为OP不想检查每个像素。@DawoodibnKareem一个位集将是一个更好的选择。请阅读(并遵循)这个感叹词,它总是一些简单的事情,每次检查代码时都会被忽略。非常感谢,我已经为此苦恼了几个小时。为什么不使用
位集
进行检查
和检查
?您需要能够从检查
快速获得下一点BitSet
确实有这样一种方法,但它需要对集合进行线性搜索,这可能是您想要避免的。ArrayQue
将在固定时间内为其提供服务,同时将避免使用ArrayList
对数组进行移位。好的,这很公平。