【翻譯】針對影象的演算法操作
⚠️這個系列是自己瞎翻的,文法很醜,跳著跳著撿重要的部分翻,翻錯了不負責,就這樣。
⚠️基於3.4.3,Arithmetic Operations on Images,附原文。
目標
- 學會幾種針對影象的演算法操作,比如影象加法、影象減法、影象邏輯運算,等等。
- 你會學到這些方法: cv.add(), cv.addWeighted() 等等。
影象加法
你可以把兩張影象用OpenCV裡的方法加在一起。cv.add() 或者簡單的用numpy操作, res = img1 + img2。兩張影象需要有相同的深度和相同的型別,或者第二個影象是一個標量值。
提示
OpenCV的加法和Numpy的加法其實是由區別的。OpenCV的加法是一個飽和操作,而Numpy的加法其實是在做模運算。
比如,仔細思考以下示例:
>>> x = np.uint8([250])
>>> y = np.uint8([10])
>>> print( cv.add(x,y) ) # 250+10 = 260 => 255
[[255]]
>>> print( x+y ) # 250+10 = 260 % 256 = 4
[4]
當你把兩張影象加在一起的時候它會更可見,OpenCV方法提供了一個更好的結果。所以堅持用OpenCV的方法總是會更好些。(譯者注:這段話的意思大概是說我們企圖對兩張影象做加法的時候,心中期望的結果是加出來的影象更可見,OpenCV的加法更符合這個期望。這其實並不是說Numpy的加法不好,而是這兩種加法有各自的使用場景。)
影象混合
這也是一種影象加法,但我們(對每張影象)給出了不同的權重,因此這種演算法給我一種感覺像是在“混合”或者“透明化”。影象被按照以下等式來加在一起。
通過修改 α 值從0到1,你可以展示出從一張影象轉換成另外一張這樣很酷的效果。
現在我用兩張影象混合在一起,第一張給出0.7的權重,第二張給出0.3的權重。方法 cv.addWeighted() 對影象應用了以下的等式。
這裡的 γ 就取0吧。
img1 = cv.imread('ml.png') img2 = cv.imread('opencv-logo.png') dst = cv.addWeighted(img1,0.7,img2,0.3,0) cv.imshow('dst',dst) cv.waitKey(0) cv.destroyAllWindows()
檢視以下結果:
邏輯運算操作
這些包含了AND, OR, NOT 以及 XOR操作。當我們要提取影象的任何部分時(就像我們下節要講到的情景),比如確定和操作一些非常規的影象感興趣區域時,這些操作都會非常有用。 接下來我們會看到一個示例,如何改變一個影象的某個特定區域。
我想要把 OpenCV 的 logo 放在一個影象的上面。如果我直接用加法把兩張圖加在一起,它的顏色就會改變。如果我混合它們,我就要得到一個半透明的效果,但我的期望是不透明。如果我要擺放上去的是一個矩形,那咱們可以用上節使用的影象感興趣區的那個方法。但 OpenCV 的 logo 又不是一個矩形。所以,你可以用以下的邏輯運算來搞定這個事:
# Load two images
img1 = cv.imread('messi5.jpg')
img2 = cv.imread('opencv-logo-white.png')
# I want to put logo on top-left corner, So I create a ROI
rows,cols,channels = img2.shape
roi = img1[0:rows, 0:cols ]
# Now create a mask of logo and create its inverse mask also
img2gray = cv.cvtColor(img2,cv.COLOR_BGR2GRAY)
ret, mask = cv.threshold(img2gray, 10, 255, cv.THRESH_BINARY)
mask_inv = cv.bitwise_not(mask)
# Now black-out the area of logo in ROI
img1_bg = cv.bitwise_and(roi,roi,mask = mask_inv)
# Take only region of logo from logo image.
img2_fg = cv.bitwise_and(img2,img2,mask = mask)
# Put logo in ROI and modify the main image
dst = cv.add(img1_bg,img2_fg)
img1[0:rows, 0:cols ] = dst
cv.imshow('res',img1)
cv.waitKey(0)
cv.destroyAllWindows()
看下面的結果。左側影象顯示了我們建立的遮蓋層,右側影象顯示了我們最終的結果。為了更好的理解,去顯示一下在上面的程式碼中所有的中間(過程產生的)影象。特別是 img1_bg 和 img2_fg。
額外資源
練習
- 用 cv.addWeighted 方法建立一個影象自動播放控制元件(譯者注:slide show 應該是指某款影象自動播放控制元件)達到平緩的改變資料夾下的影象的效果。
上篇:【翻譯】影象基本操作