1 /*
2  * Video stabilizer
3  *
4  * Copyright (c) 2008 Lenny <leonardo.masoni@gmail.com>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  */
17 
18 #include <stdlib.h>
19 #include <math.h>
20 #include <string.h>
21 #if !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(_WIN32) && !defined(__NetBSD__) && !defined(__OpenBSD__)
22 #include <values.h>
23 #endif
24 
25 #include "estimate.h"
26 #include "vector.h"
27 #include "utils.h"
28 
29 #if !defined(MAXFLOAT)
30 #define MAXFLOAT HUGE_VAL
31 #endif
32 
es_init(int nc,int nr)33 es_ctx *es_init(int nc, int nr) {
34 
35     es_ctx *es = (es_ctx *)malloc(sizeof(es_ctx));
36 
37     es->tc = KLTCreateTrackingContext();
38 
39     es->tc->sequentialMode = TRUE;
40     es->tc->min_eigenvalue = 8;
41     es->tc->verbose = FALSE;
42 
43     KLTChangeTCPyramid(es->tc, 31);
44 
45     KLTUpdateTCBorder(es->tc);
46 
47     es->fr[0] = (KLT_PixelType *)malloc(nc * nr * sizeof(KLT_PixelType));
48     es->fr[1] = (KLT_PixelType *)malloc(nc * nr * sizeof(KLT_PixelType));
49 
50     es->fl = KLTCreateFeatureList(64);
51 
52     es->dv = (vc *)malloc(64 * sizeof(vc));
53     es->nv = 0;
54 
55     es->nc = nc;
56     es->nr = nr;
57 
58     es->ff = FALSE;
59 
60     return es;
61 }
62 
es_estimate(es_ctx * es,unsigned char * fr)63 vc es_estimate(es_ctx *es, unsigned char *fr) {
64 
65     KLT_PixelType *t;
66     int is, id;
67 
68     t = es->fr[0]; es->fr[0] = es->fr[1]; es->fr[1] = t;
69 
70     for (is = 0, id = 0; id < es->nc * es->nr; is += 3, id ++)
71         es->fr[1][id] = (fr[is + 0] * 30 + fr[is + 1] * 59 + fr[is + 2] * 11) / 100;
72 
73     if (es->ff == FALSE) {
74 
75         es->ff = TRUE;
76 
77     } else {
78 
79         vc bv = vc_set(0.0, 0.0);
80         float be = MAXFLOAT;
81 
82         int i, i2;
83 
84         KLTSelectGoodFeatures(
85             es->tc, es->fr[0], es->nc, es->nr, es->fl
86             );
87 
88         for (i = 0; i < es->fl->nFeatures; i ++)
89             es->dv[i] = vc_set(es->fl->feature[i]->x, es->fl->feature[i]->y);
90 
91         KLTTrackFeatures(
92             es->tc, es->fr[0], es->fr[1], es->nc, es->nr, es->fl
93             );
94 
95         es->nv = 0;
96 
97         for (i = 0; i < es->fl->nFeatures; i ++) {
98 
99             if (es->fl->feature[i]->val == KLT_TRACKED) {
100 
101                 es->dv[es->nv] = vc_set(
102                     es->fl->feature[i]->x - es->dv[i].x,
103                     es->fl->feature[i]->y - es->dv[i].y
104                     );
105 
106                 es->nv ++;
107             }
108         }
109 
110         for (i = 0; i < es->nv; i ++) {
111 
112             float ce = 0.0;
113 
114             for (i2 = 0; i2 < es->nv; i2 ++)
115                 ce += vc_len(vc_sub(es->dv[i2], es->dv[i]));
116 
117             if (ce < be) {
118 
119                 bv = es->dv[i];
120                 be = ce;
121             }
122         }
123 
124         return bv;
125     }
126 
127     return vc_zero();
128 }
129 
es_free(es_ctx * es)130 void es_free(es_ctx *es) {
131 
132     free(es->dv);
133 
134     free(es->fr[0]);
135     free(es->fr[1]);
136 
137     KLTFreeFeatureList(es->fl);
138     KLTFreeTrackingContext(es->tc);
139 
140     free(es);
141 }
142 
143