网站服务器的工作原理,网络企业网站建设方案,跳转中,帮别人做网站怎么备案图像金字塔是图像多尺度表达的一种#xff0c;是一种以多分辨率来解释图像的有效但概念简单的结构。一幅图像的金字塔是一系列以金字塔形状排列的分辨率逐步降低#xff0c;且来源于同一张原始图的图像集合。其通过梯次向下采样获得#xff0c;直到达到某个终止条件才停止采…图像金字塔是图像多尺度表达的一种是一种以多分辨率来解释图像的有效但概念简单的结构。一幅图像的金字塔是一系列以金字塔形状排列的分辨率逐步降低且来源于同一张原始图的图像集合。其通过梯次向下采样获得直到达到某个终止条件才停止采样。我们将一层一层的图像比喻成金字塔层级越高则图像越小分辨率越低。如下图所示。 常用的图像金字塔有高斯金字塔(Gaussian pyramid)和拉普拉斯金字塔(Laplacian pyramid)。高斯金字塔用来向下采样而拉普拉斯金字塔用来从金字塔低层图像重建上层未采样图像。
高斯金字塔
下采样pyrDown
下采样也叫做降采样这个过程中是隔行隔列删去图像中的对应行和列这样原图中那些精细的细节边缘等地方会变得锯齿状产生失真因此为了缩小之后的图像看起来自然必须进行平滑。因此pyrDown函数在降采样之前要先对图像进行高斯模糊。此时采用的高斯核如下 代码
#include stdafx.h
#include opencv2/opencv.hppint main()
{// 声明两个图像矩阵cv::Mat img1, img2;// 创建两个窗口cv::namedWindow(image1, cv::WINDOW_AUTOSIZE);cv::namedWindow(image2, cv::WINDOW_AUTOSIZE);// 读取文件并将原始图像显示在image1窗口img1 cv::imread(test.jpg);cv::imshow(image1, img1);// 对原始图像进行下采样和高斯滤波处理长宽各缩小一半并显示在imge2窗口cv::pyrDown(img1, img2);cv::imshow(image2, img2);// 等待键盘事件cv::waitKey(0);// 关闭所有窗口并释放关联内存cv::destroyAllWindows();return 0;
}
运行结果 上采样pyrUp
上采样过程首先是将图像在每个方向上扩大为原来的两倍新增的行和列都以0填充然后使用下采样时用的高斯核乘以四与放大后的图像进行卷积获得“新增像素”的近似值。因此处理后的图像尺寸变大但是分辨率不变。
代码
#include stdafx.h
#include opencv2/opencv.hppint main()
{// 声明两个图像矩阵cv::Mat img1, img2;// 创建两个窗口cv::namedWindow(image1, cv::WINDOW_AUTOSIZE);cv::namedWindow(image2, cv::WINDOW_AUTOSIZE);// 读取文件并将原始图像显示在image1窗口img1 cv::imread(test.jpg);cv::imshow(image1, img1);// 对原始图像进行下采样和高斯滤波处理长宽各放大一半并显示在imge2窗口cv::pyrUp(img1, img2);cv::imshow(image2, img2);// 等待键盘事件cv::waitKey(0);// 关闭所有窗口并释放关联内存cv::destroyAllWindows();return 0;
}
运行结果 拉普拉斯金字塔
拉普拉斯金字塔可以有高斯金字塔计算得来公式如下 式中 代表第i层高斯图像 代表第i1层高斯图像 代表上采样 代表卷积运算符 代表5 × 5的卷积内核。
拉普拉金字塔的图像看起来就像边界图其中很多像素都是 0经常被用在图像压缩中。
代码
#include stdafx.h
#include opencv2/opencv.hppint main()
{// 声明两个图像矩阵cv::Mat img1, img2, img3;// 创建两个窗口cv::namedWindow(image1, cv::WINDOW_AUTOSIZE);cv::namedWindow(image2, cv::WINDOW_AUTOSIZE);// 读取文件并将原始图像显示在image1窗口img1 cv::imread(test.jpg);cv::imshow(image1, img1);// 对原始图像进行下采样和高斯滤波处理长宽各放大一半并显示在imge2窗口cv::pyrDown(img1, img2);cv::pyrDown(img2, img3);cv::pyrUp(img3, img3);img3 img2 - img3;cv::imshow(image2, img3);// 等待键盘事件cv::waitKey(0);// 关闭所有窗口并释放关联内存cv::destroyAllWindows();return 0;
}
运行结果 金字塔图像融合 分析
① 首先通过图1建立高斯金字塔
② 然后通过得到的高斯金字塔生成拉普拉斯金字塔。以图1、图2和图4为例图4是公式中的图1是公式中的图2是公式中的则图4是由图1减去图2向上采样并高斯模糊的结果得到的。
③ 因为拉普拉斯图像是用来从金字塔低层图像重建上层未采样图像的所以可以通过将其与上一层的上采样的结果相加来重建原图。以图4、图5和图6为例图6图4pyrUp图5。
注重建原图金字塔的塔顶和高斯金字塔的塔顶是一样的。
代码
注这里选取的图片最好是大小相同且行数和列数是能除尽2的6次方的值否则上采样后的行数和列数可能和原来的相差1需再进行处理。
#include stdafx.h
#include opencv2/opencv.hpp
#include iostreamint main()
{// 声明两个图像矩阵cv::Mat img1, img2;// 读取图片img1 cv::imread(apple.jpg);img2 cv::imread(orange.jpg);// 创建三个窗口cv::namedWindow(img1, cv::WINDOW_NORMAL);cv::namedWindow(img2, cv::WINDOW_NORMAL);cv::namedWindow(img, cv::WINDOW_NORMAL);// 用apple图像生成高斯金字塔共7层cv::Mat gp1[7];cv::Mat gtmp1 img1;gp1[0] gtmp1;for (int i 1; i 7; i) {cv::pyrDown(gtmp1, gtmp1);gp1[i] gtmp1;}// 用orange图像生成高斯金字塔共7层cv::Mat gp2[7];cv::Mat gtmp2 img2;gp2[0] gtmp2;for (int i 1; i 7; i) {cv::pyrDown(gtmp2, gtmp2);gp2[i] gtmp2;}// 用apple图像生成拉普拉斯金字塔共6层cv::Mat lp1[7];cv::Mat ltmp1;lp1[6] gp1[6];for (int i 5; i 0; i--) {cv::pyrUp(gp1[i1], ltmp1);cv::subtract(gp1[i], ltmp1, lp1[i]);}// 用orange图像生成拉普拉斯金字塔共6层cv::Mat lp2[7];cv::Mat ltmp2;lp2[6] gp2[6];for (int i 5; i 0; i--) {cv::pyrUp(gp2[i1], ltmp2);cv::subtract(gp2[i], ltmp2, lp2[i]);}// 将apple拉普拉斯金字塔的左半边和orang拉普拉斯金字塔的右半边拼接生成融合后的拉普拉斯金字塔cv::Mat LS[7];for (int i 0; i 7; i) {cv::Size shape lp1[i].size();int width shape.width;// 将apple拉普拉斯图像赋给融合图像LS[i] lp1[i];// 获取orange拉普拉斯图像的右半边取出cv::Mat roi2 lp2[i].colRange(width / 2, width);// 将取出的半边图像复制到融合图像的右半边实现图像融合roi2.copyTo(LS[i].colRange(width/2, width));}// 重建原图cv::Mat ls_ LS[6];for (int i 5; i 0; i--){cv::pyrUp(ls_, ls_);std::cout ls_.size() std::endl;std::cout LS[i].size() std::endl;cv::add(ls_, LS[i], ls_);}// 显示原图和重建图像cv::imshow(img1, img1);cv::imshow(img2, img2);cv::imshow(img, ls_);// 等待键盘事件cv::waitKey(0);// 关闭窗口并释放相关联的内存cv::destroyAllWindows();return 0;
}
运行结果