source: trunk/saliency_detection/src/cvgabor.cpp @ 25

Last change on this file since 25 was 10, checked in by wcaarls, 12 years ago

Imported saliency_detection at revision 1000

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    CvScalar S;
314    switch(Type)
315    {
316        case 1:  //Real
317
318           cvCopy( (CvMat*)Real, (CvMat*)kernel, NULL );
319            //pImage = cvGetImage( (CvMat*)kernel, pImageGL );
320           for (int i = 0; i < kernel->rows; i++)
321           {
322              for (int j = 0; j < kernel->cols; j++)
323              {
324                   ve = cvGetReal2D((CvMat*)kernel, i, j);
325                   cvSetReal2D( (IplImage*)pImage, j, i, ve );
326              }
327           }
328           break;
329        case 2:  //Imag
330           cvCopy( (CvMat*)Imag, (CvMat*)kernel, NULL );
331           //pImage = cvGetImage( (CvMat*)kernel, pImageGL );
332           for (int i = 0; i < kernel->rows; i++)
333           {
334              for (int j = 0; j < kernel->cols; j++)
335              {
336                   ve = cvGetReal2D((CvMat*)kernel, i, j);
337                   cvSetReal2D( (IplImage*)pImage, j, i, ve );
338              }
339           }
340           break;
341        case 3:  //Magnitude
342           ///@todo 
343           break;
344        case 4:  //Phase
345          ///@todo
346           break;
347    }
348   
349    cvNormalize((IplImage*)pImage, (IplImage*)pImage, 0, 255, CV_MINMAX, NULL );
350
351
352    cvConvertScaleAbs( (IplImage*)pImage, (IplImage*)newimage, 1, 0 );
353
354    cvReleaseMat(&kernel);
355
356    cvReleaseImage(&pImage);
357
358    return newimage;
359    }
360}
361
362
363/*!
364    \fn CvGabor::IsKernelCreate()
365Determine the gabor kernel is created or not
366
367Parameters:
368        None
369
370Returns:
371        a boolean value, TRUE is created or FALSE is non-created.
372
373Determine whether a gabor kernel is created.
374 */
375bool CvGabor::IsKernelCreate()
376{
377
378    return bKernel;
379}
380
381
382/*!
383    \fn CvGabor::get_mask_width()
384Reads the width of Mask
385
386Parameters:
387    None
388
389Returns:
390    Pointer to long type width of mask.
391 */
392long CvGabor::get_mask_width()
393{
394  return Width;
395}
396
397
398/*!
399    \fn CvGabor::Init(int iMu, int iNu, double dSigma, double dF)
400Initilize the.gabor
401
402Parameters:
403        iMu     The orientations which is iMu*PI.8
404        iNu     The scale can be from -5 to infinit
405        dSigma  The Sigma value of gabor, Normally set to 2*PI
406        dF      The spatial frequence , normally is sqrt(2)
407
408Returns:
409
410Initilize 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.
411 */
412void CvGabor::Init(int iMu, int iNu, double dSigma, double dF)
413{
414  //Initilise the parameters
415    bInitialised = FALSE;
416    bKernel = FALSE;
417
418    Sigma = dSigma;
419    F = dF;
420   
421    Kmax = PI/2;
422   
423    // Absolute value of K
424    K = Kmax / pow(F, (float)iNu);
425    Phi = PI*iMu/8;
426    bInitialised = TRUE;
427    Width = mask_width();
428    Real = cvCreateMat( Width, Width, CV_32FC1);
429    Imag = cvCreateMat( Width, Width, CV_32FC1);
430    creat_kernel();
431}
432
433
434/*!
435    \fn CvGabor::Init(double dPhi, int iNu, double dSigma, double dF)
436Initilize the.gabor
437
438Parameters:
439        dPhi    The orientations
440        iNu     The scale can be from -5 to infinit
441        dSigma  The Sigma value of gabor, Normally set to 2*PI
442        dF      The spatial frequence , normally is sqrt(2)
443
444Returns:
445        None
446
447Initilize 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
448        file_format     The format of the file, e.g. GAN_PNG_FORMAT
449        image   The image structure to be written to the file
450        octrlstr        Format-dependent control structure
451
452 */
453void CvGabor::Init(double dPhi, int iNu, double dSigma, double dF)
454{
455
456    bInitialised = FALSE;
457    bKernel = FALSE;
458    Sigma = dSigma;
459    F = dF;
460   
461    Kmax = PI/2;
462   
463    // Absolute value of K
464    K = Kmax / pow(F, (float)iNu);
465    Phi = dPhi;
466    bInitialised = TRUE;
467    Width = mask_width();
468    Real = cvCreateMat( Width, Width, CV_32FC1);
469    Imag = cvCreateMat( Width, Width, CV_32FC1);
470    creat_kernel();
471}
472
473
474
475/*!
476    \fn CvGabor::get_matrix(int Type)
477Get a matrix by the type of kernel
478
479Parameters:
480        Type            The type of kernel, e.g. REAL, IMAG, MAG, PHASE
481
482Returns:
483        Pointer to matrix structure, or NULL on failure.
484
485Return the gabor kernel.
486 */
487CvMat* CvGabor::get_matrix(int Type)
488{
489    if (!IsKernelCreate()) {perror("Error: the gabor kernel has not been created!\n"); return NULL;}
490    switch (Type)
491    {
492      case CV_GABOR_REAL:
493        return Real;
494        break;
495      case CV_GABOR_IMAG:
496        return Imag;
497        break;
498      case CV_GABOR_MAG:
499        return NULL;
500        break;
501      case CV_GABOR_PHASE:
502        return NULL;
503        break;
504    }
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.