opencv 图像金字塔(python)
圖像金字塔
- 圖像金字塔
- 理論基礎
- 下采樣
- 上采樣
- pyrDown函數
- pyrUp函數
- 采樣可逆性的研究
- 拉普拉斯金字塔
圖像金字塔
圖像金字塔是由一幅圖像的多個不同分辨率的子圖所構成的圖像集合
該組圖像是由單個圖像通過不斷地降采樣所產生的,最小的圖像可能僅僅有一個像素點。
圖像金字塔是一系列以金字塔形狀排列的、自底向上分辨率逐漸降低的圖像集合。
通常情況下,圖像金字塔的底部是待處理的高分辨率圖像(原始圖像),而頂部則為其低分辨率的近似圖像。
向金字塔的頂部移動時,圖像的尺寸和分辨率都不斷地降低。通常情況下,每向上移動一級,圖像的寬和高都降低為原來的二分之一。
理論基礎
下采樣
圖像金字塔是同一圖像不同分辨率的子圖集合,是通過對原圖像不斷地向下采樣而產生的,即由高分辨率的圖像(大尺寸)產生低分辨率的近似圖像(小尺寸)。
最簡單的圖像金字塔可以通過不斷地刪除圖像的偶數行和偶數列得到。
也可以先對原始圖像濾波,得到原始圖像的近似圖像,然后將近似圖像的偶數行和偶數列刪除以獲取向下采樣的結果。有多種濾波器可以選擇。例如:
- 鄰域濾波器:采用鄰域平均技術求原始圖像的近似圖像。該濾波器能夠產生平均金字塔。
- 高斯濾波器:采用高斯濾波器對原始圖像進行濾波,得到高斯金字塔。這是OpenCV函數cv2.pyrDown()所采用的方式。
高斯金字塔是通過不斷地使用高斯濾波器濾波、采樣所產生的。
原始圖像與各次向下采樣所得到的結果圖像共同構成了高斯金字塔。
例如,可以將原始圖像稱為第0層,第1次向下采樣的結果圖像稱為第1層,第2次向下采樣的結果圖像稱為第3層,以此類推。
上采樣
在向上采樣的過程中,通常將圖像的寬度和高度都變為原來的2倍。
這意味著,向上采樣的結果圖像的大小是原始圖像的4倍。因此,要在結果圖像中補充大量的像素點。
對新生成的像素點進行賦值,稱為插值處理,該過程可以通過多種方式實現,例如最臨近插值就是用最鄰近的像素點給當前還沒有值的像素點賦值。
有一種常見的向上采樣,對像素點以補零的方式完成插值。通常是在每列像素點的右側插入值為零的列,在每行像素點的下方插入值為零的行。
接下來,使用向下采樣時所用的高斯濾波器(高斯核)對補零后的圖像進行濾波處理,以獲取向上采樣的結果圖像。
但是需要注意,此時圖像中四分之三像素點的值都是零。所以,要將高斯濾波器系數乘以4,以保證得到的像素值范圍在其原有像素值范圍內。(補了很多0,導致濾波后結果偏小)
向上采樣和向下采樣是相反的兩種操作。但是,由于向下采樣會丟失像素值,所以這兩種操作并不是可逆的。
也就是說,對一幅圖像先向上采樣、再向下采樣,是無法恢復其原始狀態的;同樣,對一幅圖像先向下采樣、再向上采樣也無法恢復到原始狀態。
pyrDown函數
函數cv2.pyrDown(),用于實現圖像高斯金字塔操作中的向下采樣,其語法形式為:
dst = cv2.pyrDown( src[, dstsize[, borderType]] )- dst為目標圖像
- src為原始圖像
- dstsize為目標圖像的大小
- borderType為邊界類型,默認值為BORDER_DEFAULT,且這里僅支持BORDER_DEFAULT
默認情況下,輸出圖像的大小為Size((src.cols+1)/2, (src.rows+1)/2)。
在任何情況下,圖像尺寸必須滿足如下條件:
- |dst. width?2-src. cols|≤2
- |dst. height?2-src. rows|≤2
cv2.pyrDown()函數首先對原始圖像進行高斯濾波變換,以獲取原始圖像的近似圖像。在獲取近似圖像后,該函數通過拋棄偶數行和偶數列來實現向下采樣。
**例子:**使用函數cv2.pyrDown()對一幅圖像進行向下采樣
import cv2 o=cv2.imread("./img/hand1.png", cv2.IMREAD_GRAYSCALE) r1=cv2.pyrDown(o) r2=cv2.pyrDown(r1) r3=cv2.pyrDown(r2) print("o.shape=", o.shape) print("r1.shape=", r1.shape) print("r2.shape=", r2.shape) print("r3.shape=", r3.shape) cv2.imshow("original", o) cv2.imshow("r1", r1) cv2.imshow("r2", r2) cv2.imshow("r3", r3) cv2.waitKey() cv2.destroyAllWindows()經過向下采樣后,圖像的分辨率會變低。
pyrUp函數
在OpenCV中,使用函數cv2.pyrUp()實現圖像金字塔操作中的向上采樣,其語法形式如下:
dst = cv2.pyrUp( src[, dstsize[, borderType]] )- dst為目標圖像
- src為原始圖像
- dstsize為目標圖像的大小
- borderType為邊界類型,默認值為BORDER_DEFAULT,且這里僅支持BORDER_DEFAULT。
目標圖像的大小為Size(src.cols*2, src.rows*2)。
在任何情況下,圖像尺寸需要滿足下列條件:
- |dst. width-src. cols?2|≤mod(dst. widh,2)
- |dst. height-src. rows?2|≤mod(dst. height,2)
對圖像向上采樣時,在每個像素的右側、下方分別插入零值列和零值行,得到一個偶數行、偶數列(即新增的行、列)都是零值的新圖像New。接下來,用向下采樣時所使用的高斯濾波器對新圖像New進行濾波,得到向上采樣的結果圖像。
為了確保像素值區間在向上采樣后與原始圖像保持一致,需要將高斯濾波器的系數乘以4。
**例子:**使用函數cv2.pyrUp()對一幅圖像進行向上采樣
import cv2 o=cv2.imread("./img/hand2.png") r1=cv2.pyrUp(o) r2=cv2.pyrUp(r1) r3=cv2.pyrUp(r2) print("o.shape=", o.shape) print("r1.shape=", r1.shape) print("r2.shape=", r2.shape) print("r3.shape=", r3.shape) cv2.imshow("original", o) cv2.imshow("r1", r1) cv2.imshow("r2", r2) cv2.imshow("r3", r3) cv2.waitKey() cv2.destroyAllWindows()采樣可逆性的研究
拉普拉斯金字塔
為了在向上采樣時能夠恢復具有較高分辨率的原始圖像,就要獲取在采樣過程中所丟失的信息,這些丟失的信息就構成了拉普拉斯金字塔。
拉普拉斯金字塔的定義形式為:
Li=Gi - pyrUp(Gi+ 1)- Li表示拉普拉斯金字塔中的第i層
- Gi表示高斯金字塔中的第i層
拉普拉斯金字塔中的第i層,等于“高斯金字塔中的第i層”與“高斯金字塔中的第i+1層的向上采樣結果”之差。
例子: 使用函數cv2.pyrDown()和cv2.pyrUp()構造拉普拉斯金字塔。
import cv2 O=cv2.imread("./img/hand2.png") G0=O G1=cv2.pyrDown(G0) G2=cv2.pyrDown(G1) G3=cv2.pyrDown(G2) ### 注意: 可能兩個圖像的大小不一樣 L0=G0-cv2.resize(cv2.pyrUp(G1),G0.shape[0:2][::-1]) L1=G1-cv2.resize(cv2.pyrUp(G2),G1.shape[0:2][::-1]) L2=G2-cv2.resize(cv2.pyrUp(G3),G2.shape[0:2][::-1]) print("L0.shape=", L0.shape) print("L1.shape=", L1.shape) print("L2.shape=", L2.shape) cv2.imshow("L0", L0) cv2.imshow("L1", L1) cv2.imshow("L2", L2) cv2.waitKey() cv2.destroyAllWindows()拉普拉斯金字塔的作用在于,能夠恢復高分辨率的圖像。
向上采樣恢復高分辨率圖像:
G0=L0+cv2.pyrUp(G1) G1=L1+cv2.pyrUp(G2) G2=L2+cv2.pyrUp(G3)構造拉普拉斯金字塔的目的就是為了恢復高分辨率的圖像。
例子: 使用拉普拉斯金字塔及高斯金字塔恢復原始圖像。
import cv2 import numpy as np O=cv2.imread("./img/hand1.png") G0=O G1=cv2.pyrDown(G0) L0=O-cv2.resize(cv2.pyrUp(G1),G0.shape[0:2][::-1]) RO=L0+cv2.resize(cv2.pyrUp(G1),G0.shape[0:2][::-1]) # 通過拉普拉斯圖像復原的原始圖像 print("O.shape=", O.shape) print("RO.shape=", RO.shape) result=RO-O # 將O和RO做減法運算 # 計算result的絕對值 result=abs(result) # 計算result所有元素的和 print("原始圖像O與恢復圖像RO之差的絕對值和:", np.sum(result)) cv2.imshow("origin",O) cv2.imshow("ReO",RO) cv2.waitKey() cv2.destroyAllWindows()總結
以上是生活随笔為你收集整理的opencv 图像金字塔(python)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 游戏服务器端开发要点
- 下一篇: linux中分区详细步骤,Linux下硬