【发布时间】:2018-04-15 23:52:57
【问题描述】:
您可以在上面找到原始图像。我拍摄了这张图片,构建了 6 层的拉普拉斯金字塔并再次重建它,这就是我得到的:
人们会注意到重建的图像比原始图像更“闪亮”。谁能解释一下为什么?
请在下面找到我使用的代码:
Mat ** LaplacianPyramid::buildLaplacianPyramid(const Mat& originalImage, int levels) {
Mat ** laplacianPyramid = new Mat*[levels];
Mat * currentImg = new Mat(originalImage);
for (int l = 0; l<levels - 1; l++) {
Mat * up = new Mat;
Mat * down = new Mat;
pyrDown(*currentImg, *down);
pyrUp(*down, *up, currentImg -> size());
Mat * lap = new Mat((*currentImg) - (*up));
laplacianPyramid[l] = lap;
currentImg->release();
up->release();
delete currentImg;
delete up;
currentImg = down;
}
laplacianPyramid[levels - 1] = currentImg;
return laplacianPyramid;
}
对于重建,我一直在使用以下 sn-p:
Mat * LaplacianPyramid::reconstructImage() {
Mat * currentImg = ( (_laplacianPyramid[_levels - 1]));
for (int l = _levels - 2; l >= 0; l--) {
Mat up;
pyrUp(*currentImg, up, _laplacianPyramid[l] ->size());
delete currentImg;
currentImg =new Mat( up + (*_laplacianPyramid[l]));
}
return currentImg;
}
是否有可能得到精度损失重建?谢谢!
【问题讨论】:
-
您最初是 Java 程序员吗?你在任何地方都使用
new非常可怕。 -
对于您的图像,我会说“光泽”来自重建模糊。原始图像的暗部变得更亮,而亮部变得更暗。为了测量这种对比度损失,一个经典的解决方案是计算两个图像之间的PSNR。请记住,PSNR 只是一个指标,它的价值近来备受争议。
-
如果您使用的是
CV_8UC3图像,pyrDown和pyrUp中可能存在数值不精确 -
可能是由于输入数据类型(即
uint8)引起的精度损失。如果您的图像的输入数据类型是float,您能否确认是否发生了同样的情况。 -
在转换为 8 位之前尝试缩放每个级别的灰度值。如果这确实是问题,那可能会减少精度损失。但是您确定金字塔级别不需要负值吗?我不知道 pyrDown 做了什么,但拉普拉斯需要一个签名的结果。存储为带符号的 int16 怎么样?
标签: c++ opencv image-processing