北科資工二多媒體技術與應用 第三周作業-影像金字塔混和圖片

筆記說明

此筆記用途在於台北科技大學資訊工程系大二下多媒體技術與應用作業紀錄
並非所有人都適用,部分對我而言稍加容易的內容並不會寫在此內。
這是學習後心得的筆記,可能不太適用會未來的學生

由於我沒有學習過裡面的理論,因此這是資工大二學生透過網路與自身理解的筆記,學習價值並不高、且可能擁有大量錯誤。

題目如下,用圖片

此題做法

這是一題很酷的題目,你會學到影像金字塔

甚麼是影像金字塔

影像金字塔透過將圖片放大縮小,而越將圖片放大就是越底層的金字塔,縮小就是越下層的金字塔,跟金字塔的切面面積有關。

高斯金字塔

透過公式得出,不斷地使用此公式進行放大或縮小,結果如下


蒙面西红柿取得,如果有需要移除請跟我說

但有個特別重要的重點,沒有辦法用縮小後的圖片完整還原放大的圖片,很多點被壓縮,要還原也不知道要怎麼還原,因此是縮小的圖片不斷放大就會越來越模糊

拉普拉斯金字塔

必須先建立高斯金字塔才能建立拉普拉斯金字塔。

此方法主要是對同樣大小的高斯金字塔,進行操作,其操作方式如下

  • 將原始圖片設為最底層的金字塔
  • 設定要縮小的次數
  • 記錄每層高斯金字塔的縮小
  • 將上一層的高斯金字塔放大後與當前圖層進行圖片減法,從最上層開始,也就是圖片 size 最小的地方

透過此方式將高斯金字塔上一次的縮小進行放大後在跟當前的圖層進行圖片減法,所遺失的點就是拉普拉斯金字塔

圖片說明

蒙面西红柿取得,如果有需要移除請跟我說

回歸解法

說了這麼多,該來了解這題怎麼做了。

拉普拉斯金字塔是高斯金字塔放大所遺失的點,這時我們可以透過拉普拉斯金字塔來補足這些遺失的點,理論上可以回到離圖片一樣的狀態。

但是在高斯金字塔再放大時,可不知道拉普拉斯金字塔會補足哪些點,所以會一視同仁地把點放大。此時再加上拉普拉斯金字塔的點後(進行圖片相減),此時那些地方就會被中和成高斯金字塔的放大點與拉普拉斯金字塔地點,達到平滑的效果,就可以讓圖片切割的地方看起來更加圓滑。

參考連結

opencv-图像融合(高斯金字塔,拉普拉斯金字塔) by Bonjour_Amy
np.vstack, np.hstack by cltdevelop
OpenCV学习笔记(6)——图像金字塔 by 蒙面西红柿

心得

學習到了圖像金字塔是本題的最大收穫,要謝謝郭梓琳給我一個網頁裡面有教我怎麼做QQQ,不然我應該還要花很多時間才能把這題給解開、搞懂。

總之,很開心有他這個隊友,讚啦。
希望他可以容忍這麼不成材我的XD,愛睡覺又很拖拉。

程式碼

我們這邊製作六成的圖像金字塔,就能做出與題目答案類似的金字塔。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# -*- coding: utf-8 -*-
"""
Created on Thu Mar 25 11:28:28 2021

@author: user
"""

import cv2
import numpy as np

#讀圖片檔案,下面會放題目所需要的圖片
a = cv2.imread("./pic/apple.jpg")
b = cv2.imread("./pic/orange.jpg")

#目標是圖片合併,因此我們先建兩個高斯金字塔
gaussA = [a.copy()]
gaussB = [b.copy()]
copyA = a.copy()
copyB = b.copy()
for i in range(6): # more small
copyA = cv2.pyrDown(copyA) #縮小,建立金字塔上層
copyB = cv2.pyrDown(copyB)

gaussA.append(copyA)
gaussB.append(copyB)

copyA = gaussA[5] #稍微注意,拉普拉斯金字塔由於編寫方便,我們的陣列值越大時圖層越小,金字塔相反
laplacianA = [copyA] #建立拉普拉斯金字塔
copyB = gaussB[5]
laplacianB = [copyB]

for i in range(5, 0, -1): #建立拉普拉斯金字塔
tempA = cv2.pyrUp(gaussA[i]) #將當前高斯金字塔放大
tempB = cv2.pyrUp(gaussB[i])

subA = cv2.subtract(gaussA[i-1], tempA) #放大後,在跟下一層的高斯金字塔做減法得出拉普拉斯金字塔
subB = cv2.subtract(gaussB[i-1], tempB)
laplacianA.append(subA) #記錄起來
laplacianB.append(subB)
#cv2.imshow("subA", subA)
#cv2.waitKey(0)

stack = [] #要被疊加的圖層放置處

for itA, itB in zip(laplacianA, laplacianB): #合併兩個拉普拉斯金字塔
h, w, ch = itA.shape #圖片長、寬、通道
merge = np.hstack((itA[0:h, 0:(w // 2)], itB[0:h, (w // 2):w])) #將圖片進行合併
#注意,第二張圖片是要右半邊
stack.append(merge) #紀錄

result = stack[0] #一開使放入最頂端金字塔的圖層,特別注意第 0 層是沒有被減法過的圖層
for i in range(1, 6):
result = cv2.pyrUp(result) #放大圖層
result = cv2.add(result, stack[i]) #疊加我們的拉普拉斯金字塔

cv2.imshow("a", a)
cv2.imshow("result", result) #輸出完整圖片
cv2.waitKey(0)
cv.imwrite('result.jpg',result)

題目資料

apple

orange

result

  • 版權聲明: 本部落格所有文章除有特別聲明外,均採用 Apache License 2.0 許可協議。轉載請註明出處!
  • © 2020-2024 John Doe
  • Powered by Hexo Theme Ayer
  • PV: UV: