source: trunk/saliency_detection/src/cvgabor.cpp

Last change on this file was 36, checked in by wcaarls, 12 years ago

Updated saliency_detection to revision 1213

File size: 17.0 KB
Line 
1/***************************************************************************
2 *   Copyright (C) 2006 by Mian Zhou   *
3 *   M.Zhou@reading.ac.uk   *
4 *                                                                         *
5 *   This program is free software; you can redistribute it and/or modify  *
6 *   it under the terms of the GNU General Public License as published by  *
7 *   the Free Software Foundation; either version 2 of the License, or     *
8 *   (at your option) any later version.                                   *
9 *                                                                         *
10 *   This program is distributed in the hope that it will be useful,       *
11 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13 *   GNU General Public License for more details.                          *
14 *                                                                         *
15 *   You should have received a copy of the GNU General Public License     *
16 *   along with this program; if not, write to the                         *
17 *   Free Software Foundation, Inc.,                                       *
18 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
19 ***************************************************************************/
20#include <saliency_detection/cvgabor.h>
21
22#undef DEBUG
23//#define DEBUG
24CvGabor::CvGabor()
25{
26}
27
28
29CvGabor::~CvGabor()
30{
31cvReleaseMat( &Real );
32cvReleaseMat( &Imag );
33}
34
35
36/*!
37    \fn CvGabor::CvGabor(int iMu, int iNu)
38Construct a gabor
39
40Parameters:
41        iMu             The orientation iMu*PI/8,
42        iNu             The scale,
43
44Returns:
45        None,
46
47Create a gabor with a orientation iMu*PI/8, and with a scale iNu. The sigma (Sigma) and the spatial frequence (F) are set to 2*PI and sqrt(2) defaultly. It calls Init() to generate parameters and kernels.
48 */
49 CvGabor::CvGabor(int iMu, int iNu)
50{
51    //Initilise the parameters
52   
53    Sigma = 2*PI;
54    F = sqrt(2.0);
55    Init(iMu, iNu, Sigma, F);
56   
57}
58
59/*!
60    \fn CvGabor::CvGabor(int iMu, int iNu, double dSigma)
61Construct a gabor
62
63Parameters:
64        iMu             The orientation iMu*PI/8,
65        iNu             The scale,
66        dSigma          The sigma value of Gabor,
67
68Returns:
69        None
70
71Create a gabor with a orientation iMu*PI/8, a scale iNu, and a sigma value dSigma. The spatial frequence (F) is set to sqrt(2) defaultly. It calls Init() to generate parameters and kernels.
72 */
73CvGabor::CvGabor(int iMu, int iNu, float dSigma)
74{
75    F = sqrt(2.0);
76    Init(iMu, iNu, dSigma, F);
77}
78
79
80/*!
81    \fn CvGabor::CvGabor(int iMu, int iNu, double dSigma, double dF)
82Construct a gabor
83
84Parameters:
85        iMu             The orientation iMu*PI/8
86        iNu             The scale
87        dSigma          The sigma value of Gabor
88        dF              The spatial frequency
89
90Returns:
91        None
92
93Create a gabor with a orientation iMu*PI/8, a scale iNu, a sigma value dSigma, and a spatial frequence dF. It calls Init() to generate parameters and kernels.
94 */
95 CvGabor::CvGabor(int iMu, int iNu, float dSigma, float dF)
96{
97
98    Init(iMu, iNu, dSigma, dF);
99   
100}
101
102
103/*!
104    \fn CvGabor::CvGabor(double dPhi, int iNu)
105Construct a gabor
106
107Parameters:
108        dPhi            The orientation in arc
109        iNu             The scale
110
111Returns:
112        None
113
114Create a gabor with a orientation dPhi, and with a scale iNu. The sigma (Sigma) and the spatial frequence (F) are set to 2*PI and sqrt(2) defaultly. It calls Init() to generate parameters and kernels.
115 */
116 CvGabor::CvGabor(float dPhi, int iNu)
117{
118
119    Sigma = 2*PI;
120    F = sqrt(2.0);
121    Init(dPhi, iNu, Sigma, F);
122}
123
124
125/*!
126    \fn CvGabor::CvGabor(double dPhi, int iNu, double dSigma)
127Construct a gabor
128
129Parameters:
130        dPhi            The orientation in arc
131        iNu             The scale
132        dSigma          The sigma value of Gabor
133
134Returns:
135        None
136   
137Create a gabor with a orientation dPhi, a scale iNu, and a sigma value dSigma. The spatial frequence (F) is set to sqrt(2) defaultly. It calls Init() to generate parameters and kernels.
138 */
139 CvGabor::CvGabor(float dPhi, int iNu, float dSigma)
140{
141
142    F = sqrt(2.0);
143    Init(dPhi, iNu, dSigma, F);
144}
145
146
147/*!
148    \fn CvGabor::CvGabor(double dPhi, int iNu, double dSigma, double dF)
149Construct a gabor
150
151Parameters:
152        dPhi            The orientation in arc
153        iNu             The scale
154        dSigma          The sigma value of Gabor
155        dF              The spatial frequency
156
157Returns:
158        None
159
160Create a gabor with a orientation dPhi, a scale iNu, a sigma value dSigma, and a spatial frequence dF. It calls Init() to generate parameters and kernels.
161 */
162 CvGabor::CvGabor(float dPhi, int iNu, float dSigma, float dF)
163{
164
165   Init(dPhi, iNu, dSigma,dF);
166}
167
168/*!
169    \fn CvGabor::IsInit()
170Determine the gabor is initilised or not
171
172Parameters:
173        None
174
175Returns:
176        a boolean value, TRUE is initilised or FALSE is non-initilised.
177
178Determine whether the gabor has been initlized - variables F, K, Kmax, Phi, Sigma are filled.
179 */
180bool CvGabor::IsInit()
181{
182
183    return bInitialised;
184}
185
186/*!
187    \fn CvGabor::mask_width()
188Give out the width of the mask
189
190Parameters:
191        None
192
193Returns:
194        The long type show the width.
195
196Return the width of mask (should be NxN) by the value of Sigma and iNu.
197 */
198long CvGabor::mask_width()
199{
200
201    long lWidth;
202    if (IsInit() == FALSE)  {
203       perror ("Error: The Object has not been initilised in mask_width()!\n");
204       return 0;
205    }
206    else {
207       //determine the width of Mask
208      float dModSigma = Sigma/K;
209      float dWidth = cvRound(dModSigma*6 + 1);
210      //test whether dWidth is an odd.
211      if (fmod(dWidth, (float)2.0)==0.0) dWidth++;
212      lWidth = (long)dWidth;
213
214      return lWidth;
215    }
216}
217
218
219/*!
220    \fn CvGabor::creat_kernel()
221Create gabor kernel
222
223Parameters:
224        None
225
226Returns:
227        None
228
229Create 2 gabor kernels - REAL and IMAG, with an orientation and a scale
230 */
231void CvGabor::creat_kernel()
232{
233   
234    if (IsInit() == FALSE) {perror("Error: The Object has not been initilised in creat_kernel()!\n");}
235    else {
236      CvMat *mReal, *mImag;
237      mReal = cvCreateMat( Width, Width, CV_32FC1);
238      mImag = cvCreateMat( Width, Width, CV_32FC1);
239     
240      /**************************** Gabor Function ****************************/
241      int x, y;
242      float dReal;
243      float dImag;
244      float dTemp1, dTemp2, dTemp3;
245
246      for (int i = 0; i < Width; i++)
247      {
248          for (int j = 0; j < Width; j++)
249          {
250              x = i-(Width-1)/2;
251              y = j-(Width-1)/2;
252              dTemp1 = (pow(K,2)/pow(Sigma,2))*exp(-(pow((float)x,2)+pow((float)y,2))*pow(K,2)/(2*pow(Sigma,2)));
253              dTemp2 = cos(K*cos(Phi)*x + K*sin(Phi)*y) - exp(-(pow(Sigma,2)/2));
254              dTemp3 = sin(K*cos(Phi)*x + K*sin(Phi)*y);
255              dReal = dTemp1*dTemp2;
256              dImag = dTemp1*dTemp3;
257              //gan_mat_set_el(pmReal, i, j, dReal);
258              cvmSet( (CvMat*)mReal, i, j, dReal );
259              //gan_mat_set_el(pmImag, i, j, dImag);
260              cvmSet( (CvMat*)mImag, i, j, dImag );
261
262          }
263       }
264       /**************************** Gabor Function ****************************/
265       bKernel = TRUE;
266       cvCopy(mReal, Real, NULL);
267       cvCopy(mImag, Imag, NULL);
268       #ifdef DEBUG
269       printf("A %d x %d Gabor kernel with %f PI in arc is created.\n", Width, Width, Phi/PI);
270       #endif
271       cvReleaseMat( &mReal );
272       cvReleaseMat( &mImag );
273     }
274}
275
276
277/*!
278    \fn CvGabor::get_image(int Type)
279Get the speific type of image of Gabor
280
281Parameters:
282        Type            The Type of gabor kernel, e.g. REAL, IMAG, MAG, PHASE   
283
284Returns:
285        Pointer to image structure, or NULL on failure 
286
287Return an Image (gandalf image class) with a specific Type   "REAL"     "IMAG" "MAG" "PHASE" 
288 */
289IplImage* CvGabor::get_image(int Type)
290{
291
292    if(IsKernelCreate() == FALSE)
293    {
294      perror("Error: the Gabor kernel has not been created in get_image()!\n");
295      return NULL;
296    }
297    else
298    { 
299    IplImage* pImage;
300    IplImage *newimage;
301    newimage = cvCreateImage(cvSize(Width,Width), IPL_DEPTH_8U, 1 );
302    //printf("Width is %d.\n",(int)Width);
303    //printf("Sigma is %f.\n", Sigma);
304    //printf("F is %f.\n", F);
305    //printf("Phi is %f.\n", Phi);
306   
307    //pImage = gan_image_alloc_gl_d(Width, Width);
308    pImage = cvCreateImage( cvSize(Width,Width), IPL_DEPTH_32F, 1 );
309   
310   
311    CvMat* kernel = cvCreateMat(Width, Width, CV_32FC1);
312    double ve;
313    switch(Type)
314    {
315        case 1:  //Real
316
317           cvCopy( (CvMat*)Real, (CvMat*)kernel, NULL );
318            //pImage = cvGetImage( (CvMat*)kernel, pImageGL );
319           for (int i = 0; i < kernel->rows; i++)
320           {
321              for (int j = 0; j < kernel->cols; j++)
322              {
323                   ve = cvGetReal2D((CvMat*)kernel, i, j);
324                   cvSetReal2D( (IplImage*)pImage, j, i, ve );
325              }
326           }
327           break;
328        case 2:  //Imag
329           cvCopy( (CvMat*)Imag, (CvMat*)kernel, NULL );
330           //pImage = cvGetImage( (CvMat*)kernel, pImageGL );
331           for (int i = 0; i < kernel->rows; i++)
332           {
333              for (int j = 0; j < kernel->cols; j++)
334              {
335                   ve = cvGetReal2D((CvMat*)kernel, i, j);
336                   cvSetReal2D( (IplImage*)pImage, j, i, ve );
337              }
338           }
339           break;
340        case 3:  //Magnitude
341           ///@todo 
342           break;
343        case 4:  //Phase
344          ///@todo
345           break;
346    }
347   
348    cvNormalize((IplImage*)pImage, (IplImage*)pImage, 0, 255, CV_MINMAX, NULL );
349
350
351    cvConvertScaleAbs( (IplImage*)pImage, (IplImage*)newimage, 1, 0 );
352
353    cvReleaseMat(&kernel);
354
355    cvReleaseImage(&pImage);
356
357    return newimage;
358    }
359}
360
361
362/*!
363    \fn CvGabor::IsKernelCreate()
364Determine the gabor kernel is created or not
365
366Parameters:
367        None
368
369Returns:
370        a boolean value, TRUE is created or FALSE is non-created.
371
372Determine whether a gabor kernel is created.
373 */
374bool CvGabor::IsKernelCreate()
375{
376
377    return bKernel;
378}
379
380
381/*!
382    \fn CvGabor::get_mask_width()
383Reads the width of Mask
384
385Parameters:
386    None
387
388Returns:
389    Pointer to long type width of mask.
390 */
391long CvGabor::get_mask_width()
392{
393  return Width;
394}
395
396
397/*!
398    \fn CvGabor::Init(int iMu, int iNu, double dSigma, double dF)
399Initilize the.gabor
400
401Parameters:
402        iMu     The orientations which is iMu*PI.8
403        iNu     The scale can be from -5 to infinit
404        dSigma  The Sigma value of gabor, Normally set to 2*PI
405        dF      The spatial frequence , normally is sqrt(2)
406
407Returns:
408
409Initilize the.gabor with the orientation iMu, the scale iNu, the sigma dSigma, the frequency dF, it will call the function creat_kernel(); So a gabor is created.
410 */
411void CvGabor::Init(int iMu, int iNu, double dSigma, double dF)
412{
413  //Initilise the parameters
414    bInitialised = FALSE;
415    bKernel = FALSE;
416
417    Sigma = dSigma;
418    F = dF;
419   
420    Kmax = PI/2;
421   
422    // Absolute value of K
423    K = Kmax / pow(F, (float)iNu);
424    Phi = PI*iMu/8;
425    bInitialised = TRUE;
426    Width = mask_width();
427    Real = cvCreateMat( Width, Width, CV_32FC1);
428    Imag = cvCreateMat( Width, Width, CV_32FC1);
429    creat_kernel();
430}
431
432
433/*!
434    \fn CvGabor::Init(double dPhi, int iNu, double dSigma, double dF)
435Initilize the.gabor
436
437Parameters:
438        dPhi    The orientations
439        iNu     The scale can be from -5 to infinit
440        dSigma  The Sigma value of gabor, Normally set to 2*PI
441        dF      The spatial frequence , normally is sqrt(2)
442
443Returns:
444        None
445
446Initilize the.gabor with the orientation dPhi, the scale iNu, the sigma dSigma, the frequency dF, it will call the function creat_kernel(); So a gabor is created.filename      The name of the image file
447        file_format     The format of the file, e.g. GAN_PNG_FORMAT
448        image   The image structure to be written to the file
449        octrlstr        Format-dependent control structure
450
451 */
452void CvGabor::Init(double dPhi, int iNu, double dSigma, double dF)
453{
454
455    bInitialised = FALSE;
456    bKernel = FALSE;
457    Sigma = dSigma;
458    F = dF;
459   
460    Kmax = PI/2;
461   
462    // Absolute value of K
463    K = Kmax / pow(F, (float)iNu);
464    Phi = dPhi;
465    bInitialised = TRUE;
466    Width = mask_width();
467    Real = cvCreateMat( Width, Width, CV_32FC1);
468    Imag = cvCreateMat( Width, Width, CV_32FC1);
469    creat_kernel();
470}
471
472
473
474/*!
475    \fn CvGabor::get_matrix(int Type)
476Get a matrix by the type of kernel
477
478Parameters:
479        Type            The type of kernel, e.g. REAL, IMAG, MAG, PHASE
480
481Returns:
482        Pointer to matrix structure, or NULL on failure.
483
484Return the gabor kernel.
485 */
486CvMat* CvGabor::get_matrix(int Type)
487{
488    if (!IsKernelCreate()) {perror("Error: the gabor kernel has not been created!\n"); return NULL;}
489    switch (Type)
490    {
491      case CV_GABOR_REAL:
492        return Real;
493        break;
494      case CV_GABOR_IMAG:
495        return Imag;
496        break;
497      case CV_GABOR_MAG:
498        return NULL;
499        break;
500      case CV_GABOR_PHASE:
501        return NULL;
502        break;
503    }
504    return NULL;
505}
506
507
508
509
510/*!
511    \fn CvGabor::output_file(const char *filename, Gan_ImageFileFormat file_format, int Type)
512Writes a gabor kernel as an image file.
513
514Parameters:
515        filename        The name of the image file
516        file_format     The format of the file, e.g. GAN_PNG_FORMAT
517        Type            The Type of gabor kernel, e.g. REAL, IMAG, MAG, PHASE   
518Returns:
519        None
520
521Writes an image from the provided image structure into the given file and the type of gabor kernel.
522 */
523void CvGabor::output_file(const char *filename, int Type)
524{
525  IplImage *pImage;
526  pImage = get_image(Type);
527  if(pImage != NULL)
528  {
529    if( cvSaveImage(filename, pImage )) printf("%s has been written successfully!\n", filename);
530    else printf("Error: writting %s has failed!\n", filename);
531  }
532  else
533    perror("Error: the image is empty in output_file()!\n");
534
535  cvReleaseImage(&pImage);
536}
537
538
539
540
541
542
543/*!
544    \fn CvGabor::show(int Type)
545 */
546void CvGabor::show(int Type)
547{
548    if(!IsInit()) {
549        perror("Error: the gabor kernel has not been created!\n");
550    }
551    else {
552    IplImage *pImage;
553    pImage = get_image(Type);
554    cvNamedWindow("Testing",1);
555    cvShowImage("Testing",pImage);
556    cvWaitKey(0);
557    cvDestroyWindow("Testing");
558    cvReleaseImage(&pImage);
559    }
560
561}
562
563
564
565
566/*!
567    \fn CvGabor::conv_img(IplImage *src, IplImage *dst, int Type)
568 */
569void CvGabor::conv_img(IplImage *src, IplImage *dst, int Type)
570{
571    double ve, re,im;
572
573    CvMat *mat = cvCreateMat(src->width, src->height, CV_32FC1);
574    for (int i = 0; i < src->width; i++)
575    {
576       for (int j = 0; j < src->height; j++)
577       {
578              ve = cvGetReal2D((IplImage*)src, j, i);
579              cvSetReal2D( (CvMat*)mat, i, j, ve );
580       }
581    }
582
583    CvMat *rmat = cvCreateMat(src->width, src->height, CV_32FC1);
584    CvMat *imat = cvCreateMat(src->width, src->height, CV_32FC1);
585
586    CvMat *kernel = cvCreateMat( Width, Width, CV_32FC1 );
587
588    switch (Type)
589    {
590      case CV_GABOR_REAL:
591        cvCopy( (CvMat*)Real, (CvMat*)kernel, NULL );
592        cvFilter2D( (CvMat*)mat, (CvMat*)mat, (CvMat*)kernel, cvPoint( (Width-1)/2, (Width-1)/2));
593        break;
594      case CV_GABOR_IMAG:
595        cvCopy( (CvMat*)Imag, (CvMat*)kernel, NULL );
596        cvFilter2D( (CvMat*)mat, (CvMat*)mat, (CvMat*)kernel, cvPoint( (Width-1)/2, (Width-1)/2));
597        break;
598      case CV_GABOR_MAG:
599        /* Real Response */
600        cvCopy( (CvMat*)Real, (CvMat*)kernel, NULL );
601        cvFilter2D( (CvMat*)mat, (CvMat*)rmat, (CvMat*)kernel, cvPoint( (Width-1)/2, (Width-1)/2));
602        /* Imag Response */
603        cvCopy( (CvMat*)Imag, (CvMat*)kernel, NULL );
604        cvFilter2D( (CvMat*)mat, (CvMat*)imat, (CvMat*)kernel, cvPoint( (Width-1)/2, (Width-1)/2));
605        /* Magnitude response is the square root of the sum of the square of real response and imaginary response */
606        for (int i = 0; i < mat->rows; i++)
607        {
608           for (int j = 0; j < mat->cols; j++)
609           {
610               re = cvGetReal2D((CvMat*)rmat, i, j);
611               im = cvGetReal2D((CvMat*)imat, i, j);
612               ve = sqrt(re*re + im*im);
613               cvSetReal2D( (CvMat*)mat, i, j, ve );
614           }
615        }       
616        break;
617      case CV_GABOR_PHASE:
618        break;
619    }
620   
621    if (dst->depth == IPL_DEPTH_8U)
622    {
623        cvNormalize((CvMat*)mat, (CvMat*)mat, 0, 255, CV_MINMAX);
624        for (int i = 0; i < mat->rows; i++)
625        {
626            for (int j = 0; j < mat->cols; j++)
627            {
628                ve = cvGetReal2D((CvMat*)mat, i, j);
629                ve = cvRound(ve);
630                cvSetReal2D( (IplImage*)dst, j, i, ve );
631            }
632        }
633     }
634
635     if (dst->depth == IPL_DEPTH_32F)
636     {
637         for (int i = 0; i < mat->rows; i++)
638         {
639            for (int j = 0; j < mat->cols; j++)
640            {
641                ve = cvGetReal2D((CvMat*)mat, i, j);
642                cvSetReal2D( (IplImage*)dst, j, i, ve );
643            }
644         }
645     }       
646
647    cvReleaseMat(&kernel);
648    cvReleaseMat(&imat);   
649    cvReleaseMat(&rmat);
650    cvReleaseMat(&mat);
651}
Note: See TracBrowser for help on using the repository browser.