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 java.io.PrintWriter;
33 import java.io.StringWriter;
34 import java.util.ArrayList;
35 import java.util.Iterator;
36 import java.util.List;
37
38 import org.openimaj.image.pixel.Pixel;
39 import org.openimaj.math.geometry.shape.Polygon;
40 import org.openimaj.math.geometry.shape.Rectangle;
41
42
43
44
45
46
47 public class Contour extends Polygon {
48
49
50
51 public ContourType type;
52
53
54
55 public List<Contour> children = new ArrayList<Contour>();
56
57
58
59 public Contour parent;
60
61
62
63
64 public Pixel start;
65 Rectangle rect = null;
66
67
68
69
70
71
72
73 public Contour(ContourType type) {
74 this.type = type;
75 this.start = new Pixel(0, 0);
76 }
77
78
79
80
81
82
83
84
85
86
87
88 public Contour(ContourType type, int x, int y) {
89 this.type = type;
90 this.start = new Pixel(x, y);
91 }
92
93
94
95
96
97
98
99
100
101 public Contour(ContourType type, Pixel p) {
102 this.type = type;
103 this.start = p;
104 }
105
106
107
108
109
110
111
112
113
114
115 public Contour(int x, int y) {
116 this.type = null;
117 this.start = new Pixel(x, y);
118 }
119
120 protected void setParent(Contour bp) {
121 this.parent = bp;
122 bp.children.add(this);
123 }
124
125 @Override
126 public String toString() {
127 final StringWriter contour = new StringWriter();
128 final PrintWriter pw = new PrintWriter(contour);
129 pw.println(String.format("[%s] start: %s %s", this.type, this.start, this.points));
130 for (final Contour child : this.children) {
131 pw.print(child);
132 }
133 pw.flush();
134 return contour.toString();
135 }
136
137
138
139
140 public void finish() {
141 this.rect = this.calculateRegularBoundingBox();
142 }
143
144 private class ContourIterator implements Iterator<Contour> {
145 final List<Contour> toProcess = new ArrayList<Contour>();
146
147 ContourIterator() {
148 toProcess.add(Contour.this);
149 }
150
151 @Override
152 public boolean hasNext() {
153 return !toProcess.isEmpty();
154 }
155
156 @Override
157 public Contour next() {
158 final Contour next = toProcess.remove(toProcess.size() - 1);
159 toProcess.addAll(next.children);
160 return next;
161 }
162
163 @Override
164 public void remove() {
165 throw new UnsupportedOperationException("Removal not supported");
166 }
167 }
168
169
170
171
172
173
174
175 public Iterator<Contour> contourIterator() {
176 return new ContourIterator();
177 }
178
179
180
181
182
183
184
185 public Iterable<Contour> contourIterable() {
186 return new Iterable<Contour>() {
187 @Override
188 public Iterator<Contour> iterator() {
189 return contourIterator();
190 }
191 };
192 }
193
194 @Override
195 public boolean isHole() {
196 return type != null && type.equals(ContourType.HOLE);
197 }
198 }