1. 尺度空間和影像金字塔
尺度空間 是影像在不同尺度下的連續表示。其中最常見的是使用高斯核對影像進行摺積。高斯濾波可以平滑影像,從而消除影像中的細微細節。隨著高斯濾波核尺度的增加,影像變得越來越平滑,直到只剩下最基本的特征。
影像金字塔 是尺度空間的一種具體實作方式。它是由一系列不同分辨率的影像組成,這些影像以金字塔的形狀排列如下圖所示。
常見的影像金字塔有以下幾種:
高斯金字塔 (Gaussian Pyramid):高斯金字塔是透過對影像進行高斯濾波和下采樣來構建的。高斯濾波可以平滑影像,下采樣可以降低影像的分辨率。高斯金字塔具有尺度不變性,可以用於尺度不變的影像處理任務。
DoG 金字塔 (Difference of Gaussians Pyramid):DoG 金字塔是透過對高斯金字塔 相鄰層 進行 差分 來構建的。DoG 金字塔可以捕捉影像的局部特征,可以用於目標檢測和邊緣檢測等任務。
拉普拉斯金字塔 (Laplacian Pyramid):拉普拉斯金字塔是透過對高斯金字塔進行 差分 來構建的。拉普拉斯金字塔可以捕捉影像的邊緣和細節資訊,可以用於影像融合和特征提取等任務。
SIFT 金字塔 (Scale-Invariant Feature Transform Pyramid):SIFT 金字塔是透過對影像進行高斯濾波和 DoG 濾波來構建的。SIFT 金字塔具有尺度不變性和旋轉不變性,可以用於影像匹配和目標辨識等任務。
影像金字塔通常透過對影像進行 下采樣 或 上采樣 來構建。下采樣可以降低影像的分辨率,上采樣可以提高影像的分辨率。
尺度空間和影像金字塔在電腦視覺和影像處理領域有著廣泛的套用。尺度空間可以用於尺度不變的影像處理任務,例如影像匹配和目標檢測。影像金字塔可以用於影像融合、影像配準和特征提取等任務。
2. 高斯金字塔
高斯金字塔 透過對影像進行高斯濾波和下采樣獲得一系列下采樣影像。高斯金字塔的 下采樣 是對高斯濾波後的影像進行,以降低影像的分辨率。下采樣可以透過以下幾種方式實作:
平均池化 :對影像的每個局部區域進行平均操作,從而得到一個像素值。
最大池化 :對影像的每個局部區域進行最大值操作,從而得到一個像素值。
雙線性插值 :透過對相鄰像素進行插值來得到新的像素值。
高斯金字塔的構建過程如下:
將原圖作為高斯金字塔的第 0 層影像
對高斯金字塔的第 i 層(i = 0,1,2...)影像進行高斯濾波
對高斯濾波後的影像進行亞采樣,生成高斯金字塔的第 i+1 層影像
高斯金字塔的第 i 層影像的尺寸為:
其中, 和 是原始影像的寬度和高度。
重復前面兩步,直到達到預定的金字塔層數。
下面的程式碼展示了上述步驟,透過
GaussianBlur()
實作高斯濾波,透過雙線性插值實作下采樣,最終完成構建高斯金字塔。
#include<opencv2/core.hpp>
#include<opencv2/imgproc.hpp>
#include<opencv2/opencv.hpp>
usingnamespacestd;
usingnamespace cv;
// 構建高斯金字塔
voidbuildGaussianPyramid(Mat& image, vector<Mat>& pyramid, int levels){
Mat temp = image.clone();
pyramid.push_back(temp);
for (int i = 1; i < levels; i++) {
// 高斯濾波
Mat blurred;
GaussianBlur(temp, blurred, Size(5, 5), 0);
Mat downSampled(blurred.rows / 2, blurred.cols / 2, blurred.type());
resize(blurred, downSampled, downSampled.size(), 0, 0, INTER_LINEAR);
pyramid.push_back(downSampled);
temp = downSampled;
}
}
intmain(){
Mat src = imread(".../lotus.jpg");
int numLevels = 4;
vector<Mat> pyramid;
buildGaussianPyramid2(src,pyramid,numLevels);
for (int i = 0; i < numLevels; i++) {
imshow("Gaussian Pyramid Level " + to_string(i), pyramid[i]);
}
waitKey(0);
return0;
}
OpenCV 提供了
pyrDown()
函式來構建高斯金字塔,該函式先對影像進行高斯濾波然後對影像進行下采樣。
#include<opencv2/core.hpp>
#include<opencv2/imgproc.hpp>
#include<opencv2/opencv.hpp>
usingnamespacestd;
usingnamespace cv;
// 構建高斯金字塔
voidbuildGaussianPyramid2(Mat& image, vector<Mat>& pyramid, int levels){
Mat temp = image.clone();
pyramid.push_back(temp);
for (int i = 1; i < levels; i++) {
Mat downSampled;
pyrDown(temp, downSampled);
pyramid.push_back(downSampled);
temp = downSampled;
}
}
intmain(){
Mat src = imread(".../lotus.jpg");
int numLevels = 4;
vector<Mat> pyramid;
buildGaussianPyramid2(src,pyramid,numLevels);
for (int i = 0; i < numLevels; i++) {
imshow("Gaussian Pyramid Level " + to_string(i), pyramid[i]);
}
waitKey(0);
return0;
}
3. DoG 金字塔
在該系列的第十一篇文章中,曾經介紹過 DoG 算子。
DoG 金字塔 (Difference of Gaussians Pyramid)是指透過對相鄰尺度的高斯金字塔進行差分來構建的影像金字塔。DoG 金字塔可以捕捉影像的局部特征,例如邊緣和角點,可以用於目標檢測和邊緣檢測等任務。
DoG 金字塔的構建過程如下:
對原始影像進行高斯濾波,得到不同尺度的高斯金字塔。
對相鄰尺度的高斯金字塔進行差分,得到 DoG 金字塔。
DoG 金字塔的第 i 層可以表示為:
DoG(i) = G(i) - G(i-1)
確定極值點,對 DoG 金字塔進行極值點檢測,找到影像的局部特征點。
DoG 金字塔的套用:
目標檢測:它可以捕捉影像的局部特征,例如邊緣和角點。
邊緣檢測:它可以捕捉影像的邊緣資訊。
4. 拉普拉斯金字塔
拉普拉斯金字塔 它可以捕捉影像的邊緣和細節資訊,它也是基於高斯金字塔構建的,常用於影像融合和特征提取等任務。
拉普拉斯金字塔的構建步驟如下:
構建高斯金字塔。
對高斯金字塔進行差分,得到拉普拉斯金字塔。拉普拉斯金字塔的第 i 層可以表示為:
Laplacian(i) = G(i) - Expand(G(i+1))
其中,G(i) 是高斯金字塔的第 i 層,Expand() 是影像的 上采樣 操作。拉普拉斯金字塔捕捉了高斯金字塔連續層之間的細節差異,強調了原始影像中存在的邊緣和高分頻量。
不同型別的影像金字塔比較:
金字塔型別 | 特性 | 構建方式 | 套用 |
---|---|---|---|
高斯金字塔 | 提供影像的多尺度表示 | 高斯模糊和下采樣 | 尺度不變性、影像壓縮 |
DoG 金字塔 | 比較高斯金字塔的相鄰級別,強調模糊差異並捕獲角點和斑點等局部特征。 | 高斯金字塔中相鄰層的差異 | 目標檢測、邊緣檢測 |
拉普拉斯金字塔 | 關註不同尺度下影像中存在的所有邊緣和細節。 | 透過獲取高斯金字塔中相鄰級別之間的差異來計算拉普拉斯金字塔,涉及對上一層的金字塔影像進行上采樣。 | 影像融合、增強、紋理分析 |
下面的程式碼展示了如何基於高斯金字塔構建拉普拉斯金字塔:對第 i+1 層影像透過雙線性插值實作上采樣,然後用第 i 層金字塔的影像 - 剛才上采樣的影像,得到第 i 層拉普拉斯金字塔的影像。
#include<opencv2/core.hpp>
#include<opencv2/imgproc.hpp>
#include<opencv2/opencv.hpp>
usingnamespacestd;
usingnamespace cv;
// 構建高斯金字塔
voidbuildGaussianPyramid(Mat& image, vector<Mat>& pyramid, int levels){
Mat temp = image.clone();
pyramid.push_back(temp);
for (int i = 1; i < levels; i++) {
// 高斯濾波
Mat blurred;
GaussianBlur(temp, blurred, Size(5, 5), 0);
Mat downSampled(blurred.rows / 2, blurred.cols / 2, blurred.type());
resize(blurred, downSampled, downSampled.size(), 0, 0, INTER_LINEAR);
pyramid.push_back(downSampled);
temp = downSampled;
}
}
// 構建拉普拉斯金字塔
voidbuildLaplacianPyramid(vector<Mat>& pyramid,vector<Mat>& laplacianPyramid){
for (int i = 0; i < pyramid.size()-1; i++) {
Mat upSampled(pyramid[i+1].rows * 2, pyramid[i+1].cols * 2, pyramid[i+1].type());
resize(pyramid[i+1], upSampled, upSampled.size(), 0, 0, INTER_LINEAR);
Mat lap;
subtract(pyramid[i], upSampled, lap);
laplacianPyramid.push_back(lap);
}
}
intmain(){
Mat src = imread(".../lotus.jpg");
int numLevels = 4;
vector<Mat> pyramid;
buildGaussianPyramid(src,pyramid,numLevels);
vector<Mat> laplacianPyramid;
buildLaplacianPyramid(pyramid,laplacianPyramid);
for (int i = 0; i < laplacianPyramid.size(); i++) {
imshow("Laplacian Pyramid Level " + to_string(i), laplacianPyramid[i]);
}
waitKey(0);
return0;
}
OpenCV 也提供了
pyrUp()
函式來構建拉普拉斯金字塔,該函式先對影像進行升采樣(將影像尺寸行和列方向增大一倍),然後再進行高斯平滑。
pyrUp()
和
pyrDown()
不是互逆的操作。
#include<opencv2/core.hpp>
#include<opencv2/imgproc.hpp>
#include<opencv2/opencv.hpp>
usingnamespacestd;
usingnamespace cv;
// 構建拉普拉斯金字塔
voidbuildLaplacianPyramid(Mat& image, vector<Mat>& laplacianPyramid, int levels){
Mat temp = image.clone();
for (int i = 0; i < levels; i++) {
Mat downSampled,upSampled;
pyrDown(temp, downSampled);
pyrUp(downSampled,upSampled);
Mat lap;
subtract(temp, upSampled, lap);
laplacianPyramid.push_back(lap);
temp = downSampled;
}
}
intmain(){
Mat src = imread(".../lotus.jpg");
vector<Mat> laplacianPyramid;
buildLaplacianPyramid(src,laplacianPyramid,3);
for (int i = 0; i < laplacianPyramid.size(); i++) {
imshow("Laplacian Pyramid Level " + to_string(i), laplacianPyramid[i]);
}
waitKey(0);
return0;
}
5. 總結
影像金字塔是一種重要的影像處理技術,它具有尺度不變性、特征提取、影像融合、影像壓縮和影像增強等多種用途。本文詳細介紹了三種常見影像金字塔,它們的原理、套用場景以及構建方式。
好書推薦
【OpenCV4套用開發:入門、進階與工程化實踐】
全書共計16個章節,重點聚焦OpenCV開發常用模組詳解與工程化開發實踐,提升OpenCV套用開發能力,助力讀者成為OpenCV開發者,同時包含深度學習模型訓練與部署加速等知識,幫助OpenCV開發者進一步拓展技能地圖,滿足工業計畫落地所需技能提升。購買請點連結:
https://item.jd.com/10092255924058.html
學習課程有專屬答疑群
負責貼身答疑解惑
讀者專屬QQ群 :657875553
進群暗號:OpenCV4讀者