zinsser_klt.patch

Markus Moll, 2010-07-07 01:13 pm

Download (28.4 kB)

 
opencv/samples/c/lkdemo.c (working copy)
7 7

  
8 8
#define CV_NO_BACKWARD_COMPATIBILITY
9 9

  
10
#define USE_AFFINE
11

  
10 12
#ifndef _EiC
11 13
#include "cv.h"
12 14
#include "highgui.h"
......
14 16
#include <ctype.h>
15 17
#endif
16 18

  
19
static void draw_affine_feature(CvArr *img, const float *A, CvPoint2D32f x, CvScalar color, float sz)
20
{
21
    CvPoint corners[4] = { 
22
		cvPoint(x.x + (A[0]+A[1])*sz,  x.y + (A[2]+A[3])*sz), 
23
		cvPoint(x.x + (A[0]-A[1])*sz,  x.y + (A[2]-A[3])*sz),
24
		cvPoint(x.x + (-A[0]-A[1])*sz, x.y + (-A[2]-A[3])*sz),
25
		cvPoint(x.x + (-A[0]+A[1])*sz, x.y + (-A[2]+A[3])*sz)
26
	};
27

  
28
    cvLine(img, corners[3], corners[0], color, 1, 8, 0);
29
	cvLine(img, corners[0], corners[1], color, 1, 8, 0);
30
	cvLine(img, corners[1], corners[2], color, 1, 8, 0);
31
	cvLine(img, corners[2], corners[3], color, 1, 8, 0);
32
}
33

  
34
static void draw_feature(CvArr *img, CvPoint2D32f x)
35
{
36
    cvCircle( img, cvPointFrom32f(x), 3, CV_RGB(0,255,0), -1, 8,0);
37
}
38

  
17 39
IplImage *image = 0, *grey = 0, *prev_grey = 0, *pyramid = 0, *prev_pyramid = 0, *swap_temp;
18 40

  
19 41
int win_size = 10;
20 42
const int MAX_COUNT = 500;
21 43
CvPoint2D32f* points[2] = {0,0}, *swap_points;
44
#ifdef USE_AFFINE
45
CvAffineConsistencyPatch* affpatch;
46
float *affmatrices;
47
float *error;
48
#endif
22 49
char* status = 0;
23 50
int count = 0;
24 51
int need_to_init = 0;
......
94 121
            prev_pyramid = cvCreateImage( cvGetSize(frame), 8, 1 );
95 122
            points[0] = (CvPoint2D32f*)cvAlloc(MAX_COUNT*sizeof(points[0][0]));
96 123
            points[1] = (CvPoint2D32f*)cvAlloc(MAX_COUNT*sizeof(points[0][0]));
124
            
125
#ifdef USE_AFFINE
126
            affpatch = (CvAffineConsistencyPatch*)cvAlloc(MAX_COUNT*sizeof(affpatch[0]));
127
            affmatrices = (float*) cvAlloc(MAX_COUNT*4*sizeof(affmatrices[0]));
128
            error = (float*) cvAlloc(MAX_COUNT*sizeof(error[0]));
129
            for(i=0; i<MAX_COUNT; ++i)
130
            {
131
                cvInitAffineConsistencyPatch(affpatch + i, cvSize(win_size,win_size));
132
            }
133
#endif
134
            
97 135
            status = (char*)cvAlloc(MAX_COUNT);
98 136
            flags = 0;
99 137
        }
......
118 156
            cvFindCornerSubPix( grey, points[1], count,
119 157
                cvSize(win_size,win_size), cvSize(-1,-1),
120 158
                cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,20,0.03));
159

  
160
#ifdef USE_AFFINE
161
            cvGetAffineConsistencyPatches( grey, points[1], affpatch, affmatrices, count, cvSize(win_size, win_size) );
162
#endif 
163

  
121 164
            cvReleaseImage( &eig );
122 165
            cvReleaseImage( &temp );
123 166

  
......
128 171
            cvCalcOpticalFlowPyrLK( prev_grey, grey, prev_pyramid, pyramid,
129 172
                points[0], points[1], count, cvSize(win_size,win_size), 3, status, 0,
130 173
                cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,20,0.03), flags );
174
#ifdef USE_AFFINE
175
            cvAffineConsistencyCheck( grey, points[0], affpatch, points[1], affmatrices, count, cvSize(win_size, win_size), status, error, cvTermCriteria(CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, 20, 0.03) );
176

  
177
            const double err_thresh = (win_size*2+1)*(win_size*2+1) * 5.0;
178
            for( i = 0; i < count; i++ )
179
            {
180
                // let's say avg. per pixel error should be max 5
181
                // Then error threshold is patchLen * 5
182
                status[i] &= (error[i] < err_thresh);
183
            }
184
#endif
131 185
            flags |= CV_LKFLOW_PYR_A_READY;
132 186
            for( i = k = 0; i < count; i++ )
133 187
            {
......
147 201
                    continue;
148 202

  
149 203
                points[1][k++] = points[1][i];
150
                cvCircle( image, cvPointFrom32f(points[1][i]), 3, CV_RGB(0,255,0), -1, 8,0);
204
#ifdef USE_AFFINE
205
                cvSwapAffineConsistencyPatch(affpatch + k - 1, affpatch + i);
206
                memcpy(affmatrices + 4*(k-1), affmatrices + 4*i, 4*sizeof *affmatrices);
207

  
208
                draw_affine_feature(image, affmatrices + 4*i, points[1][i], CV_RGB(0,255,0), 10);
209
#else
210
                draw_feature(image, points[1][i]);
211
#endif
151 212
            }
152 213
            count = k;
153 214
        }
......
158 219
            cvFindCornerSubPix( grey, points[1] + count - 1, 1,
159 220
                cvSize(win_size,win_size), cvSize(-1,-1),
160 221
                cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,20,0.03));
222

  
223
#ifdef USE_AFFINE
224
            cvGetAffineConsistencyPatches( grey, points[1] + count - 1, 
225
                affpatch + count - 1, affmatrices + count - 1, 
226
                1, cvSize(win_size, win_size));
227
#endif
228

  
161 229
            add_remove_pt = 0;
162 230
        }
163 231

  
opencv/modules/video/include/opencv2/video/tracking.hpp (working copy)
97 97
                                     CvTermCriteria criteria,
98 98
                                     int       flags );
99 99

  
100
typedef struct CvAffineConsistencyPatch
101
{
102
    CvMat*  f;
103
    CvMat*  fx;
104
    CvMat*  fy;
105
    CvMat*  invG; // = ( sum h(x) h(x)^T )^-1, with h(x) = (x fx, y fx, x fy, y fy, fx, fy, f, 1)^T
106
} CvAffineConsistencyPatch;
100 107

  
108
CVAPI(void) cvInitAffineConsistencyPatch( CvAffineConsistencyPatch *p, CvSize win_size );
109
CVAPI(void) cvClearAffineConsistencyPatch( CvAffineConsistencyPatch *p );
110
CVAPI(void) cvSwapAffineConsistencyPatch( CvAffineConsistencyPatch *a, CvAffineConsistencyPatch *b );
111

  
112
/* This is much like cvCalcOpticalFlowPyrLK, but modified according to
113
   Zinsser, Graessl and Niemann, "Efficient Feature Tracking for Long Video Sequences".
114
   Also, this does _not_ use a pyramid as it expects the feature positions to be roughly
115
   correct on entry. This should only be used to check for consistency. */
116
CVAPI(void)  cvAffineConsistencyCheck( const CvArr*  curr,
117
                                       const CvPoint2D32f* prev_features,
118
                                       const CvAffineConsistencyPatch* initial_patches,
119
                                       CvPoint2D32f* curr_features,
120
                                       float*    affine_matrix,
121
                                       int       count,
122
                                       CvSize    win_size,
123
                                       char*     status,
124
                                       float*    track_error,
125
                                       CvTermCriteria criteria );
126

  
127
/* This function cuts out the patches needed for cvAffineConsistencyCheck) */
128
CVAPI(void)  cvGetAffineConsistencyPatches( const CvArr*  curr,
129
                                            const CvPoint2D32f* prev_features, 
130
                                            CvAffineConsistencyPatch* initial_patches,
131
                                            float*    affine_matrix,
132
                                            int       count,
133
                                            CvSize    win_size );
134

  
101 135
/* Modification of a previous sparse optical flow algorithm to calculate
102 136
   affine flow */
103 137
CVAPI(void)  cvCalcAffineFlowPyrLK( const CvArr*  prev, const CvArr*  curr,
opencv/modules/video/src/lkpyramid.cpp (working copy)
42 42
#include <float.h>
43 43
#include <stdio.h>
44 44

  
45
#define DO_SCALE
46

  
45 47
namespace cv
46 48
{
47 49

  
......
791 793
namespace cv
792 794
{
793 795

  
796
struct AffineConsistencyCheckInvoker
797
{
798
    AffineConsistencyCheckInvoker( const CvMat* _imgJ,
799
                         const CvPoint2D32f* _featuresA,
800
                         const CvAffineConsistencyPatch* _affinePatchA,
801
                         CvPoint2D32f* _featuresB,
802
                         float* _matrixB,
803
                         char* _status, float* _error,
804
                         CvTermCriteria _criteria,
805
                         CvSize _winSize )
806
    {
807
        imgJ = _imgJ;
808
        featuresA = _featuresA;
809
        affinePatchA = _affinePatchA;
810
        featuresB = _featuresB;
811
        matrixB = _matrixB;
812
        status = _status;
813
        error = _error;
814
        criteria = _criteria;
815
        winSize = _winSize;
816
    }
817
    
818
    void operator()(const BlockedRange& range) const
819
    {
820
        int i, i1 = range.begin(), i2 = range.end();
821
        
822
        CvSize patchSize = cvSize( winSize.width * 2 + 1, winSize.height * 2 + 1 );
823
        int patchLen = patchSize.width * patchSize.height;
824
        
825
        AutoBuffer<float> buf(patchLen);
826
        float* patchJ = buf;
827
        CvSize imgSize = cvGetMatSize(imgJ);
828
        
829
        // find flow for each given point
830
        for( i = i1; i < i2; i++ )
831
        {
832
            int pt_status;
833
            //CvPoint2D32f u;
834
            double D = 0;
835
            const float *patchI = (const float* ) affinePatchA[i].f->data.ptr;
836
            const float *Ix     = (const float* ) affinePatchA[i].fx->data.ptr;
837
            const float *Iy     = (const float* ) affinePatchA[i].fy->data.ptr;
838
            const double *invG   = (const double* ) affinePatchA[i].invG->data.ptr;
839
            float Av[6];
840
            float alpha = 1, beta = 0;
841
            int j, x, y;
842
           
843
            pt_status = status[i];
844
            if( !pt_status )
845
                continue;
846

  
847
            CvSize psz = cvGetSize(affinePatchA[i].f);
848
 
849
            Av[0] = matrixB[4*i + 0]; 
850
            Av[1] = matrixB[4*i + 1]; 
851
            Av[3] = matrixB[4*i + 2]; 
852
            Av[4] = matrixB[4*i + 3]; 
853
            Av[2] = featuresB[i].x;
854
            Av[5] = featuresB[i].y;
855
            
856
            for( j = 0; j < criteria.max_iter; j++ )
857
            {
858
                double g[8] = { 0 };
859
                
860
                for(int k=0; k<patchLen; ++k)
861
                    patchJ[k] = CV_8TO32F(0);
862

  
863
                if( icvGetQuadrangleSubPix_8u32f_C1R( imgJ->data.ptr, imgJ->step, imgSize, 
864
                                                      patchJ, patchSize.width*sizeof(float), patchSize, Av ) < 0 )
865
                {
866
                    // point is outside of the second image. take the next
867
                    status[i] = 0;
868
                    continue;
869
                }
870

  
871
                int yy = -winSize.height;
872
                for( y = 0; y < patchSize.height; y++, yy++ )
873
                {
874
                    // Here as well, scale pi, pj and ix and iy
875
                    const float* pi = patchI + y*patchSize.width;
876
                    const float* pj = patchJ + y*patchSize.width;
877
                    const float* ix = Ix + y*patchSize.width;
878
                    const float* iy = Iy + y*patchSize.width;
879
                    
880
                    int xx = -winSize.width;
881
                    for( x = 0; x < patchSize.width; x++, xx++ )
882
                    {
883
#ifdef DO_SCALE
884
                        g[7] += pj[x]              / 255;
885
                        g[6] += pi[x] * pj[x]      / (255 * 255);
886
                        g[5] += iy[x] * pj[x]      / (255 * 255);
887
                        g[4] += ix[x] * pj[x]      / (255 * 255);
888
                        g[3] += yy * iy[x] * pj[x] / (255 * 255);
889
                        g[2] += xx * iy[x] * pj[x] / (255 * 255);
890
                        g[1] += yy * ix[x] * pj[x] / (255 * 255);
891
                        g[0] += xx * ix[x] * pj[x] / (255 * 255);
892
#else
893
                        g[7] += pj[x]              ;
894
                        g[6] += pi[x] * pj[x]      ;
895
                        g[5] += iy[x] * pj[x]      ;
896
                        g[4] += ix[x] * pj[x]      ;
897
                        g[3] += yy * iy[x] * pj[x] ;
898
                        g[2] += xx * iy[x] * pj[x] ;
899
                        g[1] += yy * ix[x] * pj[x] ;
900
                        g[0] += xx * ix[x] * pj[x] ;
901
#endif
902
                    }
903
                }
904
                
905
                double dp[8] = {};
906
                // Compute dA = G^-1 g
907
                for(int i=0; i<8; ++i)
908
                {
909
                    const double *pG = invG + 8*i;
910
                    dp[i] = 0;
911
                    
912
                    for(int j=0; j<8; ++j)
913
                    {
914
                        dp[i] += pG[j] * g[j];
915
                    }
916
                }
917

  
918
                if(fabs(dp[6]) < 1e-5)
919
                {
920
                    pt_status = 0;
921
                    break;
922
                }
923

  
924
                for(int i=0; i<5; ++i)
925
                    dp[i] /= dp[6];
926

  
927
                // Update Av. 
928
                // I( (I + dA)x + dv ) - J( A x + v )
929
                // let y = (I + dA) x + dv, then x = (I + dA)^-1 (y - dv)
930
                // => I( y ) - J( A (I + dA)^-1 y + (v - A (I+dA)^-1 dv))
931
                // Compute determinant of (I+dA)
932

  
933
                D = 1.0/((1+dp[0])*(1+dp[3]) - dp[1]*dp[2]);
934

  
935
                // Inverse of (I+dA) is 1/det(I+dA) * [ 1+dp[3] , -dp[1] ; -dp[2] , 1+dp[0] ]
936

  
937
                float _Av[6];
938
                _Av[0] = (float) ( (Av[0]*(1+dp[3]) - Av[1]*dp[2] ) * D );
939
                _Av[1] = (float) ( (Av[1]*(1+dp[0]) - Av[0]*dp[1] ) * D );
940
                _Av[2] = Av[2] - ( _Av[0] * dp[4] + _Av[1] * dp[5] );
941
                _Av[3] = (float) ( (Av[3]*(1+dp[3]) - Av[4] * dp[2] ) * D );
942
                _Av[4] = (float) ( (Av[4]*(1+dp[0]) - Av[3] * dp[1] ) * D );
943
                _Av[5] = Av[5] - ( _Av[3] * dp[4] + _Av[4] * dp[5] );
944

  
945
                // Check if new (intermediate) affine distortion is reasonable
946
                double n1 = hypot( _Av[0], _Av[3] );    // norm of first column of A = A (1, 0)^T
947
                double n2 = hypot( _Av[1], _Av[4] );    // norm of second column of A = A (0, 1)^T
948
               
949
                // Check for extreme foreshortening 
950
                if( n1 < 0.2 || n1 > 5 )
951
                {
952
                    pt_status = 0;
953
                    break;
954
                }
955
                if( n2 < 0.2 || n2 > 5 )
956
                {
957
                    pt_status = 0;
958
                    break;
959
                }
960
                // Check for extreme distortion
961
                if( fabs(_Av[0]*_Av[1] + _Av[3]*_Av[4]) > 0.92*n1*n2 )
962
                {
963
                    pt_status = 0;
964
                    break;
965
                }
966

  
967
                // Copy values and check parameter change
968
                float delta = 0;
969
                for(int i=0; i<6; ++i)
970
                {
971
                    float dA = Av[i] - _Av[i];
972
                    delta += dA * dA;
973
                    Av[i] = _Av[i];
974
                }
975

  
976
                alpha = dp[6];
977
#ifdef DO_SCALE
978
                beta = dp[7] * 255;
979
#else
980
                beta = dp[7];
981
#endif
982

  
983
                if( delta < criteria.epsilon )
984
                    break;
985
            }
986
            
987
            featuresB[i].x = Av[2];
988
            featuresB[i].y = Av[5];
989
            
990
            matrixB[4*i+0] = Av[0];
991
            matrixB[4*i+1] = Av[1];
992
            matrixB[4*i+2] = Av[3];
993
            matrixB[4*i+3] = Av[4];
994

  
995
            status[i] = (char)pt_status;
996
            if( error && pt_status )
997
            {
998
                // calc error
999
                double err = 0;
1000
                for( y = 0; y < patchSize.height; y++ )
1001
                {
1002
                    const float* pi = patchI + y*patchSize.width;
1003
                    const float* pj = patchJ + y*patchSize.width;
1004
                    
1005
                    for( x = 0; x < patchSize.width; x++ )
1006
                    {
1007
                        double t = alpha*pi[x] + beta - pj[x];
1008
                        err += t * t;
1009
                    }
1010
                }
1011
                error[i] = (float)sqrt(err);
1012
            }
1013
        } // end of point processing loop (i)
1014
    }
1015
    
1016
    const CvMat* imgJ;
1017
    const CvPoint2D32f* featuresA;
1018
    const CvAffineConsistencyPatch* affinePatchA;
1019
    CvPoint2D32f* featuresB;
1020
    float* matrixB;
1021
    char* status;
1022
    float* error;
1023
    CvTermCriteria criteria;
1024
    CvSize winSize;
1025
};
1026

  
794 1027
struct LKTrackerInvoker
795 1028
{
796 1029
    LKTrackerInvoker( const CvMat* _imgI, const CvMat* _imgJ,
......
1020 1253
    int flags;
1021 1254
};
1022 1255
    
1256
}
1257

  
1258
CV_IMPL void
1259
cvInitAffineConsistencyPatch( CvAffineConsistencyPatch *patch, CvSize winSize )
1260
{
1261
    if( !patch )
1262
        CV_Error( CV_StsNullPtr, "" );
1263

  
1264
    if( winSize.width <= 0 || winSize.height <= 0 )
1265
        CV_Error( CV_StsOutOfRange, "window size must be positive" );
1266

  
1267
    /* clear existing values */
1268
    memset( patch, 0, sizeof *patch );
1269

  
1270
    /* allocate memory for patch (f), gradients (fx, fy) and inverse G = sum_x h(x)*h(x)^T */
1271
    int w = 2*winSize.width + 1;
1272
    int h = 2*winSize.height + 1;
1273

  
1274
    patch->f = cvCreateMat(w, h, CV_32FC1);
1275
    patch->fx = cvCreateMat(w, h, CV_32FC1);
1276
    patch->fy = cvCreateMat(w, h, CV_32FC1);
1277
    patch->invG = cvCreateMat(8, 8, CV_64FC1);
1278
}
1279

  
1280
CV_IMPL void
1281
cvClearAffineConsistencyPatchData( CvAffineConsistencyPatch *patch )
1282
{
1283
    if( patch )
1284
    {
1285
        cvReleaseMat( &patch->f );
1286
        cvReleaseMat( &patch->fx );
1287
        cvReleaseMat( &patch->fy );
1288
        cvReleaseMat( &patch->invG );
1289

  
1290
        memset( patch, 0, sizeof *patch );
1291
    }
1292
}
1293

  
1294
CV_IMPL void
1295
cvSwapAffineConsistencyPatch( CvAffineConsistencyPatch *a, CvAffineConsistencyPatch *b )
1296
{
1297
    std::swap(*a, *b);
1298
}
1299

  
1300
CV_IMPL void
1301
cvAffineConsistencyCheck( const void* arrB, 
1302
                          const CvPoint2D32f * featuresA,
1303
                          const CvAffineConsistencyPatch * patchA,
1304
                          CvPoint2D32f* featuresB,
1305
                          float *matrixB,
1306
                          int count, CvSize winSize, 
1307
                          char *status, float *error,
1308
                          CvTermCriteria criteria )
1309
{
1310
    cv::AutoBuffer<uchar> buffer;
1311
    cv::AutoBuffer<char> _status;
1312

  
1313
    CvMat stubB, *imgB = (CvMat*)arrB;
1314
    CvSize imgSize;
1023 1315
    
1316
    imgB = cvGetMat( imgB, &stubB );
1317

  
1318
    if( CV_MAT_TYPE( imgB->type ) != CV_8UC1 )
1319
        CV_Error( CV_StsUnsupportedFormat, "" );
1320

  
1321
    imgSize = cvGetMatSize( imgB );
1322

  
1323
    if( count == 0 )
1324
        return;
1325

  
1326
    if( !featuresA || !featuresB )
1327
        CV_Error( CV_StsNullPtr, "Some of arrays of point coordinates are missing" );
1328

  
1329
    if( count < 0 )
1330
        CV_Error( CV_StsOutOfRange, "The number of tracked points is negative" );
1331

  
1332
    if( winSize.width <= 1 || winSize.height <= 1 )
1333
        CV_Error( CV_StsBadSize, "Invalid search window size" );
1334

  
1335
    if( !status )
1336
    {
1337
        _status.allocate(count);
1338
        status = _status;
1339
    }
1340

  
1341
    memset( status, 1, count );
1342
    if( error )
1343
        memset( error, 0, count*sizeof(error[0]) );
1344

  
1345
    cv::parallel_for(cv::BlockedRange(0, count),
1346
                     cv::AffineConsistencyCheckInvoker(imgB, featuresA, patchA,
1347
                                                       featuresB, matrixB, status, error,
1348
                                                       criteria, winSize));
1024 1349
}
1025 1350

  
1351
CV_IMPL void cvGetAffineConsistencyPatches( const CvArr*  arrA,
1352
                                            const CvPoint2D32f* prev_features, 
1353
                                            CvAffineConsistencyPatch* initial_patches,
1354
                                            float*    affine_matrix,
1355
                                            int       count,
1356
                                            CvSize    winSize )
1357
{
1358
    static const float smoothKernel[] = { 0.09375, 0.3125, 0.09375 };  /* 3/32, 10/32, 3/32 */
1359
    CvMat stubA, *imgA = (CvMat*) arrA;
1360
    imgA = cvGetMat( imgA, &stubA );
1361
    cv::Mat G(8, 8, CV_64FC1);
1362
    float *patchI, *tmpBuffer;
1026 1363

  
1364
    CvSize patchSize = cvSize( winSize.width * 2 + 1, winSize.height * 2 + 1 );
1365
    int patchLen = patchSize.width * patchSize.height;
1366
    int patchStep = patchSize.width * sizeof( patchI[0] );
1367
    CvSize srcPatchSize = cvSize( patchSize.width + 2, patchSize.height + 2 );
1368
    int srcPatchLen = (patchSize.width + 2)*(patchSize.height + 2);
1369
    int srcPatchStep = srcPatchSize.width * sizeof( patchI[0] );
1370
    CvSize imgSize;
1371
    float eps = (float)MIN(winSize.width, winSize.height);
1372
   
1373
    if( CV_MAT_TYPE( imgA->type ) != CV_8UC1 )
1374
        CV_Error( CV_StsUnsupportedFormat, "" );
1375

  
1376
    imgSize = cvGetMatSize( imgA );
1377

  
1378
    cv::AutoBuffer<float> buf(patchLen + srcPatchLen);
1379
    patchI = buf;
1380
    tmpBuffer = patchI + srcPatchLen;
1381
     
1382
    for( int i=0; i<count; i++ )
1383
    {
1384
            const CvPoint2D32f & u = prev_features[i];
1385

  
1386
            float * const I = (float*) initial_patches[i].f->data.ptr;
1387
            float * const Ix = (float*) initial_patches[i].fx->data.ptr;
1388
            float * const Iy = (float*) initial_patches[i].fy->data.ptr;
1389

  
1390
            if( u.x < -eps || u.x >= imgSize.width+eps ||
1391
                u.y < -eps || u.y >= imgSize.height+eps ||
1392
                icvGetRectSubPix_8u32f_C1R( imgA->data.ptr, imgA->step,
1393
                imgSize, patchI, srcPatchStep, srcPatchSize, u ) < 0 )
1394
            {
1395
                // point is outside the first image. take the next
1396
                continue;
1397
            }
1398
     
1399
            /* repack patchI into initial_patches.f (remove borders) */
1400
            for( int k = 0; k < patchSize.height; k++ )
1401
                memcpy( I + k * patchSize.width,
1402
                        patchI + (k + 1) * srcPatchSize.width + 1, patchStep );
1403
       
1404
            icvCalcIxIy_32f( patchI, srcPatchStep, Ix, Iy,
1405
                (srcPatchSize.width-2)*sizeof(patchI[0]), srcPatchSize,
1406
                smoothKernel, tmpBuffer );
1407

  
1408
            // Compute G = sum h*h'
1409
            // Where h = (x Ix, y Ix, x Iy, y Iy, Ix, Iy, I, 1)
1410
           
1411
            G = cvScalar(0);
1412
            for( int y=-winSize.height, yy=1, yyy=0; yy < srcPatchSize.height-1; ++yyy, ++yy, ++y )
1413
            {
1414
                // Scale i to be in the range between 0 and 1 instead of 0 and 255
1415
                // This also scales ix and iy
1416
                CvSize sz = cvGetSize(initial_patches[i].fx);
1417
                const float * const i = patchI + yy*srcPatchSize.width + 1;
1418
                const float * const ix = Ix + yyy*patchSize.width;
1419
                const float * const iy = Iy + yyy*patchSize.width;
1420

  
1421
                for( int x=-winSize.width, xx=0; xx < srcPatchSize.width-2; ++xx, ++x )
1422
                {
1423
#ifdef DO_SCALE
1424
                    G.at<double>(0,0) += (x*ix[xx]) * (x*ix[xx]) / (255 * 255);
1425
                    G.at<double>(0,1) += (x*ix[xx]) * (y*ix[xx]) / (255 * 255);
1426
                    G.at<double>(0,2) += (x*ix[xx]) * (x*iy[xx]) / (255 * 255);
1427
                    G.at<double>(0,3) += (x*ix[xx]) * (y*iy[xx]) / (255 * 255);
1428
                    G.at<double>(0,4) += (x*ix[xx]) * (ix[xx])   / (255 * 255);
1429
                    G.at<double>(0,5) += (x*ix[xx]) * (iy[xx])   / (255 * 255);
1430
                    G.at<double>(0,6) += (x*ix[xx]) * (i[xx])    / (255 * 255);
1431
                    G.at<double>(0,7) += (x*ix[xx])              /  255;
1432

  
1433
                    G.at<double>(1,1) += (y*ix[xx]) * (y*ix[xx]) / (255 * 255);
1434
                    G.at<double>(1,2) += (y*ix[xx]) * (x*iy[xx]) / (255 * 255);
1435
                    G.at<double>(1,3) += (y*ix[xx]) * (y*iy[xx]) / (255 * 255);
1436
                    G.at<double>(1,4) += (y*ix[xx]) * (ix[xx])   / (255 * 255);
1437
                    G.at<double>(1,5) += (y*ix[xx]) * (iy[xx])   / (255 * 255);
1438
                    G.at<double>(1,6) += (y*ix[xx]) * (i[xx])    / (255 * 255);
1439
                    G.at<double>(1,7) += (y*ix[xx])              /  255;
1440

  
1441
                    G.at<double>(2,2) += (x*iy[xx]) * (x*iy[xx]) / (255 * 255);
1442
                    G.at<double>(2,3) += (x*iy[xx]) * (y*iy[xx]) / (255 * 255);
1443
                    G.at<double>(2,4) += (x*iy[xx]) * (ix[xx])   / (255 * 255);
1444
                    G.at<double>(2,5) += (x*iy[xx]) * (iy[xx])   / (255 * 255);
1445
                    G.at<double>(2,6) += (x*iy[xx]) * (i[xx])    / (255 * 255);
1446
                    G.at<double>(2,7) += (x*iy[xx])              /  255;
1447

  
1448
                    G.at<double>(3,3) += (y*iy[xx]) * (y*iy[xx]) / (255 * 255);
1449
                    G.at<double>(3,4) += (y*iy[xx]) * (ix[xx])   / (255 * 255);
1450
                    G.at<double>(3,5) += (y*iy[xx]) * (iy[xx])   / (255 * 255);
1451
                    G.at<double>(3,6) += (y*iy[xx]) * (i[xx])    / (255 * 255);
1452
                    G.at<double>(3,7) += (y*iy[xx])              /  255;
1453

  
1454
                    G.at<double>(4,4) += (ix[xx])   * (ix[xx])   / (255 * 255);
1455
                    G.at<double>(4,5) += (ix[xx])   * (iy[xx])   / (255 * 255);
1456
                    G.at<double>(4,6) += (ix[xx])   * (i[xx])    / (255 * 255);
1457
                    G.at<double>(4,7) += (ix[xx])                /  255;
1458

  
1459
                    G.at<double>(5,5) += (iy[xx])   * (iy[xx])   / (255 * 255);
1460
                    G.at<double>(5,6) += (iy[xx])   * (i[xx])    / (255 * 255);
1461
                    G.at<double>(5,7) += (iy[xx])                /  255 ;
1462

  
1463
                    G.at<double>(6,6) += (i[xx])    * (i[xx])    / (255 * 255);
1464
                    G.at<double>(6,7) += (i[xx])                 /  255;
1465

  
1466
                    G.at<double>(7,7) += 1;
1467
#else
1468
                    G.at<double>(0,0) += (x*ix[xx]) * (x*ix[xx]) ;
1469
                    G.at<double>(0,1) += (x*ix[xx]) * (y*ix[xx]) ;
1470
                    G.at<double>(0,2) += (x*ix[xx]) * (x*iy[xx]) ;
1471
                    G.at<double>(0,3) += (x*ix[xx]) * (y*iy[xx]) ;
1472
                    G.at<double>(0,4) += (x*ix[xx]) * (ix[xx])   ;
1473
                    G.at<double>(0,5) += (x*ix[xx]) * (iy[xx])   ;
1474
                    G.at<double>(0,6) += (x*ix[xx]) * (i[xx])    ;
1475
                    G.at<double>(0,7) += (x*ix[xx])              ;
1476

  
1477
                    G.at<double>(1,1) += (y*ix[xx]) * (y*ix[xx]) ;
1478
                    G.at<double>(1,2) += (y*ix[xx]) * (x*iy[xx]) ;
1479
                    G.at<double>(1,3) += (y*ix[xx]) * (y*iy[xx]) ;
1480
                    G.at<double>(1,4) += (y*ix[xx]) * (ix[xx])   ;
1481
                    G.at<double>(1,5) += (y*ix[xx]) * (iy[xx])   ;
1482
                    G.at<double>(1,6) += (y*ix[xx]) * (i[xx])    ;
1483
                    G.at<double>(1,7) += (y*ix[xx])              ;
1484

  
1485
                    G.at<double>(2,2) += (x*iy[xx]) * (x*iy[xx]) ;
1486
                    G.at<double>(2,3) += (x*iy[xx]) * (y*iy[xx]) ;
1487
                    G.at<double>(2,4) += (x*iy[xx]) * (ix[xx])   ;
1488
                    G.at<double>(2,5) += (x*iy[xx]) * (iy[xx])   ;
1489
                    G.at<double>(2,6) += (x*iy[xx]) * (i[xx])    ;
1490
                    G.at<double>(2,7) += (x*iy[xx])              ;
1491

  
1492
                    G.at<double>(3,3) += (y*iy[xx]) * (y*iy[xx]) ;
1493
                    G.at<double>(3,4) += (y*iy[xx]) * (ix[xx])   ;
1494
                    G.at<double>(3,5) += (y*iy[xx]) * (iy[xx])   ;
1495
                    G.at<double>(3,6) += (y*iy[xx]) * (i[xx])    ;
1496
                    G.at<double>(3,7) += (y*iy[xx])              ;
1497

  
1498
                    G.at<double>(4,4) += (ix[xx])   * (ix[xx])   ;
1499
                    G.at<double>(4,5) += (ix[xx])   * (iy[xx])   ;
1500
                    G.at<double>(4,6) += (ix[xx])   * (i[xx])    ;
1501
                    G.at<double>(4,7) += (ix[xx])                ;
1502

  
1503
                    G.at<double>(5,5) += (iy[xx])   * (iy[xx])   ;
1504
                    G.at<double>(5,6) += (iy[xx])   * (i[xx])    ;
1505
                    G.at<double>(5,7) += (iy[xx])                ;
1506

  
1507
                    G.at<double>(6,6) += (i[xx])    * (i[xx])    ;
1508
                    G.at<double>(6,7) += (i[xx])                 ;
1509

  
1510
                    G.at<double>(7,7) += 1;
1511

  
1512
#endif
1513
                }
1514
            }
1515

  
1516
            // Fill lower half (symmetric)
1517
            for( int k=1; k<8; ++k )
1518
                for( int m=0; m<k; ++m )
1519
                    G.at<double>(k,m) = G.at<double>(m,k);
1520

  
1521
            // Invert G and store in invG
1522
            cv::Mat invGref = initial_patches[i].invG;
1523
            invGref = G.inv();
1524

  
1525
            // Set matrix to identity.
1526
            affine_matrix[4*i + 0] = 1;
1527
            affine_matrix[4*i + 1] = 0;
1528
            affine_matrix[4*i + 2] = 0;
1529
            affine_matrix[4*i + 3] = 1;
1530
    }
1531
}
1532

  
1027 1533
CV_IMPL void
1028 1534
cvCalcOpticalFlowPyrLK( const void* arrA, const void* arrB,
1029 1535
                        void* pyrarrA, void* pyrarrB,
......
1103 1609
        CV_Error( CV_StsNullPtr, "Some of arrays of point coordinates are missing" );
1104 1610

  
1105 1611
    if( count < 0 )
1106
        CV_Error( CV_StsOutOfRange, "The number of tracked points is negative or zero" );
1612
        CV_Error( CV_StsOutOfRange, "The number of tracked points is negative" );
1107 1613

  
1108 1614
    if( winSize.width <= 1 || winSize.height <= 1 )
1109 1615
        CV_Error( CV_StsBadSize, "Invalid search window size" );