[View]  [Edit]  [Lock]  [References]  [Attachments]  [History]  [Home]  [Changes]  [Search]  [Help] 

cvConvertImage

For those of you who want to mess with the power spectrum...

Hi, i've seen a lot of posts about how to perform convolutions on the
fourier domain, and exactly how to use the DFT functions. I've read
through this forum for quite a while and finally figured it out (took
me the better part of 3 days.. ) , although the answer had to be
brought together from quite a few spots. so, without further ado, here
it is;

I'm using openCV beta 4


// height and width of the image...
int width =200, height =200; // i'm assuming 200x200

// an array of the banks you want to multiply with..
vector< float* > banks;

void createBanks(){
  // example of lowpass
  float* lowPass = new float[width*height];
  memset(lowPass, 0, sizeof(float)*width*height);
  // square lowpass centered at origin, (100,100) = (0,0)..
  for(int i = height/2-40; i < height/2+40; i++){
    for(int j = width/2-40, j < width/2+40; j++){
      lowPass[i*width+j] = 1;
    }
  }

  // example of lowpass
  float* highPass = new float[width*height];
  memset(lowPass, 1, sizeof(float)*width*height);
  // square highpass centered at origin, (100,100) = (0,0)..
  for(int i = hieght/2-10; i < height/2+10; i++){
    for(int j = width/2-10, j < width/2+10; j++){
      highPass[i*width+j] = 0;
    }
  }

  // let's add it to our banks!
  banks.push_back(lowPass);
  banks.push_bank(highPass);
}


// creates the filter based on what your bank says..
// (your bank is human readable.. what is should be isn't!)
CvMat* createFilter(int bank, int rows, int cols, int type){
CvMat* filter = cvCreateMat(rows, cols, type);

// original data..
int ii,jj;
for(int i = 0; i < height; i++){
  for(int j = 0; j < width; j++){
    ii = i;
    jj = j;

    // the fun math is because IPL swaps the
    // 2nd and 4th quadrant, 1st and 3rd quadrant
    // quadrants:
    // II I
    // III IV

    if(i >= height/2 && j >= width){
      ii -= height;
      jj -= width;
    }
    else if(i <= height && j <= width){
      ii += height;
      jj += width;
    }else if(i >= height && j <= width){
      ii -= height;
      jj += width;
    }else if(i <= height && j >= width){
      ii += height;
      jj -= width;
    }

    data[ii*width + jj] = gaborBank[bank][i*width + j];
  }
}
return filter;
}

// convolve the filter at banks[index] with the
// REAL image at src, and store it in dst
// call like:
// createBanks(); // to create the banks!
// IplImage* im ; // <-- put your source image in here...
// IplImage* res;
// IplImage* res2;
// // whole operation is a bandpass filter...
// convolve(0, src, &dst); // for lowpass
// convolve(1, dst, &dst2); // for highpass...
void convolve(int index, IplImage* src, IplImage** dst){
  // this fun was from Vadim Pisarevsky's post in this group
  // (forget what number and last name)
  CvMat Ahdr, *Are = cvGetMat( gr32f, &Ahdr );
  CvMat* Ac = cvCreateMat(Are->rows, Are->cols,
  CV_MAKETYPE(CV_MAT_DEPTH(Are->type),2));
  CvMat* Aim = cvCreateMat(Are->rows, Are->cols, Are->type);
  cvZero( Aim );
  cvMerge( Are, Aim, 0, 0, Ac );
  cvDFT( Ac, Ac, CV_DXT_FORWARD ); // Ac is full DFT matrix
  cvSplit(Ac, Are, Aim, 0, 0);

  // here's the rest of it..
  CvMat* filter = createFilter(index, Are->rows, Are->cols, Are->type);


  // this is valid, right?
  // (a + bi) * (c + di), where b = 0
  // is ac + adi , right?
  cvMul(Are, filter, Are);
  cvMul(Aim, filter, Aim);



  cvMerge( Are, Aim, 0, 0, Ac );
  cvDFT( Ac, Ac, CV_DXT_INV_SCALE );
  cvSplit(Ac, Are, Aim, 0, 0);
  *dst = cvGetImage(Are, src);

  // do some cleanup..
  cvReleaseMat( &filter );
  cvReleaseMat( &Aim );
  cvReleaseMat( &Ac );

// it complains (run time error) if you try to release *dst or Are
}



that's about it. if you have any questions or comments, feel free to
email.

Tayeb Al Karim
tak1806@r...
gcart.rit.edu