Attention! This forum will be made read-only by Dec-20. Please migrate to https://forum.opencv.org. Most of existing active users should've received invitation by e-mail.

# Revision history [back]

### 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>();
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>();
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?

 3 retagged berak 32983 ●7 ●81 ●312

### 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>();
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?