【翻译: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教程】性能测量和技术提升

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