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.feature.dense.binarypattern;
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.analyser.ImageAnalyser;
36 import org.openimaj.image.pixel.Pixel;
37
38
39
40
41
42
43 @Reference(
44 type = ReferenceType.Article,
45 author = { "Tan, Xiaoyang", "Triggs, Bill" },
46 title = "Enhanced local texture feature sets for face recognition under difficult lighting conditions",
47 year = "2010",
48 journal = "Trans. Img. Proc.",
49 pages = { "1635", "", "1650" },
50 url = "http://dx.doi.org/10.1109/TIP.2010.2042645",
51 month = "June",
52 number = "6",
53 publisher = "IEEE Press",
54 volume = "19"
55 )
56 public class LocalTernaryPattern implements ImageAnalyser<FImage> {
57 protected int[][] positiveBinaryPattern;
58 protected int[][] negativeBinaryPattern;
59 protected int[][] ternaryPattern;
60
61 protected float radius;
62 protected int samples;
63 protected float threshold;
64
65
66
67
68
69
70
71 public LocalTernaryPattern(float radius, int samples, float threshold) {
72 checkParams(radius, samples);
73 this.radius = radius;
74 this.samples = samples;
75 this.threshold = threshold;
76 }
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91 public static int[][][] calculateLTP(FImage image, float radius, int samples, float threshold) {
92 checkParams(radius, samples);
93
94 int [][][] pattern = new int[3][image.height][image.width];
95
96 for (int y=0; y<image.height; y++) {
97 for (int x=0; x<image.width; x++) {
98 int [] pn = calculateLTP(image, radius, samples, threshold, x, y);
99 pattern[0][y][x] = pn[0];
100 pattern[1][y][x] = pn[1];
101 pattern[2][y][x] = pn[2];
102 }
103 }
104
105 return pattern;
106 }
107
108
109
110
111
112
113
114
115
116
117
118
119
120 public static int[] calculateLTP(FImage image, float radius, int samples, float threshold, int x, int y) {
121 float centre = image.pixels[y][x];
122 int pattern[] = new int[3];
123
124 for (int i=0; i<samples; i++) {
125 double xx = -radius * Math.sin(2 * Math.PI * i / samples);
126 double yy = radius * Math.cos(2 * Math.PI * i / samples);
127
128 float pix = image.getPixelInterp(x+xx, y+yy);
129
130 float d = pix - centre;
131
132 if (d >= threshold) {
133 pattern[0] += Math.pow(2, i);
134 pattern[2] += Math.pow(3, i);
135 }
136 if (d <= threshold) {
137 pattern[1] += Math.pow(2, i);
138 pattern[2] += 2 * Math.pow(3, i);
139 }
140 }
141
142 return pattern;
143 }
144
145
146
147
148
149
150
151
152
153
154
155
156 public static int [] calculateLTP(FImage image, float radius, int samples, float threshold, Pixel point) {
157 return calculateLTP(image, radius, samples, threshold, point.x, point.y);
158 }
159
160 private static void checkParams(float radius, int samples) {
161 if (radius <= 0) {
162 throw new IllegalArgumentException("radius must be greater than 0");
163 }
164 if (samples <= 1 || samples > 31) {
165 throw new IllegalArgumentException("samples cannot be less than one or more than 31");
166 }
167 }
168
169
170
171
172 @Override
173 public void analyseImage(FImage image) {
174 int [][][] patterns = calculateLTP(image, radius, samples, threshold);
175
176 positiveBinaryPattern = patterns[0];
177 negativeBinaryPattern = patterns[1];
178 ternaryPattern = patterns[2];
179 }
180
181
182
183
184
185
186
187 public int[][] getPositivePattern() {
188 return positiveBinaryPattern;
189 }
190
191
192
193
194
195
196
197 public int[][] getNegativePattern() {
198 return negativeBinaryPattern;
199 }
200
201
202
203
204
205
206
207 public int[][] getTernaryPattern() {
208 return ternaryPattern;
209 }
210 }