细化一条线

我正在编写检测图像轮廓的软件,将其变为“单个像素”厚,然后对生成的轮廓执行操作。 我希望最终能得到以下结果:

在此处输入图像描述

我编写了检测RGBA颜色的软件,将其转换为HSB,要求设置一个像素是否为轮廓的限制(通常是0.25左右的某个值,并检查B(亮度)值),然后存储为true或者在二维的布尔数组中是假的(true是大纲,false不是)。 这让我到第二阶段就好了。 我目前陷入第3阶段,目前正在尝试实现以下目标:

http://i.imgur.com/BTs6miR.png

这是我当前的代码,其中outline[][]变量是trues / falses的原始2d数组(阶段2), thinned[][]是阶段3中的轮廓。

 public void thinOutline() { thinned = new boolean[outline.length][outline[0].length]; for (int x = 0; x < thinned.length; x++) for (int y = 0; y  0 && x  0 && y < thinned[0].length - 1) if (!thinned[x + 1][y] && !thinned[x - 1][y] && !thinned[x][y + 1] && !thinned[x][y - 1] && outline[x][y]) thinned[x][y] = true; else thinned[x][y] = false; else thinned[x][y] = outline[x][y]; } } 

我已经设计了一个非常简单的解决方案,可以很好地满足我的目的。 我有3个数组, outline[][]thinned[][]thinIteration[][] 。 如我的问题(第1和第2阶段)所述,加载图像时, outline[][]thinned[][]被设置。 thinIteration[][]会加载需要稀疏的批量像素,并被视为“边框”像素。 然后该函数擦除这些像素,如果它擦除了任何像素,它将重新启动该方法。 它继续执行此循环,直到找不到更多的像素。

如果像素本身是轮廓像素,则程序知道是否稀疏像素,具有至少2个边界像素左/右/上/下和至少2个对角边界像素,但不超过3左/右/上/向下和对角线(这意味着它是一个包含的像素)

 public void thinOutline() { boolean didThinIteration = false; for (int x = 1; x < originalWidth - 1; x++) for (int y = 1; y < originalHeight - 1; y++) { int numOfBorders = (thinned[x - 1][y] ? 1 : 0) + (thinned[x + 1][y] ? 1 : 0) + (thinned[x][y + 1] ? 1 : 0) + (thinned[x][y - 1] ? 1 : 0); int numOfDiagonals = (thinned[x - 1][y + 1] ? 1 : 0) + (thinned[x + 1][y + 1] ? 1 : 0) + (thinned[x - 1][y - 1] ? 1 : 0) + (thinned[x + 1][y - 1] ? 1 : 0); boolean thin = thinned[x][y] && numOfBorders > 1 && numOfBorders < 4 && numOfDiagonals > 1 && numOfDiagonals < 4; thinIteration[x][y] = thin; if (thin && !didThinIteration) didThinIteration = true; } for (int x = 0; x < originalWidth; x++) for (int y = 0; y < originalHeight; y++) if (thinIteration[x][y]) thinned[x][y] = false; if (didThinIteration) thinOutline(); }