OpenCV 离散傅里叶变换 JAVA 实现的问题

35Niu 发布于 2018/04/17 18:37
阅读 1K+
收藏 0

NGINX社区官方微服务训练营,深入了解K8s网络,线上课程+专家答疑,立即加入>>>

小弟最近在学习 OpenCV3 ,使用 Java 实现,看的书是《OpenCV3 编程入门》。说实话这本书针对 JAVA 语言参考价值一般,基本是顺着他的思路把JAVA 官方说明文档(http://opencv-java-tutorials.readthedocs.io/en/latest/)看一遍。

因为网上 JAVA 资料太少。 在看到‘离散傅里叶变换’官网的例子也不行了。 希望有过经验的朋友帮忙给出解决方案。

代码如下:

在 Core.add,这个地方,OpenCV3.4 没有官网的方法。

官网关于离散傅里叶变换的 JAVA文档地址:http://opencv-java-tutorials.readthedocs.io/en/latest/05-fourier-transform.html?highlight=dft

public class StudyTest6 extends OpenCVStudyBase{
    
    @Test
    public void testaaa(){

        Mat src = Imgcodecs.imread(this.p_test_file_path + "/imageTextN.png",Imgcodecs.CV_LOAD_IMAGE_GRAYSCALE);

        //为了进行离散傅里叶变换,需要扩充图像,具体扩充多少,根据 getOptimalDFTSize 来获取

        int new_height = Core.getOptimalDFTSize(src.rows()); // 获取纵向扩充后的距离(高度)
        int new_width = Core.getOptimalDFTSize(src.cols()); // 获取横向扩充后的距离(宽度)

//        System.out.println(new_height + "," + src.rows());
//        System.out.println(new_width + "," + src.cols());

        Mat padded = new Mat();

        // 扩充图像边界
        Core.copyMakeBorder(src,padded, 0,new_height - src.rows(), 0, new_width - src.cols() , Core.BORDER_CONSTANT , Scalar.all(0));

        // 保存图片
        this.saveImage(this.save_dest_dir + "/image_dft_1.jpg",padded);

        List<Mat> paddedMat_channels = new ArrayList<Mat>();
        List<Mat> new_paddedMat_channels = new ArrayList<Mat>();

        //转float
        padded.convertTo(padded,CvType.CV_32F);
        paddedMat_channels.add(padded);
        paddedMat_channels.add(Mat.zeros(padded.size(),CvType.CV_32F));

        //合并通道
        Mat complexImage = new Mat();
        Core.merge(paddedMat_channels,complexImage);

        //离散傅里叶变换
        Core.dft(complexImage,complexImage);

        //分割通道
        Core.split(complexImage,new_paddedMat_channels);

//将复数值转化为副值        
Core.magnitude(new_paddedMat_channels.get(0),new_paddedMat_channels.get(1),new_paddedMat_channels.get(0));
        Mat mag = new_paddedMat_channels.get(0);
        this.saveImage(this.save_dest_dir + "/image_dft_2.jpg",mag);

        /*
         * 这里出现了分歧, 官网例子这里是
         * Core.add(Mat.ones(mag.size(), CVType.CV_32F), mag);
         * 但是OpenCV add的所有多态实现方法中,并没有 add(Mat a ,Mat b) 这种。
         * 最接近的一种就是 add(Mat src1,Mat,src2 , Mat dst)
         */
        Core.add(Mat.ones(mag.size(), CvType.CV_32F), mag , mag);
        this.saveImage(this.save_dest_dir + "/image_dft_3.jpg",mag);

        Core.log(mag, mag);
        this.saveImage(this.save_dest_dir + "/image_dft_4.jpg",mag);

        mag = mag.submat(new Rect(0, 0, mag.cols() & -2, mag.rows() & -2));
        this.saveImage(this.save_dest_dir + "/image_dft_5.jpg",mag);

        int cx = mag.cols() / 2;
        int cy = mag.rows() / 2;

        Mat q0 = new Mat(mag, new Rect(0, 0, cx, cy));
        Mat q1 = new Mat(mag, new Rect(cx, 0, cx, cy));
        Mat q2 = new Mat(mag, new Rect(0, cy, cx, cy));
        Mat q3 = new Mat(mag, new Rect(cx, cy, cx, cy));

        Mat tmp = new Mat();
        q0.copyTo(tmp);
        q3.copyTo(q0);
        tmp.copyTo(q3);

        q1.copyTo(tmp);
        q2.copyTo(q1);
        tmp.copyTo(q2);

        Core.normalize(mag, mag, 0, 1, Core.NORM_MINMAX);

        this.saveImage(this.save_dest_dir + "/image_dft_6.jpg",mag);


    }
}

在 Core.add 这一步无法走下去,结果导致不是想要的:

期望的结果如下:

我代码执行的结果如下:

  • image_dft_1.jpg  (Core.copyMakeBorder 扩充边界后)

  • image_dft_2.jpg (离散傅里叶变换后)高值较多,显示为白色,低值显示为黑色,图中的噪点可以看出来

  • image_dft_3.jpg(Core.add 后),图像基本没变化

  • image_dft_4.jpg(Core.log 对数尺寸缩放),直接变黑色了。

  • image_dft_5.jpg(重现分布图像象限)
mag = mag.submat(new Rect(0, 0, mag.cols() & -2, mag.rows() & -2));

  • image_dft_6.jpg(最终图像)

 

image_dft_3.jpg(Core.add 后),图像出现了问题。 望有过爬坑经验的朋友帮忙解答下。

 

 

加载中
0
龙影
龙影

你应该用python写

0
z
zhang_wq
Core.normalize(mag, mag, 0, 1, Core.NORM_MINMAX);

参数错了。 

0
MaxTsang30
MaxTsang30

求解,跟你一样的情况,log之后就是全黑图像

0
MaxTsang30
MaxTsang30

解决了,最后一步的参数错了 

normalize(sizeMat, sizeMat, 0, 255, NORM_MINMAX,CvType.CV_8UC1,new Mat());

我用javacv是这样

OSCHINA
登录后可查看更多优质内容
返回顶部
顶部
返回顶部
顶部