OpenCV-Python圖片疊加與融合,cv2.add與cv2.addWeighted的區別

python圖片疊加與融合,cv2.add與cv2.addWeighted的區別 

目標
圖像加法、減法、位運算
學習函數cv2.add(),cv2.addWeighted()

加法:
使用cv2.add()將兩個圖像相加,可以使用numpy中的矩陣加法來實現。但是在opencv中加法是飽和操作,也就是有上限值,numpy會對結果取模。

# 圖像上的加法
# 大致有兩種:
#       cv2.add():這是一個飽和操作
#       +:這是Numpy中的運算,之一種模操作,res = img1 + img2
# 注意兩幅圖片的大小類型必須一致,或者第二個圖象是一個標量
# 由於兩者的差別,我們一般多用cv2.add(src1, src2)


綜上,使用opencv的效果更好

img1=cv2.imread('1.jpg')
img2=cv2.imread('2.jpg')

res = cv2.add(img1,img2)

原圖像
這裏寫圖片描述
這裏寫圖片描述
加法後的結果
這裏寫圖片描述

圖像混合(融合,可以設置圖片的透明度)
實際上也是加法,只不過是按比例混合起來,有不同的權重 ,給人一種混合的或者透明的感覺
公式如下
g (x) = (1 − α)f0 (x) + αf1 (x)   #a→(0,1)不同的a值可以實現不同的效果

現在第一幅圖像的權重是0.7,第二幅圖像的權重是0.3,使用cv2.addWeighted()函數進行混合

img1=cv2.imread('1.jpg')
img2=cv2.imread('2.jpg')

dst=cv2.addWeighted(img1,0.7,img2,0.3,0)

混合後的結果
這裏寫圖片描述

按位運算(問題:如何將一個圖放到另一個圖上去,加法會改變顏色,混加會透明)

位運算操作有and, or, not, xor。在提取部分圖像選擇非舉行區域roi時,位運算操作十分有用。下面例子是改變一副圖像的特定區域。
把opencv的標誌放到另外一副圖像上,如果使用加法,顏色會改變,如果使用混合,會變成透明,但是我們不想要透明效果,如果是舉行區域,可以使用roi方法,但是並不是舉行,下面使用位運算實現。

import cv2
import numpy as np
# 加載圖像
img1 = cv2.imread('2.jpg')
img2 = cv2.imread('1.jpg')

rows,cols,channels = img2.shape
roi = img1[0:rows, 0:cols ]

img2gray = cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY)      # 將圖片灰度化
ret, mask = cv2.threshold(img2gray, 175, 255, cv2.THRESH_BINARY)#ret是閾值(175)mask是二值化圖像
mask_inv = cv2.bitwise_not(mask)#獲取把logo的區域取反 按位運算

img1_bg = cv2.bitwise_and(roi,roi,mask = mask)#在img1上面,將logo區域和mask取與使值爲0

# 取 roi 中與 mask_inv 中不爲零的值對應的像素的值,其他值爲 0 。
# 把logo放到圖片當中
img2_fg = cv2.bitwise_and(img2,img2,mask = mask_inv)#獲取logo的像素信息

dst = cv2.add(img1_bg,img2_fg)#相加即可
img1[0:rows, 0:cols ] = dst
cv2.imshow('res',img2_fg)
cv2.waitKey(0)
cv2.destroyAllWindows()

樣例裏面的思路比較巧妙,logo的背景都是黑色的,方便提取出來
先將logo設定閾值並二值化,得到logo區域的範圍
將在背景圖片中要放置logo區域的像素信息用位運算置0
將logo的像素信息和背景圖片的像素相加
最後就這這個效果
這裏寫圖片描述

練習
製作一個類似幻燈片似的的圖片平滑過渡到另外一張圖片(類似鳳姐變成劉亦菲)

import cv2
import numpy as np

def nothing(x):
    pass

img1 = cv2.imread('1.jpg')
img2 = cv2.imread('2.jpg')
# 創建一個黑色背景的窗口
img = np.zeros((500,500,3), np.uint8)
cv2.namedWindow('image')

cv2.createTrackbar('a','image',0,100,nothing)


while(1):
    cv2.imshow('image',img)
    k = cv2.waitKey(1) & 0xFF
    if k == 27:
        break

    r = cv2.getTrackbarPos('a','image')
    r=float(r)/100.0

    img=cv2.addWeighted(img1,r,img2,1.0-r,0)

cv2.destroyAllWindows()

這裏寫圖片描述

import cv2
import numpy as np

import time
step_list = [0.02 * x for x in range(0, 51)]
img1 = cv2.imread("1.jpg")
img2 = cv2.imread("2.jpg")
cv2.imshow("show", img1)
for i in step_list:
    res = cv2.addWeighted(img1, i, img2, (1-i), 0)
    cv2.imshow("show", res)
    cv2.waitKey(60)
if cv2.waitKey(0) ==27:
    # 按'Esc'退出
    cv2.destroyAllWindows()

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章