【翻譯:OpenCV-Python教程】針對圖像的算法操作

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

⚠️基於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 應該是指某款圖像自動播放控件)達到平緩的改變文件夾下的圖像的效果。

上篇:【翻譯:OpenCV-Python教程】圖像基本操作

下篇:【翻譯:OpenCV-Python教程】性能測量和技術提升

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