1 package at
.mus
.recognition
;
3 import java
.util
.ArrayList
;
4 import java
.util
.Arrays
;
7 public class DTW
implements IRecognizer
{
10 public Result
recognize(List
<ICoordinate
> rawPoints
, List
<Template
> templates
, int n_
, double size
, ICoordinate origin
) {
11 int[] score
= new int[templates
.size()];
15 List
<ICoordinate
> points
= quantize(compress(rawPoints
));
16 for(Template t
: templates
) {
17 List
<ICoordinate
> pointList
= new ArrayList
<ICoordinate
>(Arrays
.asList(t
.points
));
18 score
[i
] = this.dist(points
, quantize(compress(pointList
)));
19 if(score
[i
] < score
[minIndex
]) minIndex
= i
;
24 System
.err
.println(s
);
27 return new Result(templates
.get(minIndex
), score
[minIndex
]);
30 private int dist(List
<ICoordinate
> s
, List
<ICoordinate
> t
) {
31 int m
= t
.size(), n
= s
.size();
32 int[][] dtw
= new int[n
][m
];
35 for(int i
=0; i
< m
; ++i
) { dtw
[0][i
] = Integer
.MAX_VALUE
; }
36 for(int i
=0; i
< n
; ++i
) { dtw
[i
][0] = Integer
.MAX_VALUE
; }
39 for(int i
=1; i
< n
; ++i
) {
40 for(int j
=1; j
< m
; ++j
) {
41 cost
= (int)s
.get(i
).distance(t
.get(j
));
42 dtw
[i
][j
] = cost
+ Math
.min(
43 dtw
[i
-1][j
], // insertion
44 Math
.min(dtw
[i
][j
-1], // deletion
45 dtw
[i
-1][j
-1])); // match
52 private List
<ICoordinate
> compress(List
<ICoordinate
> points
) {
53 List
<ICoordinate
> compressed
= new ArrayList
<ICoordinate
>();
54 int windowSize
= 10, stepSize
= 6;
56 for(int i
= 0, l
= points
.size(); i
+windowSize
< l
; i
+= stepSize
) {
57 ICoordinate total
= new Acceleration(0, 0, 0);
58 for(int j
= 0; j
< windowSize
; ++j
) {
59 total
= total
.add(points
.get(i
+j
));
61 compressed
.add(total
.divide(windowSize
));
67 private List
<ICoordinate
> quantize(List
<ICoordinate
> points
) {
68 List
<ICoordinate
> quantized
= new ArrayList
<ICoordinate
>();
70 for(ICoordinate coord
: points
) {
71 float[] coords
= coord
.coords();
72 for(float c
: coords
) { c
= quantize(c
); }
73 quantized
.add(new Acceleration(coords
));
78 private float quantize(float f
) {
79 if(f
< 0) return -quantizeSymm(f
);
80 return quantizeSymm(f
);
83 private float quantizeSymm(float f
) {
84 final float g
= 10f
;//9.8f;
85 if(f
> 2*g
) return 16;
86 if(f
> g
) return 11+(int)(5*(f
-g
)/g
); // 11-15
87 if(f
> 0) return 1+(int)(10*f
/g
); // 1-10