我正在编写检测图像轮廓的软件,将其变为单个像素"厚,然后对结果轮廓执行操作。我希望最终能得到以下结论:
我编写了检测RGBA颜色的软件,将其转换为HSB,要求设置一个像素是否为轮廓的限制(通常是0.25左右的某个值,并检查B(亮度)值),以及然后将真或假存储在二维的布尔数组中(true表示大纲,false表示不是)。这让我到第二阶段就好了。我目前陷入第3阶段,目前正在尝试实现以下目标:
这是我当前的代码,其中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];
}
}
答案 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();
}