细化一条线 [英] Thinning a line

查看:112
本文介绍了细化一条线的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am writing software that detects an images outline, thins it to a "single pixel" thick, then performs operations on the resulting outline. My hope is to eventually get the following:

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

I have written software that detects the RGBA colors, converts it to HSB, asks for a limit that sets whether a pixel is an outline or not (typically some value around 0.25, and checking the B (brightness) value), and then stores true or false in a 2-dimensional array of booleans (true is an outline, false is not). This gets me to stage 2 just fine. I am currently stuck on stage 3, and am currently attempting to achieve the following:

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

Here is my current code, where the outline[][] variable is the original 2d array of trues/falses (stage 2) and thinned[][] is the outline in stage 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];
        }
}


推荐答案

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

I've devised a pretty simple solution that works well enough for my purposes. I have 3 arrays, outline[][], thinned[][], and thinIteration[][]. outline[][] and thinned[][] are both set when an image is loaded as explained in my question (stages 1 and 2). thinIteration[][] is then loaded with batches of pixels that need to be thinned and are considered as "border" pixels. The function then erases these pixels, and if it erased any pixels, it restarts the method. It continues to do this cycle until it finds no more pixels to thin.

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

The program knows whether or not to thin a pixel if it is itself an outline pixel, has at least 2 bordering pixels left/right/up/down and at least 2 bordering pixels diagonally, but not more than 3 left/right/up/down and diagonally (which would mean it is a contained pixel)

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();
}

这篇关于细化一条线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆