File: corelation.m

package info (click to toggle)
lynkeos.app 3.8%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 6,740 kB
  • sloc: objc: 40,528; ansic: 811; cpp: 150; sh: 68; makefile: 27
file content (122 lines) | stat: -rw-r--r-- 3,692 bytes parent folder | download | duplicates (2)
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/*=============================================================================
** Lynkeos
** $Id$
**-----------------------------------------------------------------------------
**
**  Created by Jean-Etienne LAMIAUD on Apr 30, 1998
**  Renamed from corelation.c to corelation.m on Mar 11, 2005
**  Copyright (c) 1998,2003-2020. Jean-Etienne LAMIAUD
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
**
**-----------------------------------------------------------------------------
*/
#include <stdlib.h>
#include <assert.h>

#include "processing_core.h"
#include "corelation.h"
#include "LynkeosImageBufferAdditions.h"

void correlate_spectrums( LynkeosFourierBuffer *s1, LynkeosFourierBuffer *s2, 
                          LynkeosFourierBuffer *r )
{
   /* Fourier transform of correlation is the product of s1 by s2 conjugate */
   [s1 multiplyWithConjugateOf:s2 result:r];

   [r inverseTransform];
}

void correlate( LynkeosFourierBuffer *s1, LynkeosFourierBuffer *s2, LynkeosFourierBuffer *r )
{
   /* Transform both images */
   [s1 directTransform];
   [s2 directTransform];

   /* Perform the correlation */
   correlate_spectrums( s1, s2, r );
}

void corelation_peak( LynkeosFourierBuffer *result, CORRELATION_PEAK *peak )
{
   u_short x, y, c; 
   double sum, module_max, module_min;
   double xp, yp, s_x2, s_y2;
   u_long nb_pixel;
   REAL r;

   assert( peak != NULL );

   for( c = 0; c < result->_nPlanes; c++ )
   {
      /* Search for min and max */
      module_max = 0.0;
      module_min = HUGE_VAL;

      for( y = 0; y < result->_h; y++ )
      {
         for( x = 0; x < result->_w; x++ )
         {
            r = colorValue(result,x,y,c);

            if ( r > module_max )
               module_max = r;
            if ( r < module_min )
               module_min = r;
         }
      }

      /* Locate the peak as the barycenter of pixels above (max-min)/sqrt(2) */
      xp = 0.0;
      yp = 0.0;
      s_x2 = 0.0;
      s_y2 = 0.0;
      sum = 0.0;
      nb_pixel = 0;

      for( y = 0; y < result->_h; y++ )
      {
         for( x = 0; x < result->_w; x++ )
         {
            double module;
            r = colorValue(result,x,y,c);
            module = r - module_min;

            if ( module > (module_max-module_min)*0.707 )
            {
               // Get the offset, taking into account the quadrants order
               // from the inverse FFT
               double dx = (2*x < result->_w ? x : x - result->_w),
                      dy = (2*y < result->_h ? y : y - result->_h);
               xp += dx*module;
               yp += dy*module;
               s_x2 += dx*dx*module;
               s_y2 += dy*dy*module;
               sum += module;
               nb_pixel++;
            }
         }
      }

      /* Present the results */
      xp /= sum;
      yp /= sum;
      peak[c].val = module_max - module_min;
      peak[c].x = xp;
      peak[c].y = yp;
      peak[c].sigma_x = sqrt(s_x2/sum - xp*xp);
      peak[c].sigma_y = sqrt(s_y2/sum - yp*yp);
   }
}