~gabriel1984sibiu/opencv1/opencv

« back to all changes in this revision

Viewing changes to modules/legacy/src/texture.cpp

  • Committer: Vadim Pisarevsky
  • Date: 2014-06-24 15:18:51 UTC
  • mto: This revision was merged to the branch mainline in revision 6051.
  • Revision ID: git-v1:3858f2291d64652a82fea930ba5c598045633843
removed contrib, legacy and softcsscade modules; removed latentsvm and datamatrix detector from objdetect. removed haartraining and sft apps.
some of the stuff will be moved to opencv_contrib module.
in order to make this PR pass buildbot, please, comment off opencv_legacy, opencv_contrib and opencv_softcascade test runs.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*M///////////////////////////////////////////////////////////////////////////////////////
2
 
//
3
 
//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4
 
//
5
 
//  By downloading, copying, installing or using the software you agree to this license.
6
 
//  If you do not agree to this license, do not download, install,
7
 
//  copy or use the software.
8
 
//
9
 
//
10
 
//                        Intel License Agreement
11
 
//                For Open Source Computer Vision Library
12
 
//
13
 
// Copyright (C) 2000, Intel Corporation, all rights reserved.
14
 
// Third party copyrights are property of their respective owners.
15
 
//
16
 
// Redistribution and use in source and binary forms, with or without modification,
17
 
// are permitted provided that the following conditions are met:
18
 
//
19
 
//   * Redistribution's of source code must retain the above copyright notice,
20
 
//     this list of conditions and the following disclaimer.
21
 
//
22
 
//   * Redistribution's in binary form must reproduce the above copyright notice,
23
 
//     this list of conditions and the following disclaimer in the documentation
24
 
//     and/or other materials provided with the distribution.
25
 
//
26
 
//   * The name of Intel Corporation may not be used to endorse or promote products
27
 
//     derived from this software without specific prior written permission.
28
 
//
29
 
// This software is provided by the copyright holders and contributors "as is" and
30
 
// any express or implied warranties, including, but not limited to, the implied
31
 
// warranties of merchantability and fitness for a particular purpose are disclaimed.
32
 
// In no event shall the Intel Corporation or contributors be liable for any direct,
33
 
// indirect, incidental, special, exemplary, or consequential damages
34
 
// (including, but not limited to, procurement of substitute goods or services;
35
 
// loss of use, data, or profits; or business interruption) however caused
36
 
// and on any theory of liability, whether in contract, strict liability,
37
 
// or tort (including negligence or otherwise) arising in any way out of
38
 
// the use of this software, even if advised of the possibility of such damage.
39
 
//
40
 
//M*/
41
 
 
42
 
/****************************************************************************************\
43
 
 
44
 
      Calculation of a texture descriptors from GLCM (Grey Level Co-occurrence Matrix'es)
45
 
      The code was submitted by Daniel Eaton [danieljameseaton@yahoo.com]
46
 
 
47
 
\****************************************************************************************/
48
 
 
49
 
#include "precomp.hpp"
50
 
 
51
 
#include <math.h>
52
 
#include <assert.h>
53
 
 
54
 
#define CV_MAX_NUM_GREY_LEVELS_8U  256
55
 
 
56
 
struct CvGLCM
57
 
{
58
 
    int matrixSideLength;
59
 
    int numMatrices;
60
 
    double*** matrices;
61
 
 
62
 
    int  numLookupTableElements;
63
 
    int  forwardLookupTable[CV_MAX_NUM_GREY_LEVELS_8U];
64
 
    int  reverseLookupTable[CV_MAX_NUM_GREY_LEVELS_8U];
65
 
 
66
 
    double** descriptors;
67
 
    int numDescriptors;
68
 
    int descriptorOptimizationType;
69
 
    int optimizationType;
70
 
};
71
 
 
72
 
 
73
 
static void icvCreateGLCM_LookupTable_8u_C1R( const uchar* srcImageData, int srcImageStep,
74
 
                                             CvSize srcImageSize, CvGLCM* destGLCM,
75
 
                                             int* steps, int numSteps, int* memorySteps );
76
 
 
77
 
static void
78
 
icvCreateGLCMDescriptors_AllowDoubleNest( CvGLCM* destGLCM, int matrixIndex );
79
 
 
80
 
 
81
 
CV_IMPL CvGLCM*
82
 
cvCreateGLCM( const IplImage* srcImage,
83
 
              int stepMagnitude,
84
 
              const int* srcStepDirections,/* should be static array..
85
 
                                          or if not the user should handle de-allocation */
86
 
              int numStepDirections,
87
 
              int optimizationType )
88
 
{
89
 
    static const int defaultStepDirections[] = { 0,1, -1,1, -1,0, -1,-1 };
90
 
 
91
 
    int* memorySteps = 0;
92
 
    CvGLCM* newGLCM = 0;
93
 
    int* stepDirections = 0;
94
 
 
95
 
    CV_FUNCNAME( "cvCreateGLCM" );
96
 
 
97
 
    __BEGIN__;
98
 
 
99
 
    uchar* srcImageData = 0;
100
 
    CvSize srcImageSize;
101
 
    int srcImageStep;
102
 
    int stepLoop;
103
 
    const int maxNumGreyLevels8u = CV_MAX_NUM_GREY_LEVELS_8U;
104
 
 
105
 
    if( !srcImage )
106
 
        CV_ERROR( CV_StsNullPtr, "" );
107
 
 
108
 
    if( srcImage->nChannels != 1 )
109
 
        CV_ERROR( CV_BadNumChannels, "Number of channels must be 1");
110
 
 
111
 
    if( srcImage->depth != IPL_DEPTH_8U )
112
 
        CV_ERROR( CV_BadDepth, "Depth must be equal IPL_DEPTH_8U");
113
 
 
114
 
    // no Directions provided, use the default ones - 0 deg, 45, 90, 135
115
 
    if( !srcStepDirections )
116
 
    {
117
 
        srcStepDirections = defaultStepDirections;
118
 
    }
119
 
 
120
 
    CV_CALL( stepDirections = (int*)cvAlloc( numStepDirections*2*sizeof(stepDirections[0])));
121
 
    memcpy( stepDirections, srcStepDirections, numStepDirections*2*sizeof(stepDirections[0]));
122
 
 
123
 
    cvGetImageRawData( srcImage, &srcImageData, &srcImageStep, &srcImageSize );
124
 
 
125
 
    // roll together Directions and magnitudes together with knowledge of image (step)
126
 
    CV_CALL( memorySteps = (int*)cvAlloc( numStepDirections*sizeof(memorySteps[0])));
127
 
 
128
 
    for( stepLoop = 0; stepLoop < numStepDirections; stepLoop++ )
129
 
    {
130
 
        stepDirections[stepLoop*2 + 0] *= stepMagnitude;
131
 
        stepDirections[stepLoop*2 + 1] *= stepMagnitude;
132
 
 
133
 
        memorySteps[stepLoop] = stepDirections[stepLoop*2 + 0]*srcImageStep +
134
 
                                stepDirections[stepLoop*2 + 1];
135
 
    }
136
 
 
137
 
    CV_CALL( newGLCM = (CvGLCM*)cvAlloc(sizeof(newGLCM)));
138
 
    memset( newGLCM, 0, sizeof(*newGLCM) );
139
 
 
140
 
    newGLCM->matrices = 0;
141
 
    newGLCM->numMatrices = numStepDirections;
142
 
    newGLCM->optimizationType = optimizationType;
143
 
 
144
 
    if( optimizationType <= CV_GLCM_OPTIMIZATION_LUT )
145
 
    {
146
 
        int lookupTableLoop, imageColLoop, imageRowLoop, lineOffset = 0;
147
 
 
148
 
        // if optimization type is set to lut, then make one for the image
149
 
        if( optimizationType == CV_GLCM_OPTIMIZATION_LUT )
150
 
        {
151
 
            for( imageRowLoop = 0; imageRowLoop < srcImageSize.height;
152
 
                                   imageRowLoop++, lineOffset += srcImageStep )
153
 
            {
154
 
                for( imageColLoop = 0; imageColLoop < srcImageSize.width; imageColLoop++ )
155
 
                {
156
 
                    newGLCM->forwardLookupTable[srcImageData[lineOffset+imageColLoop]]=1;
157
 
                }
158
 
            }
159
 
 
160
 
            newGLCM->numLookupTableElements = 0;
161
 
 
162
 
            for( lookupTableLoop = 0; lookupTableLoop < maxNumGreyLevels8u; lookupTableLoop++ )
163
 
            {
164
 
                if( newGLCM->forwardLookupTable[ lookupTableLoop ] != 0 )
165
 
                {
166
 
                    newGLCM->forwardLookupTable[ lookupTableLoop ] =
167
 
                        newGLCM->numLookupTableElements;
168
 
                    newGLCM->reverseLookupTable[ newGLCM->numLookupTableElements ] =
169
 
                        lookupTableLoop;
170
 
 
171
 
                    newGLCM->numLookupTableElements++;
172
 
                }
173
 
            }
174
 
        }
175
 
        // otherwise make a "LUT" which contains all the gray-levels (for code-reuse)
176
 
        else if( optimizationType == CV_GLCM_OPTIMIZATION_NONE )
177
 
        {
178
 
            for( lookupTableLoop = 0; lookupTableLoop <maxNumGreyLevels8u; lookupTableLoop++ )
179
 
            {
180
 
                newGLCM->forwardLookupTable[ lookupTableLoop ] = lookupTableLoop;
181
 
                newGLCM->reverseLookupTable[ lookupTableLoop ] = lookupTableLoop;
182
 
            }
183
 
            newGLCM->numLookupTableElements = maxNumGreyLevels8u;
184
 
        }
185
 
 
186
 
        newGLCM->matrixSideLength = newGLCM->numLookupTableElements;
187
 
        icvCreateGLCM_LookupTable_8u_C1R( srcImageData, srcImageStep, srcImageSize,
188
 
                                          newGLCM, stepDirections,
189
 
                                          numStepDirections, memorySteps );
190
 
    }
191
 
    else if( optimizationType == CV_GLCM_OPTIMIZATION_HISTOGRAM )
192
 
    {
193
 
        CV_ERROR( CV_StsBadFlag, "Histogram-based method is not implemented" );
194
 
 
195
 
    /*  newGLCM->numMatrices *= 2;
196
 
        newGLCM->matrixSideLength = maxNumGreyLevels8u*2;
197
 
 
198
 
        icvCreateGLCM_Histogram_8uC1R( srcImageStep, srcImageSize, srcImageData,
199
 
                                       newGLCM, numStepDirections,
200
 
                                       stepDirections, memorySteps );
201
 
    */
202
 
    }
203
 
 
204
 
    __END__;
205
 
 
206
 
    cvFree( &memorySteps );
207
 
    cvFree( &stepDirections );
208
 
 
209
 
    if( cvGetErrStatus() < 0 )
210
 
    {
211
 
        cvFree( &newGLCM );
212
 
    }
213
 
 
214
 
    return newGLCM;
215
 
}
216
 
 
217
 
 
218
 
CV_IMPL void
219
 
cvReleaseGLCM( CvGLCM** GLCM, int flag )
220
 
{
221
 
    CV_FUNCNAME( "cvReleaseGLCM" );
222
 
 
223
 
    __BEGIN__;
224
 
 
225
 
    int matrixLoop;
226
 
 
227
 
    if( !GLCM )
228
 
        CV_ERROR( CV_StsNullPtr, "" );
229
 
 
230
 
    if( *GLCM )
231
 
        EXIT; // repeated deallocation: just skip it.
232
 
 
233
 
    if( (flag == CV_GLCM_GLCM || flag == CV_GLCM_ALL) && (*GLCM)->matrices )
234
 
    {
235
 
        for( matrixLoop = 0; matrixLoop < (*GLCM)->numMatrices; matrixLoop++ )
236
 
        {
237
 
            if( (*GLCM)->matrices[ matrixLoop ] )
238
 
            {
239
 
                cvFree( (*GLCM)->matrices[matrixLoop] );
240
 
                cvFree( (*GLCM)->matrices + matrixLoop );
241
 
            }
242
 
        }
243
 
 
244
 
        cvFree( &((*GLCM)->matrices) );
245
 
    }
246
 
 
247
 
    if( (flag == CV_GLCM_DESC || flag == CV_GLCM_ALL) && (*GLCM)->descriptors )
248
 
    {
249
 
        for( matrixLoop = 0; matrixLoop < (*GLCM)->numMatrices; matrixLoop++ )
250
 
        {
251
 
            cvFree( (*GLCM)->descriptors + matrixLoop );
252
 
        }
253
 
        cvFree( &((*GLCM)->descriptors) );
254
 
    }
255
 
 
256
 
    if( flag == CV_GLCM_ALL )
257
 
    {
258
 
        cvFree( GLCM );
259
 
    }
260
 
 
261
 
    __END__;
262
 
}
263
 
 
264
 
 
265
 
static void
266
 
icvCreateGLCM_LookupTable_8u_C1R( const uchar* srcImageData,
267
 
                                  int srcImageStep,
268
 
                                  CvSize srcImageSize,
269
 
                                  CvGLCM* destGLCM,
270
 
                                  int* steps,
271
 
                                  int numSteps,
272
 
                                  int* memorySteps )
273
 
{
274
 
    int* stepIncrementsCounter = 0;
275
 
 
276
 
    CV_FUNCNAME( "icvCreateGLCM_LookupTable_8u_C1R" );
277
 
 
278
 
    __BEGIN__;
279
 
 
280
 
    int matrixSideLength = destGLCM->matrixSideLength;
281
 
    int stepLoop, sideLoop1, sideLoop2;
282
 
    int colLoop, rowLoop, lineOffset = 0;
283
 
    double*** matrices = 0;
284
 
 
285
 
    // allocate memory to the matrices
286
 
    CV_CALL( destGLCM->matrices = (double***)cvAlloc( sizeof(matrices[0])*numSteps ));
287
 
    matrices = destGLCM->matrices;
288
 
 
289
 
    for( stepLoop=0; stepLoop<numSteps; stepLoop++ )
290
 
    {
291
 
        CV_CALL( matrices[stepLoop] = (double**)cvAlloc( sizeof(matrices[0])*matrixSideLength ));
292
 
        CV_CALL( matrices[stepLoop][0] = (double*)cvAlloc( sizeof(matrices[0][0])*
293
 
                                                  matrixSideLength*matrixSideLength ));
294
 
 
295
 
        memset( matrices[stepLoop][0], 0, matrixSideLength*matrixSideLength*
296
 
                                          sizeof(matrices[0][0]) );
297
 
 
298
 
        for( sideLoop1 = 1; sideLoop1 < matrixSideLength; sideLoop1++ )
299
 
        {
300
 
            matrices[stepLoop][sideLoop1] = matrices[stepLoop][sideLoop1-1] + matrixSideLength;
301
 
        }
302
 
    }
303
 
 
304
 
    CV_CALL( stepIncrementsCounter = (int*)cvAlloc( numSteps*sizeof(stepIncrementsCounter[0])));
305
 
    memset( stepIncrementsCounter, 0, numSteps*sizeof(stepIncrementsCounter[0]) );
306
 
 
307
 
    // generate GLCM for each step
308
 
    for( rowLoop=0; rowLoop<srcImageSize.height; rowLoop++, lineOffset+=srcImageStep )
309
 
    {
310
 
        for( colLoop=0; colLoop<srcImageSize.width; colLoop++ )
311
 
        {
312
 
            int pixelValue1 = destGLCM->forwardLookupTable[srcImageData[lineOffset + colLoop]];
313
 
 
314
 
            for( stepLoop=0; stepLoop<numSteps; stepLoop++ )
315
 
            {
316
 
                int col2, row2;
317
 
                row2 = rowLoop + steps[stepLoop*2 + 0];
318
 
                col2 = colLoop + steps[stepLoop*2 + 1];
319
 
 
320
 
                if( col2>=0 && row2>=0 && col2<srcImageSize.width && row2<srcImageSize.height )
321
 
                {
322
 
                    int memoryStep = memorySteps[ stepLoop ];
323
 
                    int pixelValue2 = destGLCM->forwardLookupTable[ srcImageData[ lineOffset + colLoop + memoryStep ] ];
324
 
 
325
 
                    // maintain symmetry
326
 
                    matrices[stepLoop][pixelValue1][pixelValue2] ++;
327
 
                    matrices[stepLoop][pixelValue2][pixelValue1] ++;
328
 
 
329
 
                    // incremenet counter of total number of increments
330
 
                    stepIncrementsCounter[stepLoop] += 2;
331
 
                }
332
 
            }
333
 
        }
334
 
    }
335
 
 
336
 
    // normalize matrices. each element is a probability of gray value i,j adjacency in direction/magnitude k
337
 
    for( sideLoop1=0; sideLoop1<matrixSideLength; sideLoop1++ )
338
 
    {
339
 
        for( sideLoop2=0; sideLoop2<matrixSideLength; sideLoop2++ )
340
 
        {
341
 
            for( stepLoop=0; stepLoop<numSteps; stepLoop++ )
342
 
            {
343
 
                matrices[stepLoop][sideLoop1][sideLoop2] /= double(stepIncrementsCounter[stepLoop]);
344
 
            }
345
 
        }
346
 
    }
347
 
 
348
 
    destGLCM->matrices = matrices;
349
 
 
350
 
    __END__;
351
 
 
352
 
    cvFree( &stepIncrementsCounter );
353
 
 
354
 
    if( cvGetErrStatus() < 0 )
355
 
        cvReleaseGLCM( &destGLCM, CV_GLCM_GLCM );
356
 
}
357
 
 
358
 
 
359
 
CV_IMPL void
360
 
cvCreateGLCMDescriptors( CvGLCM* destGLCM, int descriptorOptimizationType )
361
 
{
362
 
    CV_FUNCNAME( "cvCreateGLCMDescriptors" );
363
 
 
364
 
    __BEGIN__;
365
 
 
366
 
    int matrixLoop;
367
 
 
368
 
    if( !destGLCM )
369
 
        CV_ERROR( CV_StsNullPtr, "" );
370
 
 
371
 
    if( !(destGLCM->matrices) )
372
 
        CV_ERROR( CV_StsNullPtr, "Matrices are not allocated" );
373
 
 
374
 
    CV_CALL( cvReleaseGLCM( &destGLCM, CV_GLCM_DESC ));
375
 
 
376
 
    if( destGLCM->optimizationType != CV_GLCM_OPTIMIZATION_HISTOGRAM )
377
 
    {
378
 
        destGLCM->descriptorOptimizationType = destGLCM->numDescriptors = descriptorOptimizationType;
379
 
    }
380
 
    else
381
 
    {
382
 
        CV_ERROR( CV_StsBadFlag, "Histogram-based method is not implemented" );
383
 
//      destGLCM->descriptorOptimizationType = destGLCM->numDescriptors = CV_GLCMDESC_OPTIMIZATION_HISTOGRAM;
384
 
    }
385
 
 
386
 
    CV_CALL( destGLCM->descriptors = (double**)
387
 
            cvAlloc( destGLCM->numMatrices*sizeof(destGLCM->descriptors[0])));
388
 
 
389
 
    for( matrixLoop = 0; matrixLoop < destGLCM->numMatrices; matrixLoop ++ )
390
 
    {
391
 
        CV_CALL( destGLCM->descriptors[ matrixLoop ] =
392
 
                (double*)cvAlloc( destGLCM->numDescriptors*sizeof(destGLCM->descriptors[0][0])));
393
 
        memset( destGLCM->descriptors[matrixLoop], 0, destGLCM->numDescriptors*sizeof(double) );
394
 
 
395
 
        switch( destGLCM->descriptorOptimizationType )
396
 
        {
397
 
            case CV_GLCMDESC_OPTIMIZATION_ALLOWDOUBLENEST:
398
 
                icvCreateGLCMDescriptors_AllowDoubleNest( destGLCM, matrixLoop );
399
 
                break;
400
 
            default:
401
 
                CV_ERROR( CV_StsBadFlag,
402
 
                "descriptorOptimizationType different from CV_GLCMDESC_OPTIMIZATION_ALLOWDOUBLENEST\n"
403
 
                "is not supported" );
404
 
            /*
405
 
            case CV_GLCMDESC_OPTIMIZATION_ALLOWTRIPLENEST:
406
 
                icvCreateGLCMDescriptors_AllowTripleNest( destGLCM, matrixLoop );
407
 
                break;
408
 
            case CV_GLCMDESC_OPTIMIZATION_HISTOGRAM:
409
 
                if(matrixLoop < destGLCM->numMatrices>>1)
410
 
                    icvCreateGLCMDescriptors_Histogram( destGLCM, matrixLoop);
411
 
                    break;
412
 
            */
413
 
        }
414
 
    }
415
 
 
416
 
    __END__;
417
 
 
418
 
    if( cvGetErrStatus() < 0 )
419
 
        cvReleaseGLCM( &destGLCM, CV_GLCM_DESC );
420
 
}
421
 
 
422
 
 
423
 
static void
424
 
icvCreateGLCMDescriptors_AllowDoubleNest( CvGLCM* destGLCM, int matrixIndex )
425
 
{
426
 
    int sideLoop1, sideLoop2;
427
 
    int matrixSideLength = destGLCM->matrixSideLength;
428
 
 
429
 
    double** matrix = destGLCM->matrices[ matrixIndex ];
430
 
    double* descriptors = destGLCM->descriptors[ matrixIndex ];
431
 
 
432
 
    double* marginalProbability =
433
 
        (double*)cvAlloc( matrixSideLength * sizeof(marginalProbability[0]));
434
 
    memset( marginalProbability, 0, matrixSideLength * sizeof(double) );
435
 
 
436
 
    double maximumProbability = 0;
437
 
    double marginalProbabilityEntropy = 0;
438
 
    double correlationMean = 0, correlationStdDeviation = 0, correlationProductTerm = 0;
439
 
 
440
 
    for( sideLoop1=0; sideLoop1<matrixSideLength; sideLoop1++ )
441
 
    {
442
 
        int actualSideLoop1 = destGLCM->reverseLookupTable[ sideLoop1 ];
443
 
 
444
 
        for( sideLoop2=0; sideLoop2<matrixSideLength; sideLoop2++ )
445
 
        {
446
 
            double entryValue = matrix[ sideLoop1 ][ sideLoop2 ];
447
 
 
448
 
            int actualSideLoop2 = destGLCM->reverseLookupTable[ sideLoop2 ];
449
 
            int sideLoopDifference = actualSideLoop1 - actualSideLoop2;
450
 
            int sideLoopDifferenceSquared = sideLoopDifference*sideLoopDifference;
451
 
 
452
 
            marginalProbability[ sideLoop1 ] += entryValue;
453
 
            correlationMean += actualSideLoop1*entryValue;
454
 
 
455
 
            maximumProbability = MAX( maximumProbability, entryValue );
456
 
 
457
 
            if( actualSideLoop2 > actualSideLoop1 )
458
 
            {
459
 
                descriptors[ CV_GLCMDESC_CONTRAST ] += sideLoopDifferenceSquared * entryValue;
460
 
            }
461
 
 
462
 
            descriptors[ CV_GLCMDESC_HOMOGENITY ] += entryValue / ( 1.0 + sideLoopDifferenceSquared );
463
 
 
464
 
            if( entryValue > 0 )
465
 
            {
466
 
                descriptors[ CV_GLCMDESC_ENTROPY ] += entryValue * log( entryValue );
467
 
            }
468
 
 
469
 
            descriptors[ CV_GLCMDESC_ENERGY ] += entryValue*entryValue;
470
 
        }
471
 
 
472
 
        if( marginalProbability[ actualSideLoop1 ] > 0 )
473
 
            marginalProbabilityEntropy += marginalProbability[ actualSideLoop1 ]*log(marginalProbability[ actualSideLoop1 ]);
474
 
    }
475
 
 
476
 
    marginalProbabilityEntropy = -marginalProbabilityEntropy;
477
 
 
478
 
    descriptors[ CV_GLCMDESC_CONTRAST ] += descriptors[ CV_GLCMDESC_CONTRAST ];
479
 
    descriptors[ CV_GLCMDESC_ENTROPY ] = -descriptors[ CV_GLCMDESC_ENTROPY ];
480
 
    descriptors[ CV_GLCMDESC_MAXIMUMPROBABILITY ] = maximumProbability;
481
 
 
482
 
    double HXY = 0, HXY1 = 0, HXY2 = 0;
483
 
 
484
 
    HXY = descriptors[ CV_GLCMDESC_ENTROPY ];
485
 
 
486
 
    for( sideLoop1=0; sideLoop1<matrixSideLength; sideLoop1++ )
487
 
    {
488
 
        double sideEntryValueSum = 0;
489
 
        int actualSideLoop1 = destGLCM->reverseLookupTable[ sideLoop1 ];
490
 
 
491
 
        for( sideLoop2=0; sideLoop2<matrixSideLength; sideLoop2++ )
492
 
        {
493
 
            double entryValue = matrix[ sideLoop1 ][ sideLoop2 ];
494
 
 
495
 
            sideEntryValueSum += entryValue;
496
 
 
497
 
            int actualSideLoop2 = destGLCM->reverseLookupTable[ sideLoop2 ];
498
 
 
499
 
            correlationProductTerm += (actualSideLoop1 - correlationMean) * (actualSideLoop2 - correlationMean) * entryValue;
500
 
 
501
 
            double clusterTerm = actualSideLoop1 + actualSideLoop2 - correlationMean - correlationMean;
502
 
 
503
 
            descriptors[ CV_GLCMDESC_CLUSTERTENDENCY ] += clusterTerm * clusterTerm * entryValue;
504
 
            descriptors[ CV_GLCMDESC_CLUSTERSHADE ] += clusterTerm * clusterTerm * clusterTerm * entryValue;
505
 
 
506
 
            double HXYValue = marginalProbability[ actualSideLoop1 ] * marginalProbability[ actualSideLoop2 ];
507
 
            if( HXYValue>0 )
508
 
            {
509
 
                double HXYValueLog = log( HXYValue );
510
 
                HXY1 += entryValue * HXYValueLog;
511
 
                HXY2 += HXYValue * HXYValueLog;
512
 
            }
513
 
        }
514
 
 
515
 
        correlationStdDeviation += (actualSideLoop1-correlationMean) * (actualSideLoop1-correlationMean) * sideEntryValueSum;
516
 
    }
517
 
 
518
 
    HXY1 = -HXY1;
519
 
    HXY2 = -HXY2;
520
 
 
521
 
    descriptors[ CV_GLCMDESC_CORRELATIONINFO1 ] = ( HXY - HXY1 ) / ( correlationMean );
522
 
    descriptors[ CV_GLCMDESC_CORRELATIONINFO2 ] = sqrt( 1.0 - exp( -2.0 * (HXY2 - HXY ) ) );
523
 
 
524
 
    correlationStdDeviation = sqrt( correlationStdDeviation );
525
 
 
526
 
    descriptors[ CV_GLCMDESC_CORRELATION ] = correlationProductTerm / (correlationStdDeviation*correlationStdDeviation );
527
 
 
528
 
    delete [] marginalProbability;
529
 
}
530
 
 
531
 
 
532
 
CV_IMPL double cvGetGLCMDescriptor( CvGLCM* GLCM, int step, int descriptor )
533
 
{
534
 
    double value = DBL_MAX;
535
 
 
536
 
    CV_FUNCNAME( "cvGetGLCMDescriptor" );
537
 
 
538
 
    __BEGIN__;
539
 
 
540
 
    if( !GLCM )
541
 
        CV_ERROR( CV_StsNullPtr, "" );
542
 
 
543
 
    if( !(GLCM->descriptors) )
544
 
        CV_ERROR( CV_StsNullPtr, "" );
545
 
 
546
 
    if( (unsigned)step >= (unsigned)(GLCM->numMatrices))
547
 
        CV_ERROR( CV_StsOutOfRange, "step is not in 0 .. GLCM->numMatrices - 1" );
548
 
 
549
 
    if( (unsigned)descriptor >= (unsigned)(GLCM->numDescriptors))
550
 
        CV_ERROR( CV_StsOutOfRange, "descriptor is not in 0 .. GLCM->numDescriptors - 1" );
551
 
 
552
 
    value = GLCM->descriptors[step][descriptor];
553
 
 
554
 
    __END__;
555
 
 
556
 
    return value;
557
 
}
558
 
 
559
 
 
560
 
CV_IMPL void
561
 
cvGetGLCMDescriptorStatistics( CvGLCM* GLCM, int descriptor,
562
 
                               double* _average, double* _standardDeviation )
563
 
{
564
 
    CV_FUNCNAME( "cvGetGLCMDescriptorStatistics" );
565
 
 
566
 
    if( _average )
567
 
        *_average = DBL_MAX;
568
 
 
569
 
    if( _standardDeviation )
570
 
        *_standardDeviation = DBL_MAX;
571
 
 
572
 
    __BEGIN__;
573
 
 
574
 
    int matrixLoop, numMatrices;
575
 
    double average = 0, squareSum = 0;
576
 
 
577
 
    if( !GLCM )
578
 
        CV_ERROR( CV_StsNullPtr, "" );
579
 
 
580
 
    if( !(GLCM->descriptors))
581
 
        CV_ERROR( CV_StsNullPtr, "Descriptors are not calculated" );
582
 
 
583
 
    if( (unsigned)descriptor >= (unsigned)(GLCM->numDescriptors) )
584
 
        CV_ERROR( CV_StsOutOfRange, "Descriptor index is out of range" );
585
 
 
586
 
    numMatrices = GLCM->numMatrices;
587
 
 
588
 
    for( matrixLoop = 0; matrixLoop < numMatrices; matrixLoop++ )
589
 
    {
590
 
        double temp = GLCM->descriptors[ matrixLoop ][ descriptor ];
591
 
        average += temp;
592
 
        squareSum += temp*temp;
593
 
    }
594
 
 
595
 
    average /= numMatrices;
596
 
 
597
 
    if( _average )
598
 
        *_average = average;
599
 
 
600
 
    if( _standardDeviation )
601
 
        *_standardDeviation = sqrt( (squareSum - average*average*numMatrices)/(numMatrices-1));
602
 
 
603
 
    __END__;
604
 
}
605
 
 
606
 
 
607
 
CV_IMPL IplImage*
608
 
cvCreateGLCMImage( CvGLCM* GLCM, int step )
609
 
{
610
 
    IplImage* dest = 0;
611
 
 
612
 
    CV_FUNCNAME( "cvCreateGLCMImage" );
613
 
 
614
 
    __BEGIN__;
615
 
 
616
 
    float* destData;
617
 
    int sideLoop1, sideLoop2;
618
 
 
619
 
    if( !GLCM )
620
 
        CV_ERROR( CV_StsNullPtr, "" );
621
 
 
622
 
    if( !(GLCM->matrices) )
623
 
        CV_ERROR( CV_StsNullPtr, "Matrices are not allocated" );
624
 
 
625
 
    if( (unsigned)step >= (unsigned)(GLCM->numMatrices) )
626
 
        CV_ERROR( CV_StsOutOfRange, "The step index is out of range" );
627
 
 
628
 
    dest = cvCreateImage( cvSize( GLCM->matrixSideLength, GLCM->matrixSideLength ), IPL_DEPTH_32F, 1 );
629
 
    destData = (float*)(dest->imageData);
630
 
 
631
 
    for( sideLoop1 = 0; sideLoop1 < GLCM->matrixSideLength;
632
 
                        sideLoop1++, (float*&)destData += dest->widthStep )
633
 
    {
634
 
        for( sideLoop2=0; sideLoop2 < GLCM->matrixSideLength; sideLoop2++ )
635
 
        {
636
 
            double matrixValue = GLCM->matrices[step][sideLoop1][sideLoop2];
637
 
            destData[ sideLoop2 ] = (float)matrixValue;
638
 
        }
639
 
    }
640
 
 
641
 
    __END__;
642
 
 
643
 
    if( cvGetErrStatus() < 0 )
644
 
        cvReleaseImage( &dest );
645
 
 
646
 
    return dest;
647
 
}