0
votes

I'm trying to implement a DCT code in Android. I'm testing out using the code but just changing to DCT instead of DFT : Convert OpenCv DFT example from C++ to Android. There have been changes to the code, thanks to timegalore. Now I'm having problems converting the image back to BGR.

public void transformImage(){
image = Highgui.imread(imageName, Highgui.CV_LOAD_IMAGE_GRAYSCALE);      
try {
    secondImage = new Mat(image.rows(), image.cols(), CvType.CV_64FC1);
    image.convertTo(secondImage, CvType.CV_64FC1);

    int m = Core.getOptimalDFTSize(image.rows());
    int n = Core.getOptimalDFTSize(image.cols()); // on the border add zero values

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

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

    Mat result = new Mat(padded.size(), padded.type());
    Core.dct(padded, result);

    Mat transformedImage = new Mat(padded.size(), padded.type());
    Core.idct(result, watermarkedImage);

    completedImage = new Mat(image.rows(), image.cols(), CvType.CV_64FC1);
    Imgproc.cvtColor(transformedImage, completedImage, Imgproc.COLOR_GRAY2BGR);

} catch (Exception e) {
    Log.e("Blargh", e.toString());
}

}

Now, I have obtained this error

04-09 21:35:52.362: E/cv::error()(23460): OpenCV Error: Assertion failed (depth == CV_8U || depth == CV_16U || depth == CV_32F) in void cv::cvtColor(cv::InputArray, cv::OutputArray, int, int), file /home/reports/ci/slave_desktop/50-SDK/opencv/modules/imgproc/src/color.cpp, line 3642

I am not sure what I should do, please advise. Your help is very much appreciated!

1

1 Answers

1
votes

You have this line:

image.convertTo(secondImage, CvType.CV_64FC1);

but then you don't use secondImage again, just image. Try:

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

and see how you get on.

Also DCT looks like it only works on reals not complex numbers like DFT and so you don't need to add a second channel to zero the imaginary part. You can work directly with the padded variable, so:

Mat result = new Mat(padded.size(), padded.type());

then

Core.dct(padded, result);

also, the original image needs to be single channel - so a greyscale. When you call Highgui.imread the image that will be loaded is multichannel - on my device it is 3 channel in BGR format. You can convert it to greyscale using Imgproc.cvtColor but it would be simpler just to load it as grey scale in the first place:

image = Highgui.imread(imageName, Highgui.CV_LOAD_IMAGE_GRAYSCALE);