Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

DFT and IDFT of contour, Fourier descriptors

Hello, I'd like to know if my code is good. I want to get Fourier descriptors from contour(shape). Correct me if I am wrong: Fourier descriptors = DFT output?

I'd also want transform, scale and rotation invariance. To get this I reject F[0], divide all F[i]/F[1] and use only magnitudes |F[i]|, correct?

Here is the code(java);

Imgproc.findContours(image, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_NONE); 
...
Point[] arr = contours.get(maxIdx).toArray();
Mat pointsX = new Mat(new Size(1,128), CvType.CV_32FC1);
Mat pointsY = new Mat(new Size(1,128), CvType.CV_32FC1);    
int delta = arr.length / 128;             // 128 points from contour
int j = 0;
for(int i = 0; i < arr.length && j < 128; i += delta, ++j) {
   pointsX.put(j, 0, arr[i].x); 
   pointsY.put(j, 0, arr[i].y); 
}   

List<Mat> planes = new ArrayList<Mat>();
planes.add(pointsX);
planes.add(pointsY);
Mat complexI = new Mat();
Core.merge(planes, complexI);                   
Core.dft(complexI, complexI);               

// scale invariant Fi = Fi / |F1|
double Re = complexI.get(1,0)[0];
double Im = complexI.get(1,0)[1];
double magF1 = Math.sqrt(Re*Re + Im*Im);
for(int i = 2; i < complexI.rows(); ++i) {
   double[] newVal = new double[2];
   newVal[0] = complexI.get(i, 0)[0] / magF1;
   newVal[1] = complexI.get(i, 0)[1] / magF1;
   complexI.put(i, 0, newVal);
}
// rotation invariant |Fi|
Core.split(complexI, planes);            // planes[0] = Re(DFT(I), planes[1] = Im(DFT(I))
Mat dftMag = new Mat();
Core.magnitude(planes.get(0), planes.get(1), dftMag);

I don't know why but after I did inverse dft(just after forward dft) I got big values such (30000,4000).

Mat idft = new Mat(new Size(1,128), CvType.CV_32FC2);
Core.dft(complexI, idft, Core.DFT_INVERSE, 0);

Is this good approach? Did I miss something here?

DFT and IDFT of contour, Fourier descriptors

Hello, I'd like to know if my code is good. I want to get Fourier descriptors from contour(shape). Correct me if I am wrong: Fourier descriptors = DFT output?

I'd also want transform, scale and rotation invariance. To get this I reject F[0], divide all F[i]/F[1] and use only magnitudes |F[i]|, correct?

Here is the code(java);

Imgproc.findContours(image, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_NONE); 
...
Point[] arr = contours.get(maxIdx).toArray();
Mat pointsX = new Mat(new Size(1,128), CvType.CV_32FC1);
Mat pointsY = new Mat(new Size(1,128), CvType.CV_32FC1);    
int delta = arr.length / 128;             // 128 points from contour
int for(int i = 0, j = 0;
for(int i = 0; i < arr.length && j < 128; i += delta, ++j) {
   pointsX.put(j, 0, arr[i].x); 
   pointsY.put(j, 0, arr[i].y); 
}   

List<Mat> planes = new ArrayList<Mat>();
planes.add(pointsX);
planes.add(pointsY);
Mat complexI = new Mat();
Core.merge(planes, complexI);                   
Core.dft(complexI, complexI);               

// scale invariant Fi = Fi / |F1|
double Re = complexI.get(1,0)[0];
double Im = complexI.get(1,0)[1];
double magF1 = Math.sqrt(Re*Re + Im*Im);
for(int i = 2; i < complexI.rows(); ++i) {
   double[] newVal = new double[2];
   newVal[0] = complexI.get(i, 0)[0] / magF1;
   newVal[1] = complexI.get(i, 0)[1] / magF1;
   complexI.put(i, 0, newVal);
}
// rotation invariant |Fi|
Core.split(complexI, planes);            // planes[0] = Re(DFT(I), planes[1] = Im(DFT(I))
Mat dftMag = new Mat();
Core.magnitude(planes.get(0), planes.get(1), dftMag);

I don't know why but after I did inverse dft(just after forward dft) I got big values such (30000,4000).

Mat idft = new Mat(new Size(1,128), CvType.CV_32FC2);
Core.dft(complexI, idft, Core.DFT_INVERSE, 0);

Is this good approach? Did I miss something here?

click to hide/show revision 3
retagged

updated 2013-12-18 12:21:32 -0600

berak gravatar image

DFT and IDFT of contour, Fourier descriptors

Hello, I'd like to know if my code is good. I want to get Fourier descriptors from contour(shape). Correct me if I am wrong: Fourier descriptors = DFT output?

I'd also want transform, scale and rotation invariance. To get this I reject F[0], divide all F[i]/F[1] and use only magnitudes |F[i]|, correct?

Here is the code(java);

Imgproc.findContours(image, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_NONE); 
...
Point[] arr = contours.get(maxIdx).toArray();
Mat pointsX = new Mat(new Size(1,128), CvType.CV_32FC1);
Mat pointsY = new Mat(new Size(1,128), CvType.CV_32FC1);    
int delta = arr.length / 128;             // 128 points from contour
for(int i = 0, j = 0; i < arr.length && j < 128; i += delta, ++j) {
   pointsX.put(j, 0, arr[i].x); 
   pointsY.put(j, 0, arr[i].y); 
}   

List<Mat> planes = new ArrayList<Mat>();
planes.add(pointsX);
planes.add(pointsY);
Mat complexI = new Mat();
Core.merge(planes, complexI);                   
Core.dft(complexI, complexI);               

// scale invariant Fi = Fi / |F1|
double Re = complexI.get(1,0)[0];
double Im = complexI.get(1,0)[1];
double magF1 = Math.sqrt(Re*Re + Im*Im);
for(int i = 2; i < complexI.rows(); ++i) {
   double[] newVal = new double[2];
   newVal[0] = complexI.get(i, 0)[0] / magF1;
   newVal[1] = complexI.get(i, 0)[1] / magF1;
   complexI.put(i, 0, newVal);
}
// rotation invariant |Fi|
Core.split(complexI, planes);            // planes[0] = Re(DFT(I), planes[1] = Im(DFT(I))
Mat dftMag = new Mat();
Core.magnitude(planes.get(0), planes.get(1), dftMag);

I don't know why but after I did inverse dft(just after forward dft) I got big values such (30000,4000).

Mat idft = new Mat(new Size(1,128), CvType.CV_32FC2);
Core.dft(complexI, idft, Core.DFT_INVERSE, 0);

Is this good approach? Did I miss something here?