1 
2 
3 /*******************************************************************
4 Tracker based on Variable Mean-Shift algorithm and Interpolate Template Matching
5 
6 Version: MT1
7 
8 Compiler: Microsoft Visual Studio.net
9 
10 Luigi Sgaglione
11 
12 **********************************************************************/
13 #include <memory>
14 
15 #include "ObjectTracker.h"
16 #include <math.h>
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <fstream>
20 #include <iostream>
21 #include <ios>
22 #include <algorithm>
23 
24 using namespace std;
25 
26 #define MEANSHIFT_ITERATION_NO 15
27 #define ALPHA 0.98
28 #define EDGE_DETECT_THRESHOLD 32
29 #define ITERACTION_THRESHOLD 0.4
30 #define MAX_FLOAT 3.40282e+38;
31 
32 //---------------------------------------------------------------------------------------------------------
33 // Costructor
CObjectTracker(int imW,int imH,bool _colorimage,bool _att_background,bool _man_occlusion)34 CObjectTracker::CObjectTracker(int imW, int imH, bool _colorimage,
35                                bool _att_background, bool _man_occlusion) {
36   att_background = _att_background;
37   colorimage     = _colorimage;
38   m_nImageWidth  = imW;
39   m_nImageHeight = imH;
40   track          = true;
41   man_occlusion  = _man_occlusion;
42   m_initialized  = false;
43 
44   for (int i = 0; i < 30; i++) {
45     neighbours[i].X     = -1;
46     neighbours[i].Y     = -1;
47     neighbours[i].dist2 = MAX_FLOAT;
48     neighbours[i].X_old = -1;
49     neighbours[i].Y_old = -1;
50   }
51 
52   if (!colorimage)
53     HISTOGRAM_LENGTH = 512;
54   else
55     HISTOGRAM_LENGTH = 8192;
56 
57   m_sTrackingObject.initHistogram.reset(new float[HISTOGRAM_LENGTH]);
58   if (att_background)
59     m_sTrackingObject.weights_background.reset(new float[HISTOGRAM_LENGTH]);
60   else
61     m_sTrackingObject.weights_background.reset();
62 
63   m_sTrackingObject.Status = false;
64   for (short j                         = 0; j < HISTOGRAM_LENGTH; j++)
65     m_sTrackingObject.initHistogram[j] = 0;
66 };
67 
68 //--------------------------------------------------------------------------------------------------------
69 // Distructor
~CObjectTracker()70 CObjectTracker::~CObjectTracker() {}
71 
72 //--------------------------------------------------------------------------------------------------------
73 // Get pixel value RGB
GetPixelValues(TRaster32P * frame,short x,short y)74 ValuePixel CObjectTracker::GetPixelValues(TRaster32P *frame, short x, short y) {
75   TPixel32 *data;
76   ValuePixel pixelValues;
77 
78   (*frame)->lock();
79   data = x + (*frame)->pixels(abs(y - m_nImageHeight + 1));
80 
81   pixelValues.b = data->b;
82   pixelValues.g = data->g;
83   pixelValues.r = data->r;
84 
85   (*frame)->unlock();
86 
87   return (pixelValues);
88 }
89 
90 //--------------------------------------------------------------------------------------------------------
91 // Set pixel value RGB
SetPixelValues(TRaster32P * frame,ValuePixel pixelValues,short x,short y)92 void CObjectTracker::SetPixelValues(TRaster32P *frame, ValuePixel pixelValues,
93                                     short x, short y) {
94   TPixel32 *data;
95 
96   (*frame)->lock();
97   data = x + (*frame)->pixels(abs(y - m_nImageHeight + 1));
98 
99   data->b = pixelValues.b;
100   data->g = pixelValues.g;
101   data->r = pixelValues.r;
102 
103   (*frame)->unlock();
104 }
105 
106 //--------------------------------------------------------------------------------------------------------
107 // Inizialization parameters object
ObjectTrackerInitObjectParameters(short id,short x,short y,short Width,short Height,short _dim,short _var_dim,float _dist,float _distB)108 void CObjectTracker::ObjectTrackerInitObjectParameters(
109     short id, short x, short y, short Width, short Height, short _dim,
110     short _var_dim, float _dist, float _distB) {
111   objID = id;
112 
113   m_sTrackingObject.dim_temp             = _dim;
114   m_sTrackingObject.var_dim              = _var_dim;
115   m_sTrackingObject.threshold_distance   = _dist;
116   m_sTrackingObject.threshold_distance_B = _distB;
117   m_sTrackingObject.X                    = x;
118   m_sTrackingObject.Y                    = y;
119   m_sTrackingObject.W                    = Width;
120   m_sTrackingObject.H                    = Height;
121   m_sTrackingObject.X_old                = x;
122   m_sTrackingObject.Y_old                = y;
123   m_sTrackingObject.W_old                = Width;
124   m_sTrackingObject.H_old                = Height;
125   m_sTrackingObject.X_temp               = x;
126   m_sTrackingObject.Y_temp               = y;
127   m_sTrackingObject.W_temp               = Width;
128   m_sTrackingObject.H_temp               = Height;
129 
130   m_sTrackingObject.half_pixelx = 0;
131   m_sTrackingObject.half_pixely = 0;
132 
133   m_sTrackingObject.Status           = true;
134   m_sTrackingObject.assignedAnObject = false;
135 }
136 
137 //--------------------------------------------------------------------------------------------------------
138 // Update frame template
updateTemp()139 void CObjectTracker::updateTemp() {
140   m_sTrackingObject.X_temp = m_sTrackingObject.X;
141   m_sTrackingObject.Y_temp = m_sTrackingObject.Y;
142   m_sTrackingObject.W_temp = m_sTrackingObject.W;
143   m_sTrackingObject.H_temp = m_sTrackingObject.H;
144 }
145 //--------------------------------------------------------------------------------------------------------
146 // Object Tracking
ObjeckTrackerHandlerByUser(TRaster32P * frame)147 void CObjectTracker::ObjeckTrackerHandlerByUser(TRaster32P *frame) {
148   if (m_sTrackingObject.Status) {
149     if (!m_sTrackingObject.assignedAnObject) {
150       FindHistogram(frame, m_sTrackingObject.initHistogram.get(), 1);
151       m_sTrackingObject.assignedAnObject = true;
152       /*
153       ofstream output;
154       output.open("output.txt",ios_base::app);
155       output<<m_sTrackingObject.X <<" "<<m_sTrackingObject.Y<<endl;
156       output<<m_sTrackingObject.W <<" "<<m_sTrackingObject.H<<endl;
157       output<<m_sTrackingObject.half_pixelx <<"
158       "<<m_sTrackingObject.half_pixely<<endl;
159       if (m_visible=="")
160       {
161               output<<"VISIBLE"<<endl;
162       }
163       else
164       {
165               output<<m_visible<<endl;
166       }
167       output.close();
168       output.open("output_center.txt",ios_base::app);
169       output<<"Coordinate del punto - X : "<<m_sTrackingObject.X -
170       ((m_nImageWidth - 1)/2)<<" - Y : "<<m_sTrackingObject.Y - ((m_nImageHeight
171       - 1)/2)<<endl;
172       output<<"Larghezza dell'area : "<<m_sTrackingObject.W <<" - Altezza
173       dell'aera : "<<m_sTrackingObject.H<<endl;
174       output<<"Mezzo pixel : "<<m_sTrackingObject.half_pixelx <<"
175       "<<m_sTrackingObject.half_pixely<<endl;
176       if (m_visible=="")
177       {
178               output<<"Visibilità : VISIBLE"<<endl;
179       }
180       else
181       {
182               output<<"Visibilità : "<<m_visible<<endl;
183       }
184       output.close();*/
185     } else {
186       FindNextLocation(frame);
187     }
188   }
189 }
190 
191 //--------------------------------------------------------------------------------------------------------
192 // histogram object
FindHistogram(TRaster32P * frame,float (* histogram),float h)193 void CObjectTracker::FindHistogram(TRaster32P *frame, float(*histogram),
194                                    float h) {
195   short normx = 0, normy = 0;
196   float normc = 0.0, normc1 = 0.0;
197   short i   = 0;
198   short x   = 0;
199   short y   = 0;
200   UBYTE8 E  = 0;
201   UBYTE8 qR = 0, qG = 0, qB = 0;
202   ValuePixel pixelValues;
203   int indice = 0;
204 
205   for (i = 0; i < HISTOGRAM_LENGTH; i++) histogram[i] = 0.0;
206 
207   if ((colorimage) && (att_background)) FindWeightsBackground(frame);
208 
209   // normalization
210   normx = short(m_sTrackingObject.X + m_sTrackingObject.W / 2);
211   normy = short(m_sTrackingObject.Y + m_sTrackingObject.H / 2);
212 
213   for (y = std::max(m_sTrackingObject.Y - m_sTrackingObject.H / 2, 0);
214        y <= std::min(m_sTrackingObject.Y + m_sTrackingObject.H / 2,
215                      m_nImageHeight - 1);
216        y++)
217     for (x = std::max(m_sTrackingObject.X - m_sTrackingObject.W / 2, 0);
218          x <= std::min(m_sTrackingObject.X + m_sTrackingObject.W / 2,
219                        m_nImageWidth - 1);
220          x++) {
221       E = CheckEdgeExistance(frame, x, y);
222 
223       pixelValues = GetPixelValues(frame, x, y);
224 
225       // components RGB "quantizzate"
226       if (!colorimage) {
227         indice = 256 * E + pixelValues.r;
228       } else {
229         qR     = pixelValues.r / 16;
230         qG     = pixelValues.g / 16;
231         qB     = pixelValues.b / 16;
232         indice = 4096 * E + 256 * qR + 16 * qG + qB;
233       }
234 
235       histogram[indice] += 1 -
236                            (((m_sTrackingObject.X - x) / normx) *
237                                 ((m_sTrackingObject.X - x) / normx) +
238                             ((m_sTrackingObject.Y - y) / normy) *
239                                 ((m_sTrackingObject.Y - y) / normy)) /
240                                (h * h);
241     }
242 
243   if ((colorimage) && (att_background)) {
244     for (i = 0; i < HISTOGRAM_LENGTH; i++)
245       histogram[i] *= m_sTrackingObject.weights_background[i];
246 
247     // normalization pdf
248     for (i = 0; i < HISTOGRAM_LENGTH; i++) {
249       normc += histogram[i];
250       normc1 += m_sTrackingObject.weights_background[i];
251     }
252     // Pdf
253     for (i         = 0; i < HISTOGRAM_LENGTH; i++)
254       histogram[i] = histogram[i] / (normc * normc1);
255   }
256 
257   else {
258     for (i = 0; i < HISTOGRAM_LENGTH; i++) normc += histogram[i];
259 
260     for (i         = 0; i < HISTOGRAM_LENGTH; i++)
261       histogram[i] = histogram[i] / (normc);
262   }
263 }
264 
265 //--------------------------------------------------------------------------------------------------------
266 // Histogram background
FindHistogramBackground(TRaster32P * frame,float (* background))267 void CObjectTracker::FindHistogramBackground(TRaster32P *frame,
268                                              float(*background)) {
269   short i   = 0;
270   short x   = 0;
271   short y   = 0;
272   UBYTE8 E  = 0;
273   UBYTE8 qR = 0, qG = 0, qB = 0;
274   ValuePixel pixelValues;
275   UINT32 pix = 0;
276 
277   for (i = 0; i < HISTOGRAM_LENGTH; i++) background[i] = 0.0;
278 
279   for (y = std::max(m_sTrackingObject.Y - (m_sTrackingObject.H * 1.73) / 2,
280                     0.0);
281        y <= std::min(m_sTrackingObject.Y + (m_sTrackingObject.H * 1.73) / 2,
282                      m_nImageHeight - 1.0);
283        y++)
284     for (x = std::max(m_sTrackingObject.X - (m_sTrackingObject.W * 1.73) / 2,
285                       0.0);
286          x <= std::min(m_sTrackingObject.X + (m_sTrackingObject.W * 1.73) / 2,
287                        m_nImageWidth - 1.0);
288          x++) {
289       if (((m_sTrackingObject.Y - m_sTrackingObject.H / 2) <= y) &&
290           (y <= (m_sTrackingObject.Y + m_sTrackingObject.H / 2)) &&
291           ((m_sTrackingObject.X - m_sTrackingObject.W / 2) <= x) &&
292           (x <= (m_sTrackingObject.X + m_sTrackingObject.W / 2)))
293         continue;
294 
295       E = CheckEdgeExistance(frame, x, y);
296 
297       pixelValues = GetPixelValues(frame, x, y);
298 
299       // components RGB "quantizzate"
300       qR = pixelValues.r / 16;
301       qG = pixelValues.g / 16;
302       qB = pixelValues.b / 16;
303 
304       background[4096 * E + 256 * qR + 16 * qG + qB] += 1;
305       pix++;
306     }
307 
308   // Pdf
309   for (i = 0; i < HISTOGRAM_LENGTH; i++) background[i] = background[i] / pix;
310 }
311 //--------------------------------------------------------------------------------------------------------
312 // Weights Background
FindWeightsBackground(TRaster32P * frame)313 void CObjectTracker::FindWeightsBackground(TRaster32P *frame) {
314   float small1;
315   std::unique_ptr<float[]> background(new float[HISTOGRAM_LENGTH]);
316   short i;
317   for (i                                    = 0; i < HISTOGRAM_LENGTH; i++)
318     m_sTrackingObject.weights_background[i] = 0.0;
319 
320   // Histogram background
321   FindHistogramBackground(frame, background.get());
322 
323   // searce min != 0.0
324   for (i = 0; background[i] == 0.0; i++)
325     ;
326   small1 = background[i];
327   for (i = 0; i < HISTOGRAM_LENGTH; i++)
328     if ((background[i] != 0.0) && (background[i] < small1))
329       small1 = background[i];
330 
331   // weights
332   for (i = 0; i < HISTOGRAM_LENGTH; i++) {
333     if (background[i] == 0.0)
334       m_sTrackingObject.weights_background[i] = 1;
335     else
336       m_sTrackingObject.weights_background[i] = small1 / background[i];
337   }
338 }
339 
340 //--------------------------------------------------------------------------------------------------------
341 // new location
FindWightsAndCOM(TRaster32P * frame,float (* histogram))342 void CObjectTracker::FindWightsAndCOM(TRaster32P *frame, float(*histogram)) {
343   short i            = 0;
344   short x            = 0;
345   short y            = 0;
346   UBYTE8 E           = 0;
347   float sumOfWeights = 0;
348   short ptr          = 0;
349   UBYTE8 qR = 0, qG = 0, qB = 0;
350   float newX = 0.0;
351   float newY = 0.0;
352   ValuePixel pixelValues;
353 
354   std::unique_ptr<float[]> weights(new float[HISTOGRAM_LENGTH]);
355 
356   // weigths
357   for (i = 0; i < HISTOGRAM_LENGTH; i++) {
358     if (histogram[i] > 0.0)
359       weights[i] = sqrt(m_sTrackingObject.initHistogram[i] / histogram[i]);
360     else
361       weights[i] = 0.0;
362   }
363 
364   // new location
365   for (y = std::max(m_sTrackingObject.Y - m_sTrackingObject.H / 2, 0);
366        y <= std::min(m_sTrackingObject.Y + m_sTrackingObject.H / 2,
367                      m_nImageHeight - 1);
368        y++)
369     for (x = std::max(m_sTrackingObject.X - m_sTrackingObject.W / 2, 0);
370          x <= std::min(m_sTrackingObject.X + m_sTrackingObject.W / 2,
371                        m_nImageWidth - 1);
372          x++) {
373       E = CheckEdgeExistance(frame, x, y);
374 
375       pixelValues = GetPixelValues(frame, x, y);
376 
377       if (!colorimage) {
378         ptr = 256 * E + pixelValues.r;
379       } else {
380         qR = pixelValues.r / 16;
381         qG = pixelValues.g / 16;
382         qB = pixelValues.b / 16;
383 
384         ptr = 4096 * E + 256 * qR + 16 * qG + qB;
385       }
386 
387       newX += (weights[ptr] * x);
388       newY += (weights[ptr] * y);
389 
390       sumOfWeights += weights[ptr];
391     }
392 
393   if (sumOfWeights > 0) {
394     m_sTrackingObject.X = short((newX / sumOfWeights) + 0.5);
395     m_sTrackingObject.Y = short((newY / sumOfWeights) + 0.5);
396   }
397 }
398 
399 //--------------------------------------------------------------------------------------------------------
400 // Edge Information of pixel
CheckEdgeExistance(TRaster32P * frame,short _x,short _y)401 UBYTE8 CObjectTracker::CheckEdgeExistance(TRaster32P *frame, short _x,
402                                           short _y) {
403   UBYTE8 E         = 0;
404   short GrayCenter = 0;
405   short GrayLeft   = 0;
406   short GrayRight  = 0;
407   short GrayUp     = 0;
408   short GrayDown   = 0;
409   ValuePixel pixelValues;
410 
411   pixelValues = GetPixelValues(frame, _x, _y);
412 
413   GrayCenter = short(3 * pixelValues.r + 6 * pixelValues.g + pixelValues.b);
414   if (_x > 0) {
415     pixelValues = GetPixelValues(frame, _x - 1, _y);
416 
417     GrayLeft = short(3 * pixelValues.r + 6 * pixelValues.g + pixelValues.b);
418   }
419 
420   if (_x < (m_nImageWidth - 1)) {
421     pixelValues = GetPixelValues(frame, _x + 1, _y);
422 
423     GrayRight = short(3 * pixelValues.r + 6 * pixelValues.g + pixelValues.b);
424   }
425 
426   if (_y > 0) {
427     pixelValues = GetPixelValues(frame, _x, _y - 1);
428 
429     GrayUp = short(3 * pixelValues.r + 6 * pixelValues.g + pixelValues.b);
430   }
431 
432   if (_y < (m_nImageHeight - 1)) {
433     pixelValues = GetPixelValues(frame, _x, _y + 1);
434 
435     GrayDown = short(3 * pixelValues.r + 6 * pixelValues.g + pixelValues.b);
436   }
437 
438   if (abs((GrayCenter - GrayLeft) / 10) > EDGE_DETECT_THRESHOLD) E = 1;
439 
440   if (abs((GrayCenter - GrayRight) / 10) > EDGE_DETECT_THRESHOLD) E = 1;
441 
442   if (abs((GrayCenter - GrayUp) / 10) > EDGE_DETECT_THRESHOLD) E = 1;
443 
444   if (abs((GrayCenter - GrayDown) / 10) > EDGE_DETECT_THRESHOLD) E = 1;
445 
446   return (E);
447 }
448 
449 //--------------------------------------------------------------------------------------------------------
450 // Mean-shift
FindNextLocation(TRaster32P * frame)451 void CObjectTracker::FindNextLocation(TRaster32P *frame) {
452   short i         = 0;
453   short iteration = 0;
454   short xold      = 0;
455   short yold      = 0;
456   float distanza;
457   float Height, Width;
458   float h = 1.0;
459   float h_opt;
460   float DELTA;
461   double rho, rho1, rho2;
462 
463   std::unique_ptr<float[]> currentHistogram(new float[HISTOGRAM_LENGTH]);
464 
465   Height = m_sTrackingObject.H;
466   Width  = m_sTrackingObject.W;
467 
468   // old
469   m_sTrackingObject.W_old = m_sTrackingObject.W;
470   m_sTrackingObject.H_old = m_sTrackingObject.H;
471 
472   m_sTrackingObject.X_old = m_sTrackingObject.X;
473   m_sTrackingObject.Y_old = m_sTrackingObject.Y;
474 
475   for (iteration = 0; iteration < MEANSHIFT_ITERATION_NO; iteration++) {
476     rho  = 0.0;
477     rho1 = 0.0;
478     rho2 = 0.0;
479 
480     DELTA = 0.1 * h;
481 
482     // Prew center
483     xold = m_sTrackingObject.X;
484     yold = m_sTrackingObject.Y;
485 
486     // Histogram with bandwidth h
487     FindHistogram(frame, currentHistogram.get(), h);
488 
489     // New location
490     FindWightsAndCOM(frame, currentHistogram.get());
491 
492     // Histogram with new location
493     FindHistogram(frame, currentHistogram.get(), h);
494 
495     // Battacharyya coefficient
496     for (i = 0; i < HISTOGRAM_LENGTH; i++)
497       rho += sqrt(m_sTrackingObject.initHistogram[i] * currentHistogram[i]);
498 
499     // old center
500     m_sTrackingObject.X = xold;
501     m_sTrackingObject.Y = yold;
502 
503     // Histogram with bandwidth h-DELTA
504     m_sTrackingObject.H = Height - m_sTrackingObject.var_dim;
505     m_sTrackingObject.W = Width - m_sTrackingObject.var_dim;
506     FindHistogram(frame, currentHistogram.get(), h - DELTA);
507 
508     // New location
509     FindWightsAndCOM(frame, currentHistogram.get());
510 
511     // Histogram with new location
512     FindHistogram(frame, currentHistogram.get(), h - DELTA);
513 
514     // Battacharyya coefficient
515     for (i = 0; i < HISTOGRAM_LENGTH; i++)
516       rho1 += sqrt(m_sTrackingObject.initHistogram[i] * currentHistogram[i]);
517 
518     // old center
519     m_sTrackingObject.X = xold;
520     m_sTrackingObject.Y = yold;
521 
522     // Histogram with bandwidth h+DELTA
523     m_sTrackingObject.H = Height + m_sTrackingObject.var_dim;
524     m_sTrackingObject.W = Width + m_sTrackingObject.var_dim;
525     FindHistogram(frame, currentHistogram.get(), h + DELTA);
526 
527     // New location
528     FindWightsAndCOM(frame, currentHistogram.get());
529 
530     // Histogram with new location
531     FindHistogram(frame, currentHistogram.get(), h + DELTA);
532 
533     // Battacharyya coefficient
534     for (i = 0; i < HISTOGRAM_LENGTH; i++)
535       rho2 += sqrt(m_sTrackingObject.initHistogram[i] * currentHistogram[i]);
536 
537     // h_optimal
538     if ((rho >= rho1) && (rho >= rho2))
539       h_opt = h;
540 
541     else if (rho1 > rho2) {
542       h_opt = h - DELTA;
543       Height -= m_sTrackingObject.var_dim;
544       Width -= m_sTrackingObject.var_dim;
545     } else {
546       h_opt = h + DELTA;
547       Height += m_sTrackingObject.var_dim;
548       Width += m_sTrackingObject.var_dim;
549     }
550 
551     // oversensitive scale adaptation
552     h = 0.1 * h_opt + (1 - 0.1) * h;
553 
554     // New dimension Object box
555     m_sTrackingObject.H = Height;
556     m_sTrackingObject.W = Width;
557 
558     // old center
559     m_sTrackingObject.X = xold;
560     m_sTrackingObject.Y = yold;
561 
562     // Current Histogram
563     FindHistogram(frame, currentHistogram.get(), h);
564 
565     // Definitive new location
566     FindWightsAndCOM(frame, currentHistogram.get());
567 
568     // threshold
569     distanza = sqrt(
570         float((xold - m_sTrackingObject.X) * (xold - m_sTrackingObject.X) +
571               (yold - m_sTrackingObject.Y) * (yold - m_sTrackingObject.Y)));
572 
573     if (distanza <= ITERACTION_THRESHOLD) break;
574   }
575   // New Histogram
576   FindHistogram(frame, currentHistogram.get(), h);
577   // Update
578   UpdateInitialHistogram(currentHistogram.get());
579 }
580 
581 //--------------------------------------------------------------------------------------------------------
582 // Update Initial histogram
UpdateInitialHistogram(float (* histogram))583 void CObjectTracker::UpdateInitialHistogram(float(*histogram)) {
584   short i = 0;
585 
586   for (i = 0; i < HISTOGRAM_LENGTH; i++)
587     m_sTrackingObject.initHistogram[i] =
588         ALPHA * m_sTrackingObject.initHistogram[i] + (1 - ALPHA) * histogram[i];
589 }
590 
591 //-------------------------------------------------------------------------------------------------------
592 // Template Matching
Matching(TRaster32P * frame,TRaster32P * frame_temp)593 float CObjectTracker::Matching(TRaster32P *frame, TRaster32P *frame_temp) {
594   float dist     = 0.0;
595   float min_dist = MAX_FLOAT;
596 
597   short u, v, x, y;
598   short u_sup, v_sup;
599   short x_min, y_min;
600   short x_max, y_max;
601   short dimx, dimy;
602   short dimx_int, dimy_int;
603   short ok_u = 0;
604   short ok_v = 0;
605 
606   if (!track) {
607     if (m_sTrackingObject.X != -1) {
608       m_sTrackingObject.X_old = m_sTrackingObject.X;
609       m_sTrackingObject.Y_old = m_sTrackingObject.Y;
610     } else {
611       m_sTrackingObject.X = m_sTrackingObject.X_old;
612       m_sTrackingObject.Y = m_sTrackingObject.Y_old;
613     }
614   }
615 
616   std::unique_ptr<short[]> u_att(new short[2 * m_sTrackingObject.dim_temp + 1]);
617   std::unique_ptr<short[]> v_att(new short[2 * m_sTrackingObject.dim_temp + 1]);
618 
619   x_min = std::max(m_sTrackingObject.X_temp - m_sTrackingObject.W_temp / 2, 0);
620   y_min = std::max(m_sTrackingObject.Y_temp - m_sTrackingObject.H_temp / 2, 0);
621 
622   x_max = std::min(m_sTrackingObject.X_temp + m_sTrackingObject.W_temp / 2,
623                    m_nImageWidth - 1);
624   y_max = std::min(m_sTrackingObject.Y_temp + m_sTrackingObject.H_temp / 2,
625                    m_nImageHeight - 1);
626 
627   // dimension template
628   dimx = x_max - x_min + 1;
629   dimy = y_max - y_min + 1;
630 
631   // dimension interpolate template
632   dimx_int = dimx * 2 - 1;
633   dimy_int = dimy * 2 - 1;
634 
635   // searce area
636   int in = 0;
637   for (u = -m_sTrackingObject.dim_temp; u <= m_sTrackingObject.dim_temp; u++) {
638     if (((m_sTrackingObject.X + u - dimx / 2) < 0) ||
639         ((m_sTrackingObject.X + u + dimx / 2) > m_nImageWidth - 1))
640       u_att[in] = 0;
641     else {
642       u_att[in] = 1;
643       ok_u += 1;
644     }
645 
646     in++;
647   }
648 
649   in = 0;
650   for (v = -m_sTrackingObject.dim_temp; v <= m_sTrackingObject.dim_temp; v++) {
651     if (((m_sTrackingObject.Y + v - dimy / 2) < 0) ||
652         ((m_sTrackingObject.Y + v + dimy / 2) > m_nImageHeight - 1))
653       v_att[in] = 0;
654     else {
655       v_att[in] = 1;
656       ok_v += 1;
657     }
658 
659     in++;
660   }
661 
662   if ((ok_u > 0) && (ok_v > 0)) {
663     // Interpolate template
664     std::unique_ptr<ValuePixel[]> pixel_temp(
665         new ValuePixel[dimx_int * dimy_int]);
666 
667     // original value
668     for (int i = 0; i <= (dimx - 1); i++)
669       for (int j = 0; j <= (dimy - 1); j++) {
670         pixel_temp[i * dimy_int * 2 + j * 2] =
671             GetPixelValues(frame_temp, x_min + i, y_min + j);
672       }
673 
674     // Interpolate value row
675     for (int i = 1; i < (dimx_int * dimy_int); i += 2) {
676       pixel_temp[i].r = (pixel_temp[i - 1].r + pixel_temp[i + 1].r) / 2;
677       pixel_temp[i].g = (pixel_temp[i - 1].g + pixel_temp[i + 1].g) / 2;
678       pixel_temp[i].b = (pixel_temp[i - 1].b + pixel_temp[i + 1].b) / 2;
679 
680       if (i % dimy_int == dimy_int - 2) i += dimy_int + 1;
681     }
682 
683     // Interpolate value column
684     for (int i = dimy_int; i <= ((dimx_int - 1) * dimy_int - 1); i += 2) {
685       pixel_temp[i].r =
686           (pixel_temp[i - dimy_int].r + pixel_temp[i + dimy_int].r) / 2;
687       pixel_temp[i].g =
688           (pixel_temp[i - dimy_int].g + pixel_temp[i + dimy_int].g) / 2;
689       pixel_temp[i].b =
690           (pixel_temp[i - dimy_int].b + pixel_temp[i + dimy_int].b) / 2;
691 
692       if (i % dimy_int == dimy_int - 1) i += dimy_int - 1;
693     }
694 
695     // Interpolate value central
696     for (int i = dimy_int + 1; i <= ((dimx_int - 1) * dimy_int - 2); i += 2) {
697       pixel_temp[i].r = UBYTE8(float((pixel_temp[i - dimy_int - 1].r +
698                                       pixel_temp[i - dimy_int + 1].r +
699                                       pixel_temp[i + dimy_int - 1].r +
700                                       pixel_temp[i + dimy_int + 1].r) /
701                                      4) +
702                                0.4);
703 
704       pixel_temp[i].g = UBYTE8(float((pixel_temp[i - dimy_int - 1].g +
705                                       pixel_temp[i - dimy_int + 1].g +
706                                       pixel_temp[i + dimy_int - 1].g +
707                                       pixel_temp[i + dimy_int + 1].g) /
708                                      4) +
709                                0.4);
710 
711       pixel_temp[i].b = UBYTE8(float((pixel_temp[i - dimy_int - 1].b +
712                                       pixel_temp[i - dimy_int + 1].b +
713                                       pixel_temp[i + dimy_int - 1].b +
714                                       pixel_temp[i + dimy_int + 1].b) /
715                                      4) +
716                                0.4);
717 
718       if (i % dimy_int == dimy_int - 2) i += dimy_int + 1;
719     }
720 
721     //--------------------------------------------------------
722     short dimx_int_ric, dimy_int_ric;
723     short x_min_ric, y_min_ric;
724 
725     short u_min = -m_sTrackingObject.dim_temp;
726     short v_min = -m_sTrackingObject.dim_temp;
727 
728     for (int i = 0; i <= 2 * m_sTrackingObject.dim_temp; i++)
729       if (u_att[i] == 1)
730         break;
731       else
732         u_min++;
733 
734     x_min_ric = m_sTrackingObject.X + u_min - dimx / 2;
735 
736     for (int i = 0; i <= 2 * m_sTrackingObject.dim_temp; i++)
737       if (v_att[i] == 1)
738         break;
739       else
740         v_min++;
741 
742     y_min_ric = m_sTrackingObject.Y + v_min - dimy / 2;
743 
744     // Effective Dimension searce interpolate area
745     dimx_int_ric = ((dimx + ok_u - 1) * 2 - 1);
746     dimy_int_ric = ((dimy + ok_v - 1) * 2 - 1);
747 
748     std::unique_ptr<ValuePixel[]> area_ricerca(
749         new ValuePixel[dimx_int_ric * dimy_int_ric]);
750 
751     // Original value
752     for (int i = 0; i <= ((dimx + ok_u - 1) - 1); i++)
753       for (int j = 0; j <= ((dimy + ok_v - 1) - 1); j++) {
754         area_ricerca[i * dimy_int_ric * 2 + j * 2] =
755             GetPixelValues(frame, x_min_ric + i, y_min_ric + j);
756       }
757 
758     // interpolate value row
759     for (int i = 1; i < (dimx_int_ric * dimy_int_ric); i += 2) {
760       area_ricerca[i].r = (area_ricerca[i - 1].r + area_ricerca[i + 1].r) / 2;
761       area_ricerca[i].g = (area_ricerca[i - 1].g + area_ricerca[i + 1].g) / 2;
762       area_ricerca[i].b = (area_ricerca[i - 1].b + area_ricerca[i + 1].b) / 2;
763 
764       if (i % dimy_int_ric == dimy_int_ric - 2) i += dimy_int_ric + 1;
765     }
766 
767     // Interpolate value column
768     for (int i = dimy_int_ric; i <= ((dimx_int_ric - 1) * dimy_int_ric - 1);
769          i += 2) {
770       area_ricerca[i].r = (area_ricerca[i - dimy_int_ric].r +
771                            area_ricerca[i + dimy_int_ric].r) /
772                           2;
773       area_ricerca[i].g = (area_ricerca[i - dimy_int_ric].g +
774                            area_ricerca[i + dimy_int_ric].g) /
775                           2;
776       area_ricerca[i].b = (area_ricerca[i - dimy_int_ric].b +
777                            area_ricerca[i + dimy_int_ric].b) /
778                           2;
779 
780       if (i % dimy_int_ric == dimy_int_ric - 1) i += dimy_int_ric - 1;
781     }
782 
783     // Interpolate value central
784     for (int i = dimy_int_ric + 1; i <= ((dimx_int_ric - 1) * dimy_int_ric - 2);
785          i += 2) {
786       area_ricerca[i].r = UBYTE8(float((area_ricerca[i - dimy_int_ric - 1].r +
787                                         area_ricerca[i - dimy_int_ric + 1].r +
788                                         area_ricerca[i + dimy_int_ric - 1].r +
789                                         area_ricerca[i + dimy_int_ric + 1].r) /
790                                        4) +
791                                  0.4);
792 
793       area_ricerca[i].g = UBYTE8(float((area_ricerca[i - dimy_int_ric - 1].g +
794                                         area_ricerca[i - dimy_int_ric + 1].g +
795                                         area_ricerca[i + dimy_int_ric - 1].g +
796                                         area_ricerca[i + dimy_int_ric + 1].g) /
797                                        4) +
798                                  0.4);
799 
800       area_ricerca[i].b = UBYTE8(float((area_ricerca[i - dimy_int_ric - 1].b +
801                                         area_ricerca[i - dimy_int_ric + 1].b +
802                                         area_ricerca[i + dimy_int_ric - 1].b +
803                                         area_ricerca[i + dimy_int_ric + 1].b) /
804                                        4) +
805                                  0.4);
806 
807       if (i % dimy_int_ric == dimy_int_ric - 2) i += dimy_int_ric + 1;
808     }
809 
810     short u_max = m_sTrackingObject.dim_temp;
811     short v_max = m_sTrackingObject.dim_temp;
812 
813     for (int i = 2 * m_sTrackingObject.dim_temp; i >= 0; i--)
814       if (u_att[i] == 1)
815         break;
816       else
817         u_max--;
818 
819     for (int i = 2 * m_sTrackingObject.dim_temp; i >= 0; i--)
820       if (v_att[i] == 1)
821         break;
822       else
823         v_max--;
824 
825     unsigned long indt, indc;
826 
827     std::unique_ptr<float[]> mat_dist(
828         new float[(2 * ok_u - 1) * (2 * ok_v - 1)]);
829     float att_dist_cent = MAX_FLOAT;
830     float dist_cent;
831 
832     // Distance
833     for (u = 2 * u_min; u <= 2 * u_max; u++) {
834       for (v = 2 * v_min; v <= 2 * v_max; v++) {
835         dist = 0.0;
836         //
837         for (x = 0; x < dimx_int; x++)
838           for (y = 0; y < dimy_int; y++) {
839             // T(x,y)
840 
841             indt = x * dimy_int + y;
842 
843             // L(x+u,y+v)
844 
845             indc =
846                 ((x + (u - 2 * u_min))) * dimy_int_ric + (y + (v - 2 * v_min));
847 
848             dist += (pixel_temp[indt].r - area_ricerca[indc].r) *
849                         (pixel_temp[indt].r - area_ricerca[indc].r) +
850                     (pixel_temp[indt].g - area_ricerca[indc].g) *
851                         (pixel_temp[indt].g - area_ricerca[indc].g) +
852                     (pixel_temp[indt].b - area_ricerca[indc].b) *
853                         (pixel_temp[indt].b - area_ricerca[indc].b);
854           }
855         dist = sqrt(dist) / (sqrt(float(dimx_int * dimy_int * 3 * 255 * 255)));
856 
857         mat_dist[(u - 2 * u_min) * (2 * ok_v - 1) + (v - 2 * v_min)] = dist;
858 
859         if (dist < min_dist) {
860           min_dist      = dist;
861           u_sup         = u;
862           v_sup         = v;
863           att_dist_cent = sqrt(float(u * u + v * v));
864         }
865 
866         else if (dist == min_dist) {
867           dist_cent = sqrt(float(u * u + v * v));
868           if (dist_cent < att_dist_cent) {
869             min_dist      = dist;
870             u_sup         = u;
871             v_sup         = v;
872             att_dist_cent = dist_cent;
873           }
874         }
875       }
876     }
877 
878     if (!man_occlusion) {
879       if (min_dist > m_sTrackingObject.threshold_distance) {
880         track               = false;
881         m_sTrackingObject.X = m_sTrackingObject.X_old;
882         m_sTrackingObject.Y = m_sTrackingObject.Y_old;
883         m_visible           = "INVISIBLE";
884       } else {
885         track = true;
886         if (min_dist > m_sTrackingObject.threshold_distance_B) {
887           m_visible = "WARNING";
888           m_K_dist  = floor(
889               (double)(min_dist - m_sTrackingObject.threshold_distance_B) /
890               (m_sTrackingObject.threshold_distance -
891                m_sTrackingObject.threshold_distance_B));
892         } else {
893           m_visible = "VISIBLE";
894         }
895       }
896     }
897 
898     if (track) {
899       // half pixel
900       m_sTrackingObject.half_pixelx = 0;
901       m_sTrackingObject.half_pixely = 0;
902 
903       if (u_sup % 2 != 0)
904         if (v_sup % 2 != 0) {
905           if (mat_dist[(u_sup - 2 * u_min - 1) * (2 * ok_v - 1) +
906                        (v_sup - 2 * v_min - 1)] <
907               mat_dist[(u_sup - 2 * u_min - 1) * (2 * ok_v - 1) +
908                        (v_sup - 2 * v_min + 1)])
909 
910             if (mat_dist[(u_sup - 2 * u_min - 1) * (2 * ok_v - 1) +
911                          (v_sup - 2 * v_min - 1)] <
912                 mat_dist[(u_sup - 2 * u_min + 1) * (2 * ok_v - 1) +
913                          (v_sup - 2 * v_min - 1)])
914 
915               if (mat_dist[(u_sup - 2 * u_min - 1) * (2 * ok_v - 1) +
916                            (v_sup - 2 * v_min - 1)] <
917                   mat_dist[(u_sup - 2 * u_min + 1) * (2 * ok_v - 1) +
918                            (v_sup - 2 * v_min + 1)]) {
919                 m_sTrackingObject.half_pixelx = -1;
920                 m_sTrackingObject.half_pixely = -1;
921                 u_sup -= 1;
922                 v_sup -= 1;
923               } else {
924                 m_sTrackingObject.half_pixelx = 1;
925                 m_sTrackingObject.half_pixely = 1;
926                 u_sup += 1;
927                 v_sup += 1;
928               }
929             else if (mat_dist[(u_sup - 2 * u_min + 1) * (2 * ok_v - 1) +
930                               (v_sup - 2 * v_min - 1)] <
931                      mat_dist[(u_sup - 2 * u_min + 1) * (2 * ok_v - 1) +
932                               (v_sup - 2 * v_min + 1)]) {
933               m_sTrackingObject.half_pixelx = 1;
934               m_sTrackingObject.half_pixely = -1;
935               u_sup += 1;
936               v_sup -= 1;
937             } else {
938               m_sTrackingObject.half_pixelx = 1;
939               m_sTrackingObject.half_pixely = 1;
940               u_sup += 1;
941               v_sup += 1;
942             }
943           else if (mat_dist[(u_sup - 2 * u_min - 1) * (2 * ok_v - 1) +
944                             (v_sup - 2 * v_min + 1)] <
945                    mat_dist[(u_sup - 2 * u_min + 1) * (2 * ok_v - 1) +
946                             (v_sup - 2 * v_min - 1)])
947 
948             if (mat_dist[(u_sup - 2 * u_min - 1) * (2 * ok_v - 1) +
949                          (v_sup - 2 * v_min + 1)] <
950                 mat_dist[(u_sup - 2 * u_min + 1) * (2 * ok_v - 1) +
951                          (v_sup - 2 * v_min + 1)]) {
952               m_sTrackingObject.half_pixelx = -1;
953               m_sTrackingObject.half_pixely = 1;
954               u_sup -= 1;
955               v_sup += 1;
956             } else {
957               m_sTrackingObject.half_pixelx = 1;
958               m_sTrackingObject.half_pixely = 1;
959               u_sup += 1;
960               v_sup += 1;
961             }
962           else if (mat_dist[(u_sup - 2 * u_min + 1) * (2 * ok_v - 1) +
963                             (v_sup - 2 * v_min - 1)] <
964                    mat_dist[(u_sup - 2 * u_min + 1) * (2 * ok_v - 1) +
965                             (v_sup - 2 * v_min + 1)]) {
966             m_sTrackingObject.half_pixelx = 1;
967             m_sTrackingObject.half_pixely = -1;
968 
969             u_sup += 1;
970             v_sup -= 1;
971           } else {
972             m_sTrackingObject.half_pixelx = 1;
973             m_sTrackingObject.half_pixely = 1;
974             u_sup += 1;
975             v_sup += 1;
976           }
977         } else {
978           if (mat_dist[(u_sup - 2 * u_min - 1) * (2 * ok_v - 1) +
979                        (v_sup - 2 * v_min)] <
980               mat_dist[(u_sup - 2 * u_min + 1) * (2 * ok_v - 1) +
981                        (v_sup - 2 * v_min)]) {
982             m_sTrackingObject.half_pixelx = -1;
983             m_sTrackingObject.half_pixely = 0;
984             u_sup -= 1;
985           } else {
986             m_sTrackingObject.half_pixelx = 1;
987             m_sTrackingObject.half_pixely = 0;
988             u_sup += 1;
989           }
990         }
991       else if (v_sup % 2 != 0) {
992         if (mat_dist[(u_sup - 2 * u_min) * (2 * ok_v - 1) +
993                      (v_sup - 2 * v_min - 1)] <
994             mat_dist[(u_sup - 2 * u_min) * (2 * ok_v - 1) +
995                      (v_sup - 2 * v_min + 1)]) {
996           m_sTrackingObject.half_pixelx = 0;
997           m_sTrackingObject.half_pixely = -1;
998           v_sup -= 1;
999         } else {
1000           m_sTrackingObject.half_pixelx = 0;
1001           m_sTrackingObject.half_pixely = 1;
1002           v_sup += 1;
1003         }
1004       }
1005 
1006       m_sTrackingObject.X += u_sup / 2;
1007       m_sTrackingObject.Y += v_sup / 2;
1008     }
1009   }
1010 
1011   return min_dist;
1012 }
1013 
1014 //-------------------------------------------------------------------------------------------------------
1015 // Update characteristic neighbours
DistanceAndUpdate(NEIGHBOUR position)1016 void CObjectTracker::DistanceAndUpdate(NEIGHBOUR position) {
1017   float x0 = m_sTrackingObject.X;
1018   float y0 = m_sTrackingObject.Y;
1019   float x1 = position.X_old, y1 = position.Y_old;
1020   float dist2;
1021   dist2 = (x0 - x1) * (x0 - x1) + (y0 - y1) * (y0 - y1);
1022 
1023   // searce free position
1024   for (int i = 0; i < 30; i++) {
1025     if ((neighbours[i].X == -1) && (neighbours[i].Y == -1)) {
1026       neighbours[i].X     = position.X;
1027       neighbours[i].Y     = position.Y;
1028       neighbours[i].dist2 = dist2;
1029       neighbours[i].X_old = position.X_old;
1030       neighbours[i].Y_old = position.Y_old;
1031       return;
1032     }
1033   }
1034 
1035   // sostitution based on distance
1036   int i = 0;
1037   for (i = 0; i < 30; i++) {
1038     if (dist2 < neighbours[i].dist2) {
1039       neighbours[i].X     = position.X;
1040       neighbours[i].Y     = position.Y;
1041       neighbours[i].dist2 = dist2;
1042       neighbours[i].X_old = position.X_old;
1043       neighbours[i].Y_old = position.Y_old;
1044       return;
1045     }
1046   }
1047 }
1048 
1049 //--------------------------------------------------------------------------------------------------------
1050 // Set position by neighbours
SetPositionByNeighbours(void)1051 void CObjectTracker::SetPositionByNeighbours(void) {
1052   if (!track) {
1053     float x[3], y[3], d2[3];
1054     for (int i = 0; i < 30; i++) {
1055       //((X,Y)=(-1,-1) => neighbours not valid)
1056       if ((neighbours[i].X == -1) && (neighbours[i].Y == -1)) {
1057         m_sTrackingObject.X = -1;
1058         m_sTrackingObject.Y = -1;
1059         return;
1060       } else {
1061         x[i]  = neighbours[i].X;
1062         y[i]  = neighbours[i].Y;
1063         d2[i] = neighbours[i].dist2;
1064       }
1065     }
1066 
1067     // error: neighbours aligns
1068     if ((y[1] - y[0]) * (x[2] - x[0]) == (y[2] - y[0]) * (x[1] - x[0])) {
1069       m_sTrackingObject.X = -1;
1070       m_sTrackingObject.Y = -1;
1071       return;
1072     }
1073 
1074     // old neighbours coordinate
1075     float x_old[3], y_old[3];
1076     int i = 0;
1077     for (i = 0; i < 3; i++) {
1078       x_old[i] = neighbours[i].X_old;
1079       y_old[i] = neighbours[i].Y_old;
1080     }
1081 
1082     //
1083     float dn2[3], dn_old2[3];
1084 
1085     // distance
1086     for (i = 0; i < 2; i++)
1087       for (int j = i + 1; j < 3; j++) {
1088         dn_old2[i + j - 1] = (x_old[i] - x_old[j]) * (x_old[i] - x_old[j]) +
1089                              (y_old[i] - y_old[j]) * (y_old[i] - y_old[j]);
1090         dn2[i + j - 1] =
1091             (x[i] - x[j]) * (x[i] - x[j]) + (y[i] - y[j]) * (y[i] - y[j]);
1092       }
1093 
1094     // scale factor (^2)
1095     float scale = ((dn2[0] / dn_old2[0]) + (dn2[1] / dn_old2[1]) +
1096                    (dn2[2] / dn_old2[2])) /
1097                   3.0;
1098 
1099     // update distance
1100     for (i = 0; i < 3; i++) d2[i] *= scale;
1101 
1102     // new location
1103     float A[2][2], b[2];
1104     A[0][0] = 2 * (x[1] - x[0]);
1105     A[0][1] = 2 * (y[1] - y[0]);
1106     A[1][0] = 2 * (x[2] - x[0]);
1107     A[1][1] = 2 * (y[2] - y[0]);
1108     b[0] =
1109         d2[0] - d2[1] + x[1] * x[1] - x[0] * x[0] + y[1] * y[1] - y[0] * y[0];
1110     b[1] =
1111         d2[0] - d2[2] + x[2] * x[2] - x[0] * x[0] + y[2] * y[2] - y[0] * y[0];
1112     float detA, invA[2][2];
1113     detA       = A[0][0] * A[1][1] - A[0][1] * A[1][0];
1114     invA[0][0] = A[1][1] / detA;
1115     invA[0][1] = -A[0][1] / detA;
1116     invA[1][0] = -A[1][0] / detA;
1117     invA[1][1] = A[0][0] / detA;
1118     float X, Y;
1119     X = invA[0][0] * b[0] + invA[0][1] * b[1];
1120     Y = invA[1][0] * b[0] + invA[1][1] * b[1];
1121 
1122     m_sTrackingObject.X = short(X + 0.49999);
1123     m_sTrackingObject.Y = short(Y + 0.49999);
1124 
1125     m_sTrackingObject.half_pixelx = 0;
1126     m_sTrackingObject.half_pixely = 0;
1127 
1128     // error
1129     if (m_sTrackingObject.X < 0) {
1130       //			m_sTrackingObject.X = 0;
1131       m_visible = "INVISIBLE";
1132     }
1133     if (m_sTrackingObject.X > (m_nImageWidth - 1)) {
1134       //			m_sTrackingObject.X = m_nImageWidth - 1;
1135       m_visible = "INVISIBLE";
1136     }
1137     if (m_sTrackingObject.Y < 0) {
1138       //			m_sTrackingObject.Y = 0;
1139       m_visible = "INVISIBLE";
1140     }
1141     if (m_sTrackingObject.Y > (m_nImageHeight - 1)) {
1142       //			m_sTrackingObject.Y = m_nImageHeight - 1;
1143       m_visible = "INVISIBLE";
1144     }
1145   }
1146 }
1147 
1148 //--------------------------------------------------------------------------------------------------------
1149 // Write on output file
WriteOnOutputFile(char * filename)1150 void CObjectTracker::WriteOnOutputFile(char *filename) {
1151   ofstream output;
1152   output.open(filename, ios_base::app);
1153   output << m_sTrackingObject.X << " " << m_sTrackingObject.Y << endl;
1154   output << m_sTrackingObject.W << " " << m_sTrackingObject.H << endl;
1155   output << m_sTrackingObject.half_pixelx << " "
1156          << m_sTrackingObject.half_pixely << endl;
1157   output << m_visible << endl;
1158   output.close();
1159   output.open("output_center.txt", ios_base::app);
1160   output << "Coordinate del punto - X : "
1161          << m_sTrackingObject.X - ((m_nImageWidth - 1) / 2)
1162          << " - Y : " << m_sTrackingObject.Y - ((m_nImageHeight - 1) / 2)
1163          << endl;
1164   output << "Larghezza dell'area : " << m_sTrackingObject.W
1165          << " - Altezza dell'aera : " << m_sTrackingObject.H << endl;
1166   output << "Mezzo pixel : " << m_sTrackingObject.half_pixelx << " "
1167          << m_sTrackingObject.half_pixely << endl;
1168   output << "Visibilità : " << m_visible << endl;
1169   output.close();
1170 }
1171 
1172 //--------------------------------------------------------------------------------------------------------
1173 // Reset distance
DistanceReset(void)1174 void CObjectTracker::DistanceReset(void) {
1175   for (int i = 0; i < 30; i++) {
1176     neighbours[i].X     = -1;
1177     neighbours[i].Y     = -1;
1178     neighbours[i].dist2 = MAX_FLOAT;
1179   }
1180 }
1181 
1182 //--------------------------------------------------------------------------------------------------------
1183 // Get position neighbours
GetPosition(void)1184 NEIGHBOUR CObjectTracker::GetPosition(void) {
1185   NEIGHBOUR _neighbour;
1186 
1187   _neighbour.X     = m_sTrackingObject.X;
1188   _neighbour.Y     = m_sTrackingObject.Y;
1189   _neighbour.dist2 = MAX_FLOAT;
1190   _neighbour.X_old = m_sTrackingObject.X_old;
1191   _neighbour.Y_old = m_sTrackingObject.Y_old;
1192 
1193   return _neighbour;
1194 }
1195 
1196 // Set position of the object
SetPosition(short x,short y)1197 void CObjectTracker::SetPosition(short x, short y) {
1198   if (x < 0) {
1199     //		x = 0;
1200     m_visible = "INVISIBLE";
1201   } else if (x > (m_nImageWidth - 1)) {
1202     //		x = m_nImageWidth - 1;
1203     m_visible = "INVISIBLE";
1204   }
1205   if (y < 0) {
1206     //		y = 0;
1207     m_visible = "INVISIBLE";
1208   } else if (y > (m_nImageHeight - 1)) {
1209     //		y = m_nImageHeight - 1;
1210     m_visible = "INVISIBLE";
1211   }
1212 
1213   m_sTrackingObject.X = x;
1214   m_sTrackingObject.Y = y;
1215 
1216   m_sTrackingObject.half_pixelx = 0;
1217   m_sTrackingObject.half_pixely = 0;
1218 }
1219 
1220 // Set the object as initialized
SetInit(bool status)1221 void CObjectTracker::SetInit(bool status) { m_initialized = status; }
1222 
1223 // Get if the object is initialized
GetInit()1224 bool CObjectTracker::GetInit() { return m_initialized; }
1225 
GetVisibility()1226 std::string CObjectTracker::GetVisibility() { return m_visible; }
1227 
SetVisibility(string visibility)1228 void CObjectTracker::SetVisibility(string visibility) {
1229   m_visible = visibility;
1230 }
1231 
1232 // Set initials position of neighbours
SetInitials(NEIGHBOUR position)1233 void CObjectTracker::SetInitials(NEIGHBOUR position) {
1234   initial.x = position.X;
1235   initial.y = position.Y;
1236 }
1237 
1238 // Get initials position of neighbours
GetInitials()1239 Predict3D::Point CObjectTracker::GetInitials() { return initial; }
1240 
1241 // Get the K_Dist
GetKDist()1242 int CObjectTracker::GetKDist() { return m_K_dist; }
1243 
1244 // End
1245