细化一条线

时间:2015-03-29 19:02:57

标签: java

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

enter image description here

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

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

这是我当前的代码,其中outline[][]变量是原始的2d trues / falses数组(第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 < thinned[0].length; y++) {
            if (x > 0 && x < thinned.length - 1 && y > 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];
        }
}

1 个答案:

答案 0 :(得分:0)

我设计了一个非常简单的解决方案,适用于我的目的。我有3个数组,outline[][]thinned[][]thinIteration[][]。如我的问题(第1阶段和第2阶段)所述,加载图像时都会设置outline[][]thinned[][]。然后thinIteration[][]加载了需要细化的像素批次,并被视为&#34; border&#34;像素。然后该函数擦除这些像素,如果它擦除任何像素,它将重新启动该方法。它继续执行此循环,直到找不到更多的像素。

如果像素本身是轮廓像素,则程序知道是否稀疏像素,左/右/上/下至少有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();
}