我仍在寻找更好的答案,但我找到了一种平滑线条的解决方案,几乎没有噪音(所以仍然相当无用)。事实证明,当对上述二值图像进行细化时,在交叉点处会发生以下两种情况之一:连接的组件被破坏,或者一般区域中的一个像素连接到 2 个像素而不是 1 个。解决方案:修改连接成分
//PLEASE NOTE: THE IMAGE MUST BE THINNED FIRST!! Read above paragraph
int width = img.length;
int height = img[0].length;
int intersections = 0;
for (int i = 1; i < width - 2; i++){
for (int j = 1; j < height - 2; j++){
if (img[i,j] > 50){
//initialize a queue for this connected component
ArrayList<Integer[]> queue = new ArrayList<>();
queue.add({i, j});
img[i, j] = 0;
while (!queue.isEmpty()){
Integer[] c = queue.remove(0);
int count = 0;
for (int x = -1; x < 2; x++){
for (int y = -1; y < 2; y++){
if (img[c[0]+ x, c[1] + y] > 50){
queue.add({c[0] + x, c[1] + y});
img[c[0] + x, c[1] + y] = 0
//count the number of pixels connected to this one
count += 1;
}
}
}
if (count > 1){
//if more than 1 pixel was connected, it's at an intersection
intersections += 1;
}
}
}
//add 1 intersection for every connected component found
intersections += 1;
}
}
//correct for the original number of connected components in the image
//minus 1; helps offset against tendency for false negatives
intersections -= original_number_of_connected_components - 1
return intersections / 2;
上面是用 Java 编写的以公开逻辑,但我在 IDL 中实现了它,所以我没有调试过这个(即没有承诺这个代码在放入实际方法时编译。事实上,如果你不这样做,它肯定不会'不要将数组作为图像和original_number_of_connected_components参数传入)。
编辑:正如人们所预料的那样,这在锯齿状或嘈杂的图像上做了一项可怕的工作。仍在寻找更好的解决方案。
编辑:我有一个做得很好的解决方案。它将在 10 月 19 日在 GitHub 上发布,那时我会变得不那么忙。它在一些不太薄的图像上关闭,但通常在同一个球场,并且目前不适用于自相交图像。这个答案将在 19 日完全改变,除非到那时我收到一个相当简单的解决方案,否则我将修改这个答案并接受它为正确的。