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 后),图像出现了问题。 望有过爬坑经验的朋友帮忙解答下。
你应该用python写
参数错了。
求解,跟你一样的情况,log之后就是全黑图像
解决了,最后一步的参数错了
我用javacv是这样