1. 程式人生 > >opencv學習(十七):影象金子塔

opencv學習(十七):影象金子塔

邊緣檢測運算元

參考學習連結:https://blog.csdn.net/xiaowei_cqu/article/details/7829481

影象金子塔

參考學習連結:https://www.cnblogs.com/Matrix420/p/4214123.html

opencv中的高斯金字塔、拉普拉斯金字塔與圖片尺寸縮放常用函式說明,

可以使用OpenCV為我們提供的如下兩種方式:

<1>resize函式。這是最直接的方式,

<2>pyrUp( )、pyrDown( )函式。即影象金字塔相關的兩個函式,對影象進行向上取樣,向下取樣的操作。

pyrUp、pyrDown其實和專門用作放大縮小影象尺寸的resize在功能上差不多,披著影象金字塔的皮,說白了還是在對影象進行放大和縮小操作。另外需要指出的是,pyrUp、pyrDown在OpenCV的imgproc模組中的Image Filtering子模組裡。而resize在imgproc 模組的Geometric Image Transformations子模組裡。

影象金字塔是影象中多尺度表達的一種,最主要用於影象的分割,是一種以多解析度來解釋影象的有效但概念簡單的結構。

影象金字塔最初用於機器視覺和影象壓縮,一幅影象的金字塔是一系列以金字塔形狀排列的解析度逐步降低,且來源於同一張原始圖的影象集合。其通過梯次向下取樣獲得,直到達到某個終止條件才停止取樣。

金字塔的底部是待處理影象的高解析度表示,而頂部是低解析度的近似。

我們將一層一層的影象比喻成金字塔,層級越高,則影象越小,解析度越低。

一般情況下有兩種型別的影象金字塔常常出現在文獻和以及實際運用中。他們分別是:

  • 高斯金字塔Gaussianpyramid): 用來向下取樣,主要的影象金字塔
  • 拉普拉斯金字塔(Laplacianpyramid): 用來從金字塔低層影象重建上層未取樣影象,在數字影象處理中也即是預測殘差,可以對影象進行最大程度的還原,配合高斯金字塔一起使用。

兩者的簡要區別:高斯金字塔用來向下降取樣影象,而拉普拉斯金字塔則用來從金字塔底層影象中向上取樣重建一個影象。

要從金字塔第i層生成第i+1層(我們表示第i+1層為G_i+1),我們先要用高斯核對G_1進行卷積,然後刪除所有偶數行和偶數列。當然的是,新得到影象面積會變為源影象的四分之一。按上述過程對輸入影象G_0執行操作就可產生出整個金字塔。

當影象向金字塔的上層移動時,尺寸和解析度就降低。OpenCV中,從金字塔中上一級影象生成下一級影象的可以用PryDown。而通過PryUp將現有的影象在每個維度都放大兩遍。

影象金字塔中的向上和向下取樣分別通過OpenCV函式 pyrUp 和 pyrDown 實現。

概括起來就是:

  • 對影象向上取樣:pyrUp函式
  • 對影象向下取樣:pyrDown函式

這裡的向下與向上取樣,是對影象的尺寸而言的(和金字塔的方向相反),向上就是影象尺寸加倍,向下就是影象尺寸減半。而如果我們按上圖中演示的金字塔方向來理解,金字塔向上影象其實在縮小,這樣剛好是反過來了。

但需要注意的是,PryUp和PryDown不是互逆的,即PryUp不是降取樣的逆操作。這種情況下,影象首先在每個維度上擴大為原來的兩倍,新增的行(偶數行)以0填充。然後給指定的濾波器進行卷積(實際上是一個在每個維度都擴大為原來兩倍的過濾器)去估計“丟失”畫素的近似值。

PryDown( )是一個會丟失資訊的函式。為了恢復原來更高的解析度的影象,我們要獲得由降取樣操作丟失的資訊,這些資料就和拉普拉斯金字塔有關係了。

例項演示:

程式碼如下:

# 匯入cv模組
import cv2 as cv
import numpy as np


# 高斯金子塔
def pyrmid_demo(image):
    level = 3
    temp = image.copy()
    pyrmid_images = []
    for i in range(level):
        dst = cv.pyrDown(temp)
        pyrmid_images.append(dst)
        cv.imshow("pyrmid_down_" + str(i), dst)
        temp = dst.copy()
    return pyrmid_images


# 拉普拉斯金字塔
def lapalim_demo(image):
    pyrmid_images = pyrmid_demo(image)
    level = len(pyrmid_images)
    for i in range[level - 1, -1, -1]:
        if (i - 1) < 0:
            expand = cv.pyrUp(pyrmid_images[i], dstsize=image.shape[:2])
            lpls = cv.subtract(image, expand)
            cv.imshow("lapalim_down_" + str(i), lpls)
        else:
            expand = cv.pyrUp(pyrmid_images[i], dstsize=pyrmid_images[i - 1].shape[:2])
            lpls = cv.subtract(pyrmid_images[i - 1], expand)
            cv.imshow("lapalim_down_" + str(i), lpls)


print("------------Hi,Python!-------------")
# 讀取影象,支援 bmp、jpg、png、tiff 等常用格式
src = cv.imread("F:/Projects/images/demo.png")
# 建立視窗並顯示影象
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)  # 顯示原圖
pyrmid_demo(src)
cv.waitKey(0)
# 釋放視窗
cv.destroyAllWindows()

執行效果: