离散傅立叶变换OpenCV无法在Android上运行

时间:2018-12-03 02:24:12

标签: android opencv dft

我正在尝试在Android上转换并显示使用Core.dft()制作的图像,但它一直崩溃在我称为Core.dft()的行上。

这是我的代码:

private Mat getDFT(Mat singleChannel) {

    singleChannel.convertTo(singleChannel, CvType.CV_64FC1);

    int m = Core.getOptimalDFTSize(singleChannel.rows());
    int n = Core.getOptimalDFTSize(singleChannel.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(singleChannel, padded, 0, m - singleChannel.rows(), 0,
            n - singleChannel.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.dct(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, 255, Core.NORM_MINMAX);

    Mat realResult = new Mat(magI5.size(), CvType.CV_8UC1);

    magI5.convertTo(realResult, CvType.CV_8UC1);

    return realResult;
}

我采用here的形式。

引发Android Studio的错误是:

  

原因:CvException [org.opencv.core.CvException:cv :: Exception:OpenCV(3.4.1)/build/master_pack-android/opencv/modules/core/src/dxt.cpp:3335:错误: (-215)类型==((((5)&((1 << 3)-1))+((((1)-1)<< 3))||类型==((((5)&((1 << 3)-1))+((((2)-1)<< 3))||类型==((((6)&((1 << 3)-1))+((((1)-1)<< 3))||在函数void cv :: dft(cv :: InputArray,cv ::中,类型==((((6)&((1 << 3)-1))+((((2)-1)<< 3))) OutputArray,int,int)

我叫getDFT(mat);来自:

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode,resultCode,data);
    if (resultCode == RESULT_OK){
        path = data.getData();
        foto.setImageURI(path);
        try {
            Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), path);
            Mat mat = new Mat();
            Bitmap bitmap1 = bitmap.copy(Bitmap.Config.ARGB_8888, true);
            Utils.bitmapToMat(bitmap1, mat);
            getDFT(mat);
            Utils.matToBitmap(mat, bitmap);
            fourier.setImageBitmap(bitmap);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

这是从以下位置调用的:

boton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
            intent.setType("image/");
            startActivityForResult(intent.createChooser(intent,"Selecciona la aplicación"),10);
        }
    });

我还尝试了here中的一些代码

但是什么也没发生。

我正在使用OpenCv 3.4.1和Android Studio 3.2.1

有什么建议吗?

1 个答案:

答案 0 :(得分:0)

我使用您的代码通过更改行来实时实现dft的相机预览
Core.dct(complexI, complexI2);Core.dft(complexI, complexI2);