fourier descriptor in opencv

asked 2016-12-01 15:48:52 -0600

siline gravatar image

I tried to implement fourier descriptor to use it in machine learning algorithm but i got this error OpenCV Error: Assertion failed (type == CV_32FC1 || type == CV_32FC2 || type == CV_64FC1 || type == CV_64FC2) in void cv::dft(cv::InputArray, cv::OutputArray, int, int), file /home/maksim/workspace/android-pack/opencv/modules/core/src/dxt.cpp, line 2506

This is my code:

            Mat trainData = new Mat();
    Mat train_labels = new Mat();


    String Newligne=System.getProperty("line.separator");


    for (int i = 0; i <48; i++) {
        String path1 = Environment.getExternalStorageDirectory().toString()
                + "/Pictures/images/" + "a"+i + ".jpg";


        Mat img = Imgcodecs.imread(path1);
        Log.i(TAG, "error" + i + img.empty());
        img.convertTo(img, CvType.CV_32FC1);
        Mat secondImage = new Mat(img.rows(), img.cols(), CvType.CV_64FC1);
        img.convertTo(secondImage, CvType.CV_64FC1);

        int m = Core.getOptimalDFTSize(img.rows());
        int n = Core.getOptimalDFTSize(img.cols()); // on the border
        // add zero values Imgproc.copyMakeBorder(image1, padded, 0, m - image1.rows(), 0, n

        Mat padded = new Mat(new Size(n, m), CvType.CV_64FC1); // expand input
        // image to
        // optimal size

        Core.copyMakeBorder(secondImage, padded, 0, m - secondImage.rows(), 0,
                n - secondImage.cols(), Core.BORDER_CONSTANT);

        List<Mat> planes = new ArrayList<Mat>();
        planes.add(padded);
        planes.add(Mat.zeros(padded.rows(), padded.cols(), CvType.CV_64FC1));

        Mat complexI = Mat.zeros(padded.rows(), padded.cols(), CvType.CV_64FC2);

        Mat complexI2 = Mat
                .zeros(padded.rows(), padded.cols(), CvType.CV_64FC2);

        Core.merge(planes, complexI); // Add to the expanded another plane with
        // zeros

        Core.dft(complexI, complexI2); // this way the result may fit in the
        // source matrix

        // compute the magnitude and switch to logarithmic scale
        // => log(1 + sqrt(Re(DFT(I))^2 + Im(DFT(I))^2))
        Core.split(complexI2, planes); // planes[0] = Re(DFT(I), planes[1] =
        // Im(DFT(I))

        Mat mag = new Mat(planes.get(0).size(), planes.get(0).type());

        Core.magnitude(planes.get(0), planes.get(1), mag);// planes[0]
        // =
        // magnitude

        Mat magI = mag;
        Mat magI2 = new Mat(magI.size(), magI.type());
        Mat magI3 = new Mat(magI.size(), magI.type());
        Mat magI4 = new Mat(magI.size(), magI.type());
        Mat magI5 = new Mat(magI.size(), magI.type());

        Core.add(magI, Mat.ones(padded.rows(), padded.cols(), CvType.CV_64FC1),
                magI2); // switch to logarithmic scale
        Core.log(magI2, magI3);

        Mat crop = new Mat(magI3, new Rect(0, 0, magI3.cols() & -2,
                magI3.rows() & -2));

        magI4 = crop.clone();

        // rearrange the quadrants of Fourier image so that the origin is at the
        // image center
        int cx = magI4.cols() / 2;
        int cy = magI4.rows() / 2;

        Rect q0Rect = new Rect(0, 0, cx, cy);
        Rect q1Rect = new Rect(cx, 0, cx, cy);
        Rect q2Rect = new Rect(0, cy, cx, cy);
        Rect q3Rect = new Rect(cx, cy, cx, cy);

        Mat q0 = new Mat(magI4, q0Rect); // Top-Left - Create a ROI per quadrant
        Mat q1 = new Mat(magI4, q1Rect); // Top-Right
        Mat q2 = new Mat(magI4, q2Rect); // Bottom-Left
        Mat q3 = new Mat(magI4, q3Rect); // Bottom-Right

        Mat tmp = new Mat(); // swap quadrants (Top-Left with Bottom-Right)
        q0.copyTo(tmp);
        q3.copyTo(q0);
        tmp.copyTo(q3);

        q1.copyTo(tmp); // swap quadrant (Top-Right with Bottom-Left)
        q2.copyTo(q1);
        tmp.copyTo(q2);

        Core.normalize(magI4, magI5, 0 ...
(more)
edit retag flag offensive close merge delete

Comments

The Assertion is telling you, that in the specific method cv::dft you can not insert any Mat which format is: type == CV_32FC1 || type == CV_32FC2 || type == CV_64FC1 || type == CV_64FC2 I guess, that this method is causing it Core.dft(complexI, complexI2); is it possible for you to change the Format?

Vintez gravatar imageVintez ( 2016-12-02 01:39:06 -0600 )edit

I tried to change the format but the error persist

siline gravatar imagesiline ( 2016-12-02 06:25:02 -0600 )edit

Which formats did you try?

Vintez gravatar imageVintez ( 2016-12-02 06:36:07 -0600 )edit

I tried CV_8UC1 , CV_16S

siline gravatar imagesiline ( 2016-12-02 08:05:05 -0600 )edit

So complexI, complexI2 have both been that Types? And still the Error was the Assertion you mentioned above?

Vintez gravatar imageVintez ( 2016-12-02 08:10:22 -0600 )edit

yes, it still the same error . i think that the logical type is CV_64FC2 because we need complexe number but i don't guess the error

siline gravatar imagesiline ( 2016-12-02 08:28:52 -0600 )edit

so as in the opencv c++ example they use CV_32F and it worked, so probably it had to be a 3 or 4 channel CV_32F in the example. Could you try to do sth. similar? (Sorry, that nothing worked so far =/)

Mat planes[] = {Mat_<float>(padded), Mat::zeros(padded.size(), CV_32F)};
Mat complexI;
merge(planes, 2, complexI);
Vintez gravatar imageVintez ( 2016-12-02 08:37:41 -0600 )edit

I should change all the type CV_64FC1 and CV_64FC1 to CV_32F or only for complexI and complexI2 ?

siline gravatar imagesiline ( 2016-12-02 09:11:05 -0600 )edit

Try it like it is shown in the example. The base Image is a grayscale. The others seem to be CV_32F.

Vintez gravatar imageVintez ( 2016-12-02 09:36:23 -0600 )edit

Fourier descriptors or Fourier coefficients ?

LBerger gravatar imageLBerger ( 2016-12-03 04:31:54 -0600 )edit

I would use fourier to construct a descripter used as a feature for machine learning (KNN)

siline gravatar imagesiline ( 2016-12-03 04:55:49 -0600 )edit