內容來自OpenCV-Python Tutorials 自己翻譯整理
目標
映像加法、減法、位元運算
學習函數cv2.add(),cv2.addWeighted()
加法:
使用cv2.add()將兩個映像相加,可以使用numpy中的矩陣加法來實現。但是在opencv中加法是飽和操作,也就是有上限值,numpy會對結果模數。
綜上,使用opencv的效果更好
img1=cv2.imread('1.jpg')img2=cv2.imread('2.jpg')res = cv2.add(img1,img2)
原映像
加法後的結果
映像混合
實際上也是加法,只不過是按比例混合起來,有不同的權重
公式如下
g (x) = (1 − α)f0 (x) + αf1 (x)
現在第一幅映像的權重是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 cv2import numpy as np# 載入映像img1 = cv2.imread('2.jpg')img2 = cv2.imread('1.jpg')rows,cols,channels = img2.shaperoi = 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 ] = dstcv2.imshow('res',img2_fg)cv2.waitKey(0)cv2.destroyAllWindows()
範例裡面的思路比較巧妙,logo的背景都是黑色的,方便提取出來
先將logo設定閾值並二值化,得到logo地區的範圍
將在背景圖片中要放置logo地區的像素資訊用位元運算置0
將logo的像素資訊和背景圖片的像素相加
最後就這這個效果
練習
製作一個類似投影片似的的圖片平滑過渡到另外一張圖片(類似鳳姐變成劉亦菲)
import cv2import numpy as npdef nothing(x): passimg1 = 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()
可怕~