1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 package org.openimaj.image.contour;
31
32 import org.openimaj.citation.annotation.Reference;
33 import org.openimaj.citation.annotation.ReferenceType;
34 import org.openimaj.image.FImage;
35 import org.openimaj.image.pixel.Pixel;
36 import org.openimaj.util.function.Operation;
37 import org.openimaj.util.pair.IndependentPair;
38
39
40
41
42
43
44
45
46 @Reference(
47 type = ReferenceType.Article,
48 author = { "Suzuki, S.", "Abe, K." },
49 title = "Topological Structural Analysis of Digitized Binary Image by Border Following",
50 year = "1985",
51 journal = "Computer Vision, Graphics and Image Processing",
52 pages = { "32", "46" },
53 month = "January",
54 number = "1",
55 volume = "30")
56 public class SuzukiNeighborStrategy extends ContourFollowingStrategy {
57 @Override
58 public void contour(FImage image, Pixel start, Pixel from, final Operation<Pixel> operation) {
59 directedContour(image, start, from, new Operation<IndependentPair<Pixel, boolean[]>>() {
60
61 @Override
62 public void perform(IndependentPair<Pixel, boolean[]> object) {
63 operation.perform(object.firstObject());
64 }
65 });
66 }
67
68
69
70
71
72
73
74
75
76
77
78
79
80 public void
81 directedContour(FImage image, Pixel ij, Pixel i2j2, Operation<IndependentPair<Pixel, boolean[]>> operation)
82 {
83 Direction dir = Direction.fromTo(ij, i2j2);
84 Direction trace = dir.clockwise();
85
86 Pixel i1j1 = null;
87 while (trace != dir) {
88 final Pixel activePixel = trace.active(image, ij);
89 if (activePixel != null) {
90 i1j1 = activePixel;
91 break;
92 }
93 trace = trace.clockwise();
94 }
95 if (i1j1 == null)
96 return;
97
98
99 i2j2 = i1j1;
100 Pixel i3j3 = ij;
101 final boolean[] checked = new boolean[] {
102
103
104
105 false, false, false, false, false, false, false, false
106 };
107 while (true) {
108 dir = Direction.fromTo(i3j3, i2j2);
109 trace = dir.counterClockwise();
110 Pixel i4j4 = null;
111 resetChecked(checked);
112 while (true) {
113 i4j4 = trace.active(image, i3j3);
114 if (i4j4 != null)
115 break;
116 checked[trace.ordinal()] = true;
117 trace = trace.counterClockwise();
118 }
119 operation.perform(IndependentPair.pair(i3j3, checked));
120 if (i4j4.equals(ij) && i3j3.equals(i1j1))
121 break;
122 i2j2 = i3j3;
123 i3j3 = i4j4;
124 }
125 }
126
127 private void resetChecked(boolean[] checked) {
128 for (int i = 0; i < checked.length; i++) {
129 checked[i] = false;
130 }
131 }
132
133 }