Like Share Discussion Bookmark Smile

J.J. Huang   2026-02-02   Python OpenCV 04.幾何與繪圖篇   瀏覽次數:次   DMCA.com Protection Status

Python | OpenCV 圖片合成、疊加與相減

📚 前言

在前一篇我們學會了 建立遮罩與基本運算
這一篇要介紹 圖片合成、疊加與相減,並展示如何利用遮罩完成 去背 + 合成 的應用。

🎨 範例圖片


圖:三原色範例圖片 — 紅色、綠色、藍色圓形

圖:圖片來源 — OpenCV 官方 Github

圖:圖片相減範例圖片 — 黃色、白綠色圓形

➕ 圖片合成 (add)

原理說明

  • 使用 cv2.add(img1, img2) 將兩張圖片相加。
  • 像素值超過 255 時會被截斷為 255。
  • 可以逐步相加,將三張圖片合成為一張「三原色比較圖」。

💻 範例程式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import cv2

# 讀取三張圖片
img1 = cv2.imread("red.png")
img2 = cv2.imread("green.png")
img3 = cv2.imread("blue.png")

# 確保大小一致
img2 = cv2.resize(img2, (img1.shape[1], img1.shape[0]))
img3 = cv2.resize(img3, (img1.shape[1], img1.shape[0]))

# 先合成前兩張
temp = cv2.add(img1, img2)

# 再把結果與第三張合成
output = cv2.add(temp, img3)

cv2.imshow("Red", img1)
cv2.imshow("Green", img2)
cv2.imshow("Blue", img3)
cv2.imshow("Add Result", output)
cv2.waitKey(0)
cv2.destroyAllWindows()


圖:程式碼執行結果 — 三張圖片合成為三原色比較圖

🌫️ 圖片權重疊加 (addWeighted)

原理說明

  • 使用 cv2.addWeighted(img1, alpha, img2, beta, gamma)
  • 可模擬透明效果,常用於影像融合。
  • alphabeta 為權重比例,gamma 為亮度調整。

💻 範例程式

1
2
3
4
5
6
7
8
9
10
11
12
import cv2

img1 = cv2.imread("test.png") # 部落格頭像
img2 = cv2.imread("OpenCV_logo_black.png")

img2 = cv2.resize(img2, (img1.shape[1], img1.shape[0]))

output = cv2.addWeighted(img1, 0.8, img2, 0.2, 0)

cv2.imshow("Weighted Blend", output)
cv2.waitKey(0)
cv2.destroyAllWindows()


圖:程式碼執行結果 — 頭像與 OpenCV logo 的透明融合

➖ 圖片相減 (subtract)

原理說明

  • 使用 cv2.subtract(img1, img2),會逐像素相減。
  • 若結果為負數,會被截斷成 0(黑色);若大於 255,則截斷為 255。
  • 常用於差異檢測,找出兩張圖片不同的部分。

💻 範例程式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import cv2

# 讀取圖片
img1 = cv2.imread("white_green.png") # 白色 + 綠色重疊的圖
img2 = cv2.imread("yellow.png") # 黃色圓形的圖

# 確保大小一致
img2 = cv2.resize(img2, (img1.shape[1], img1.shape[0]))

# 相減
output = cv2.subtract(img1, img2)

# 顯示結果
cv2.imshow("Image A (White+Green)", img1)
cv2.imshow("Image B (Yellow)", img2)
cv2.imshow("Subtract Result", output)
cv2.waitKey(0)
cv2.destroyAllWindows()


圖:程式碼執行結果 — 白色與綠色圖片減去黃色圖片

🎨 顏色相減示例

圖片 A 像素 圖片 B 像素 結果像素 說明
(255,255,255) 白色 (0,255,255) 黃色 (255,0,0) 藍色 白色減去黃色 → 只剩藍色
(0,255,0) 綠色 (0,255,255) 黃色 (0,0,0) 黑色 綠色減去黃色 → 負值截斷為黑色
(255,0,0) 紅色 (0,255,255) 黃色 (255,0,0) 紅色 紅色減去黃色 → 維持紅色

📊 小結

  • subtract() 的結果取決於兩張圖片的顏色差異。
  • 白色減去黃色 → 只剩藍色分量。
  • 綠色減去黃色 → 因為差值為負,結果變黑。
  • 適合用來比較兩張相似圖片,找出差異區域。

🖼️ 去背 + 合成

原理說明

  • 利用遮罩 (mask) 去除 logo 背景。
  • 再用 add()addWeighted() 將去背後的圖片合成到背景。

💻 範例程式

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
import cv2
import numpy as np

# 讀取 logo 與背景 (保持原始大小)
logo = cv2.imread("OpenCV_logo_black.png")
bg = cv2.imread("test.png")

# 建立灰階遮罩
logo_gray = cv2.cvtColor(logo, cv2.COLOR_BGR2GRAY)

# 建立兩個遮罩:一個保留 logo,一個保留背景
# 白色區域灰階值很高,設定閾值 240
_, mask_logo = cv2.threshold(logo_gray, 240, 255, cv2.THRESH_BINARY_INV) # 保留非白色區域 (logo)
_, mask_bg = cv2.threshold(logo_gray, 240, 255, cv2.THRESH_BINARY) # 保留白色區域 (背景)

# 去背:只保留 logo 部分
logo_no_bg = cv2.bitwise_and(logo, logo, mask=mask_logo)

# 建立 ROI (放置 logo 的區域)
# 這裡假設 logo 要放在背景左上角 (0:logo.shape[0], 0:logo.shape[1])
rows, cols = logo.shape[:2]
roi = bg[0:rows, 0:cols]

# 清空 ROI 中 logo 的位置
bg_roi = cv2.bitwise_and(roi, roi, mask=mask_bg)

# 合成:背景 ROI + logo
dst = cv2.add(bg_roi, logo_no_bg)
bg[0:rows, 0:cols] = dst

# 顯示結果
cv2.imshow("Logo Merge Result", bg)
cv2.waitKey(0)
cv2.destroyAllWindows()


圖:利用遮罩去背後,將 OpenCV logo 合成到部落格頭像

📊 效果比較

函式 功能 常見用途
add() 圖片相加 合成影像
addWeighted() 權重疊加 透明效果、影像融合
subtract() 圖片相減 差異檢測
遮罩 + 合成 去背後合成 Logo 疊加、圖片合成

⚠️ 注意事項

  • 圖片大小add()addWeighted()subtract() 都要求兩張圖片大小一致,否則需要先用 cv2.resize() 調整。
  • 像素值範圍add()subtract() 的結果會被截斷在 0–255 之間,超過 255 會變成 255,低於 0 會變成 0。
  • 透明效果addWeighted() 可以模擬透明疊加,但 OpenCV 本身不支援 alpha 通道顯示,若要真正透明背景需轉成 BGRA 並輸出 PNG。
  • 遮罩合成:去背合成時,遮罩必須是灰階圖,且大小要與前景圖片一致。

🎯 結語

本篇我們學會了 圖片合成、疊加與相減,並展示了遮罩去背後的合成應用。這些技巧在影像處理、資料集製作、圖片融合時非常常見。

在下一篇,我們將進一步探索 魔術棒填充顏色,學習如何利用 OpenCV 的區域選取與顏色填充技巧,讓影像編輯更直觀。

📖 如在學習過程中遇到疑問,或是想了解更多相關主題,建議回顧一下 Python | OpenCV 系列導讀,掌握完整的章節目錄,方便快速找到你需要的內容。

註:以上參考了
OpenCV Tutorials
OpenCV-Python Tutorials