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