簡介:圖像金字塔是圖像中多尺度表達的一種,最主要用於圖像的分割,是一種以多分辨率來解釋圖像的有效但概念簡單的結構。簡單來說,圖像金字塔就是用來進行圖像縮放的。
進行圖像縮放可以用圖像金字塔,也可以使用resize函數進行縮放,后者效果更好。這里只是對圖像金字塔做一些簡單了解。
兩種類型的金字塔:
①高斯金字塔:用於下采樣。高斯金字塔是最基本的圖像塔。原理:首先將原圖像作為最底層圖像G0(高斯金字塔的第0層),利用高斯核(5*5)對其進行卷積,然后對卷積后的圖像進行下采樣(去除偶數行和列)得到上一層圖像G1,將此圖像作為輸入,重復卷積和下采樣操作得到更上一層圖像,反復迭代多次,形成一個金字塔形的圖像數據結構,即高斯金字塔。
②拉普拉斯金字塔:用於重建圖像,也就是預測殘差,對圖像進行最大程度的還原。比如一幅小圖像重建為一幅大圖,原理:用高斯金字塔的每一層圖像減去其上一層圖像上采樣並高斯卷積之后的預測圖像,得到一系列的差值圖像即為 LP 分解圖像。
兩種類型的采樣:
①上采樣:就是圖片放大(所謂上嘛,就是變大),使用PryUp函數。 上采樣步驟:先將圖像在每個方向放大為原來的兩倍,新增的行和列用0填充,再使用先前同樣的內核與放大后的圖像卷積,獲得新增像素的近似值。
②下采樣:就是圖片縮小(所謂下嘛,就是變小),使用PryDown函數。下采樣將步驟:先對圖像進行高斯內核卷積 ,再將所有偶數行和列去除。
總之,上、下采樣都存在一個嚴重的問題,那就是圖像變模糊了,因為縮放的過程中發生了信息丟失的問題。要解決這個問題,就得用拉普拉斯金字塔。
參考博客:
https://www.cnblogs.com/skyfsm/p/6876732.html
https://blog.csdn.net/app_12062011/article/details/52471299
代碼如下:
import cv2 as cv #高斯金字塔 def pyramid_demo(image): level = 3 #設置金字塔的層數為3 temp = image.copy() #拷貝圖像 pyramid_images = [] #建立一個空列表 for i in range(level): dst = cv.pyrDown(temp) #先對圖像進行高斯平滑,然后再進行降采樣(將圖像尺寸行和列方向縮減一半) pyramid_images.append(dst) #在列表末尾添加新的對象 cv.imshow("pyramid"+str(i), dst) temp = dst.copy() return pyramid_images #拉普拉斯金字塔 def lapalian_demo(image): pyramid_images = pyramid_demo(image) #做拉普拉斯金字塔必須用到高斯金字塔的結果 level = len(pyramid_images) for i in range(level-1, -1, -1): if (i-1) < 0: expand = cv.pyrUp(pyramid_images[i], dstsize = image.shape[:2]) lpls = cv.subtract(image, expand) cv.imshow("lapalian_down_"+str(i), lpls) else: expand = cv.pyrUp(pyramid_images[i], dstsize = pyramid_images[i-1].shape[:2]) lpls = cv.subtract(pyramid_images[i-1], expand) cv.imshow("lapalian_down_"+str(i), lpls) src = cv.imread('E:/imageload/zixia.jpg') cv.namedWindow('input_image', cv.WINDOW_AUTOSIZE) #設置為WINDOW_NORMAL可以任意縮放 cv.imshow('input_image', src) lapalian_demo(src) cv.waitKey(0) cv.destroyAllWindows()
運行結果:
注意:
1.opencv的pyrDown函數先對圖像進行高斯平滑,然后再進行降采樣(將圖像尺寸行和列方向縮減一半)。其函數原型為:pyrDown(src[, dst[, dstsize[, borderType]]]) -> dst
src參數表示輸入圖像。
dst參數表示輸出圖像,它與src類型、大小相同。
dstsize參數表示降采樣之后的目標圖像的大小。它是有默認值的,如果我們調用函數的時候不指定第三個參數,那么這個值是按照 Size((src.cols+1)/2, (src.rows+1)/2) 計算的。而且不管你自己如何指定這個參數,一定必須保證滿足以下關系式:|dstsize.width * 2 - src.cols| ≤ 2; |dstsize.height * 2 - src.rows| ≤ 2。也就是說降采樣的意思其實是把圖像的尺寸縮減一半,行和列同時縮減一半。
borderType參數表示表示圖像邊界的處理方式。
2.opencv的pyrUp函數先對圖像進行升采樣(將圖像尺寸行和列方向增大一倍),然后再進行高斯平滑。其函數原型為:pyrUp(src[, dst[, dstsize[, borderType]]]) -> dst
src參數表示輸入圖像。
dst參數表示輸出圖像,它與src類型、大小相同。
dstsize參數表示降采樣之后的目標圖像的大小。在默認的情況下,這個尺寸大小是按照 Size(src.cols*2, (src.rows*2) 來計算的。如果你自己要指定大小,那么一定要滿足下面的條件:
|dstsize.width - src.cols * 2| ≤ (dstsize.width mod 2); //如果width是偶數,那么必須dstsize.width是src.cols的2倍
|dstsize.height - src.rows * 2| ≤ (dstsize.height mod 2);
borderType參數表示表示圖像邊界的處理方式。
參考:
https://blog.csdn.net/woainishifu/article/details/62888228
https://blog.csdn.net/poem_qianmo/article/details/26157633
注意:拉普拉斯金字塔時,圖像大小必須是2的n次方*2的n次方,不然會報錯?(只要圖像長和寬相等即可,並不非要是2的n次方*2的n次方,至少我這么做沒問題,也不知道為什么都說圖像大小必須是2的n次方*2的n次方,求知道的大佬告知一波!)