原文:图像金字塔----高斯和拉普拉斯
图像金字塔是图像中多尺度表达的一种,最初用于机器视觉和图像压缩,最主要用于图像的分割、融合。
高斯金字塔 ( Gaussian pyramid):
高斯金字塔是由底部的最大分辨率图像逐次向下采样得到的一系列图像。最下面的图像分辨率最高,越往上图像分辨率越低。
高斯金字塔的向下采样过程是:
1) 对于给定的图像先做一次高斯平滑处理,也就是使用一个大小为的卷积核对图像进行卷积操作.
OpenCv 中使用的高斯核
2) 然后再对图像采样,去除图像中的偶数行和偶数列,然后就得到一张图片。
向下取样会逐渐丢失图像的信息。以上就是对图像的向下取样操作,即缩小图像。
拉普拉斯金字塔(Laplacian pyramid):
用来从金字塔低层图像重建上层未采样图像,在数字图像处理中也即是预测残差,可以对图像进行最大程度的还原,配合高斯金字塔一起使用。
也就是说,拉普拉斯金字塔是通过源图像减去先缩小后再放大的图像的一系列图像构成的。保留的是残差!为图像还原做准备!
OpenCv中都给我们提供好了API:
CV_EXPORTS_W void pyrDown( InputArray src, OutputArray dst,
const Size& dstsize = Size(), int borderType = BORDER_DEFAULT );
CV_EXPORTS_W void pyrUp( InputArray src, OutputArray dst,
const Size& dstsize = Size(), int borderType = BORDER_DEFAULT );
高斯金字塔与拉普拉斯金字塔的实测效果如下:
如上图所示:通过 高斯向上采样,与拉普拉斯金字塔结果,恢复效果有一定差距。
参考代码:
#include <string>
#include <iostream>
#include <opencv2/opencv.hpp>
#include <vector>
using namespace std;
using namespace cv;
vector<Mat> vecPyUp;//放大
vector<Mat> vecPyDown;//缩小
vector<Mat> vecLapImg; //差值 拉普拉斯金字塔(Laplacian pyramid)
string pyramidDown = "GaussianPyramidDown";
string pyramidDownRestore = "pyramidDownRestore";
string pyramidUp = "Gaussian pyramidUp";
string LaplacianPyramid = "LaplacianPyramid";
int MaxLevel=6;
void pyramidCreate(Mat imgOri)
{
vecPyUp.clear();
vecPyDown.clear();
vecLapImg.clear();
// Down
for (int i = 0; i < MaxLevel; i++)
{
vecPyDown.push_back(imgOri);
pyrDown(imgOri, imgOri);
}
// Up
Mat imgMin = vecPyDown[MaxLevel - 1].clone();
vecPyUp.push_back(imgMin);
for (int i = 0; i < MaxLevel-1; i++)
{
pyrUp(imgMin, imgMin, vecPyDown[MaxLevel - i - 2 ].size());
vecPyUp.push_back(imgMin);
}
Mat temp;
// Laplace
for (int i = 0; i < MaxLevel; i++)
{
subtract(vecPyDown[MaxLevel-i-1], vecPyUp[i], temp);
// temp = temp + Scalar(127, 127, 127);
vecLapImg.push_back(temp);
}
}
//回调函数
void callBack(int level, void* )
{
if(level<0)level=0;
imshow(pyramidUp, vecPyUp[level]);
imshow(pyramidDown, vecPyDown[MaxLevel-level-1]);
imshow(LaplacianPyramid, vecLapImg[level]);
Mat restore;
add(vecLapImg[level],vecPyUp[level],restore);
imshow(pyramidDownRestore, restore);
}
int main()
{
//输入图片
srcImage = imread("lady.jpg"); // 读取图像;
if (srcImage.empty()) {
printf("读取失败");
return 0;
}
pyramidCreate(srcImage);
namedWindow(pyramidDown, 0);
namedWindow(pyramidUp, 0);
namedWindow(LaplacianPyramid, 0);
namedWindow(pyramidDownRestore, 0);
createTrackbar("Level", pyramidDown, 0, pyramid::MaxLevel-1, callBack);
createTrackbar("Level", pyramidUp, 0, pyramid::MaxLevel-1, callBack);
createTrackbar("Level", LaplacianPyramid, 0, pyramid::MaxLevel-1, callBack);
createTrackbar("Level", ppyramidDownRestore, 0, pyramid::MaxLevel-1, callBack);
callBack(0,0);
waitKey(0);
destroyAllWindows();
return 0;
}