我正在尝试在Android中实现DCT代码。我正在使用拆分和合并方法来获取图像的原始颜色。
以下是代码的片段
image = Highgui.imread(imageName);
secondImage = new Mat(image.rows(), image.cols(), CvType.CV_32FC3);
image.convertTo(secondImage, CvType.CV_32FC3);
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_32FC3); // expand input image to optimal size
Imgproc.copyMakeBorder(secondImage, padded, 0, m - secondImage.rows(), 0, n - secondImage.cols(), Imgproc.BORDER_CONSTANT);
List<Mat> planes = new ArrayList<Mat>();
Core.split(padded, planes);
List<Mat> outplanes = new ArrayList<Mat>(planes.size());
for (int k = 0; k < planes.size(); k++) {
outplanes.add(new Mat(padded.size(), CvType.CV_32FC1));
}
Mat trans = new Mat(padded.size(), padded.type());
for (int k = 0; k < planes.size(); k++) {
Core.dct(planes.get(k), outplanes.get(k));
}
List<Mat> ioutplanes = new ArrayList<Mat>(outplanes.size());
for (int k = 0; k < planes.size(); k++) {
ioutplanes.add(new Mat(padded.size(), CvType.CV_32FC1));
}
for (int k = 0; k < planes.size(); k++) {
Core.idct(outplanes.get(k), ioutplanes.get(k));
}
Core.merge(ioutplanes, trans);
这次有例外:
在void cv :: dct(cv :: InputArray,cv :: OutputArray,int),file / home / reports / ci / slave_desktop / 50中未实现函数/功能(未实现奇数DCT) -SDK / opencv / modules / core / src / dxt.cpp,第2330行
这段代码是否正确?非常感谢您的帮助。
更新:我注意到copyMakeBorder()是导致我的图片大小为奇数的那个,这就是我遇到此异常的原因。
答案 0 :(得分:0)
SIGSEGV是一个分段错误,通常在程序试图访问它没有权限或无法访问的内存部分时抛出。我的想法是,这是由于硬件,可能是操作的内存太少。
您是否尝试使用较小的样本或其他计算机运行程序?
答案 1 :(得分:0)
secondImage和padded将是类型:CvType.CV_32FC3。还有就地转换,如:
planes.get(k).convertTo(planes.get(k), CvType.CV_32FC1);
我不确定是否有效,所以如果你需要进行这种转换,请使用中间Mat。另请注意,填充已经是CV_32F,因此不确定是否需要执行此转换。同样来自dct的输出 - 如果这是CV_32F则不需要转换。
如果要显示合并的图片,您当然需要将每个通道值标准化为0到255之间。
看起来你正在应用dct变换然后反向直接,所以你将回到你的开始。我认为我们还需要注意像outplanes.addAll(飞机)之类的调用,因为我认为这只是添加对象的引用而不是分配空间,这正是你想要的。
试试这个:
Imgproc.copyMakeBorder(secondImage, padded, 0,
m - secondImage.rows(), 0, n - secondImage.cols(),
Imgproc.BORDER_CONSTANT);
List<Mat> planes = new ArrayList<Mat>();
Core.split(padded, planes);
Mat trans = new Mat(padded.size(), padded.type());
List<Mat> ioutplanes = new ArrayList<Mat>(planes.size());
for (int k = 0; k < planes.size(); k++) {
ioutplanes.add(new Mat(padded.size(), CvType.CV_32FC1));
}
for (int k = 0; k < planes.size(); k++) {
Core.idct(planes.get(k), ioutplanes.get(k));
}
Core.merge(ioutplanes, trans);
答案 2 :(得分:0)
也许你可以改变这段代码
int m = Core.getOptimalDFTSize(image.rows());
int n = Core.getOptimalDFTSize(image.cols());
到
int m =Core.getOptimalDFTSize((image.rows()+1)/2)*2;
int n = Core.getOptimalDFTSize((image.cols()+1)/2)*2;
以获得DCT的奇数大小,因为此函数用于DFT。
它写在网站的功能文档中:
虽然该函数不能直接用于估计DCT变换的最佳矢量大小(因为当前的DCT实现仅支持偶数大小的矢量),但它可以很容易地处理为getOptimalDFTSize((vecsize + 1)/ 2)* 2。