Libraryless. Click here for Pure Java version (5676L/31K).
1 | // from https://rosettacode.org/wiki/Zhang-Suen_thinning_algorithm#Java |
2 | |
3 | srecord noeq ZhangSuenThinner(IBinaryImage image) {
|
4 | settable bool blackIsFG = true; |
5 | |
6 | static final int[][] nbrs = {{0, -1}, {1, -1}, {1, 0}, {1, 1}, {0, 1},
|
7 | {-1, 1}, {-1, 0}, {-1, -1}, {0, -1}};
|
8 | |
9 | static final int[][][] nbrGroups = {
|
10 | {{0, 2, 4}, {2, 4, 6}},
|
11 | {{0, 2, 6}, {0, 4, 6}}};
|
12 | |
13 | new PtBuffer toWhite; |
14 | |
15 | run {
|
16 | bool firstStep; |
17 | int w = image.getWidth(), h = image.getHeight(); |
18 | |
19 | while ping (true) {
|
20 | firstStep = !firstStep; |
21 | |
22 | for (int r = 1; r < h - 1; r++) |
23 | for (int c = 1; c < w - 1; c++) {
|
24 | if (!getPixel(c, r)) |
25 | continue; |
26 | |
27 | int nn = numNeighbors(r, c); |
28 | if (nn < 2 || nn > 6) |
29 | continue; |
30 | |
31 | if (numTransitions(r, c) != 1) |
32 | continue; |
33 | |
34 | if (!atLeastOneIsWhite(r, c, firstStep ? 0 : 1)) |
35 | continue; |
36 | |
37 | toWhite.add(c, r); |
38 | } |
39 | |
40 | if (!firstStep && empty(toWhite)) break; |
41 | for (Pt p : toWhite) |
42 | clearPixel(p.x, p.y); |
43 | toWhite.clear(); |
44 | } |
45 | } |
46 | |
47 | int numNeighbors(int r, int c) {
|
48 | int count = 0; |
49 | for (int i = 0; i < nbrs.length - 1; i++) |
50 | if (getPixel(c + nbrs[i][0], r + nbrs[i][1])) |
51 | count++; |
52 | ret count; |
53 | } |
54 | |
55 | int numTransitions(int r, int c) {
|
56 | int count = 0; |
57 | for (int i = 0; i < nbrs.length - 1; i++) |
58 | if (!getPixel(c + nbrs[i][0], r + nbrs[i][1]) |
59 | && getPixel(c + nbrs[i+1][0], r + nbrs[i+1][1])) |
60 | count++; |
61 | ret count; |
62 | } |
63 | |
64 | bool atLeastOneIsWhite(int r, int c, int step) {
|
65 | int count = 0; |
66 | int[][] group = nbrGroups[step]; |
67 | for (int i = 0; i < 2; i++) |
68 | for (int j = 0; j < group[i].length; j++) {
|
69 | int[] nbr = nbrs[group[i][j]]; |
70 | if (!getPixel(c + nbr[0], r + nbr[1])) {
|
71 | count++; |
72 | break; |
73 | } |
74 | } |
75 | ret count > 1; |
76 | } |
77 | |
78 | bool getPixel(int x, int y) {
|
79 | ret image.getBoolPixel(x, y) != blackIsFG; |
80 | } |
81 | |
82 | void clearPixel(int x, int y) {
|
83 | image.setPixel(x, y, blackIsFG); |
84 | } |
85 | } |
Began life as a copy of #1034923
download show line numbers debug dex old transpilations
Travelled to 4 computer(s): bhatertpkbcr, ekrmjmnbrukm, mowyntqkapby, mqqgnosmbjvj
No comments. add comment
| Snippet ID: | #1034925 |
| Snippet name: | ZhangSuenThinner - binary image thinning algorithm [dev.] |
| Eternal ID of this version: | #1034925/9 |
| Text MD5: | ab3d2d6a3e28f4e4c25030192a5c6755 |
| Transpilation MD5: | c51f5018dce8febe7fffe749b3de823c |
| Author: | stefan |
| Category: | javax / imaging |
| Type: | JavaX fragment (include) |
| Public (visible to everyone): | Yes |
| Archived (hidden from active list): | No |
| Created/modified: | 2022-03-15 20:34:10 |
| Source code size: | 2133 bytes / 85 lines |
| Pitched / IR pitched: | No / No |
| Views / Downloads: | 663 / 810 |
| Version history: | 8 change(s) |
| Referenced in: | [show references] |