iT邦幫忙

2024 iThome 鐵人賽

DAY 3
0
AI/ ML & Data

AI 影像處理 30天系列 第 3

[AI 影像處理 30天] [Day 03] 電腦視覺進階應用:2D 平面圖像置入技術

  • 分享至 

  • xImage
  •  

前言

前面一天我們介紹了 OpenCV 的基本功能像是圖像讀取、顯示、保存、色彩空間轉換..那我們接著進入我們的主題,在第一天時我們提到了 Adobe 的物品置入技術,你可能會想這有什麼難的?不就是直接把物品去背丟進去嗎?沒錯這樣的理解或許是對的~不過因為 3D 物品將會涉及更多的細節像是在光影下材質的不同表現,所以我們在今天先用 2D 圖像來玩玩吧!不過不用擔心這些內容在之後的鐵人賽都會有更深入的探討,我們開始吧!
我們可以先來看看結果圖吧!
https://ithelp.ithome.com.tw/upload/images/20240830/201689013uXZ8vtRiD.png

首先一樣歡迎大家前往 Kaggle 的 Notebook 來做練習

開始實作

收先先來引入必要的套件吧!

import cv2
print(cv2.__version__)

接著我們來讀取圖片吧!

background_path = '/kaggle/input/combine-picture-dataset/kitchen.png'
poster_path = '/kaggle/input/combine-picture-dataset/lisa.jpg'

# 讀取背景和海報圖片
background = cv2.imread(background_path)
poster = cv2.imread(poster_path, cv2.IMREAD_UNCHANGED)  # 保留 Alpha 通道
# 如果海報沒有 Alpha 通道,添加一個
if poster.shape[2] == 3:
    poster = cv2.cvtColor(poster, cv2.COLOR_BGR2BGRA)

接著透過調整 Alpha 通道的方式去調整透明度。

# 確保圖像有Alpha通道
if poster.shape[2] != 4:
    poster = cv2.cvtColor(image, cv2.COLOR_BGR2BGRA)

# 將Alpha值調整到0-255的範圍
alpha_factor = int(alpha * 255)

# 調整alpha通道
poster[:, :, 3] = alpha_factor

那因為我們蒙娜麗莎的圖片大小太大了所以需要去調整海報大小,這邊使用縮放的方式去進行調整。

# 計算縮放比例,使海報高度為背景高度的一半
scale = background.shape[0] / (4 * poster.shape[0])
new_width = int(poster.shape[1] * scale)
new_height = int(poster.shape[0] * scale)
poster = cv2.resize(poster, (new_width, new_height), interpolation=cv2.INTER_AREA)

接著我們貼上指定的區域吧!這下方的程式目標就是要確保海報不會超出畫面。

# 確保海報不會超出背景邊界
x, y = position
if x < 0: x = 0
if y < 0: y = 0
if x + poster.shape[1] > background.shape[1]: x = background.shape[1] - poster.shape[1]
if y + poster.shape[0] > background.shape[0]: y = background.shape[0] - poster.shape[0]
position = (x, y)

再來創建遮罩並進行 Alpha 混合。為甚麼這邊要做遮罩和 Alpha 混合呢?

  • 遮罩:遮罩是一個灰度圖像,其中的每個像素值表示相應位置的透明度(Alpha 值)。在圖像合成中,遮罩決定了哪些部分應該顯示(不透明),哪些部分應該透明或部分透明。
  • Alpha 通道:Alpha 通道是圖像中的一個額外通道,用於表示像素的透明度。在圖像合成中,Alpha 通道可以用來控制前景圖像的透明度,使得它能夠更自然地融合到背景圖像中。例如,當將一張海報合成到一張背景圖像上時,Alpha 通道可以用來創建半透明效果,這樣可以模擬玻璃反光、霧氣等效果。

下方的程式碼邏輯如下,首先先用 np.zeros 創建了一個全黑的遮罩(全透明),然後用前景圖像的 Alpha 通道填充該遮罩。接著提取圖像區域和計算混合比例 roi(Region of Interest)定義了背景中前景圖像將被放置的位置,Alpha 計算了前景圖像中每個像素的透明度(0 到 1 之間),使用公式 result = (1 - alpha) * roi + alpha * poster_bgr 進行混合。這個公式將背景和前景圖像按照 Alpha 通道的比例進行加權平均。

mask = np.zeros(background.shape[:2], dtype=np.uint8)
mask[y:y+poster.shape[0], x:x+poster.shape[1]] = poster[:,:,3]
poster_bgr = poster[:,:,:3]
roi = background[y:y+poster.shape[0], x:x+poster.shape[1]]
alpha = mask[y:y+poster.shape[0], x:x+poster.shape[1]] / 255.0
result = (1 - alpha[:,:,np.newaxis]) * roi + alpha[:,:,np.newaxis] * poster_bgr

最後一步就是保存結果啦~

background[y:y+poster.shape[0], x:x+poster.shape[1]] = result.astype(np.uint8)
cv2.imwrite('/kaggle/working/result.png', background)

結語

https://ithelp.ithome.com.tw/upload/images/20240830/201689013uXZ8vtRiD.png
你可以看到圖像是被貼上去了,透過 Alpha 混合有稍微讓合成效果比起隨意貼上更加真實且自然,但可以看到在光影以及透視的感覺並沒有這麼的好因此我們接下來將會針對這些問題繼續探討下去,歡迎繼續追蹤我們的鐵人賽文章~

如有任何問題也可以下方留言Q&A!


撰文者: RenHe Huang


上一篇
[AI 影像處理 30天] [Day 02] 電腦視覺幼幼班:Python OpenCV 介紹 OpenCV 的基礎用法
下一篇
[AI 影像處理 30天] [Day 04] 深究深度圖生成套件 stable-diffusion-webui-depthmap-script 的用途
系列文
AI 影像處理 30天30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言