1. 程式人生 > >【翻譯】針對影象的演算法操作

【翻譯】針對影象的演算法操作

⚠️這個系列是自己瞎翻的,文法很醜,跳著跳著撿重要的部分翻,翻錯了不負責,就這樣。

⚠️基於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的加法不好,而是這兩種加法有各自的使用場景。)

影象混合 

這也是一種影象加法,但我們(對每張影象)給出了不同的權重,因此這種演算法給我一種感覺像是在“混合”或者“透明化”。影象被按照以下等式來加在一起。

g(x)=(1-\alpha)f_{0}(x)+\alpha f_{1}(x)

通過修改 α 值從0到1,你可以展示出從一張影象轉換成另外一張這樣很酷的效果。

現在我用兩張影象混合在一起,第一張給出0.7的權重,第二張給出0.3的權重。方法 cv.addWeighted() 對影象應用了以下的等式。

dst = \alpha \times img1 + \beta \times img2 + \gamma

這裡的 γ 就取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()

檢視以下結果:

blending.jpg

 

邏輯運算操作 

這些包含了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。

overlay.jpg

 

額外資源  

練習 

  • 用 cv.addWeighted 方法建立一個影象自動播放控制元件(譯者注:slide show 應該是指某款影象自動播放控制元件)達到平緩的改變資料夾下的影象的效果。

上篇:【翻譯】影象基本操作

下篇:【翻譯】效能測量和技術提升