图像的算术运算

目标

  • 学习对图像的几种算术运算,如加法,减法,按位运算等。
  • 您将学习以下函数:cv.add()cv.addWeighted()等。

图像加法

您可以通过 OpenCV 函数,cv.add()或简单地通过 numpy 操作将两个图像相加,res = img1 + img2。两个图像应该具有相同的深度和类型,或者第二个图像可以是像素值,比如(255,255,255),白色值。

注意 OpenCV 相加操作和 Numpy 相加操作之间存在差异。OpenCV 添加是饱和操作,而 Numpy 添加是模运算。要注意的是,两种加法对于结果溢出的数据,会通过某种方法使其在限定的数据范围内。

例如,请考虑以下示例:

  1. >>> x = np.uint8([250])
  2. >>> y = np.uint8([10])
  3. >>> print(cv.add(x,y)) #250 + 10 =260 => 255
  4. [[255]]
  5. >>> print(x + y)
  6. [4]

在将两个图象相加时会发现 OpenCV 函数能够提供更好的结果,所以尽可能地选择 OpenCV 函数。

图像混合

这也是将图像相加,但是对图像赋予不同的权重,从而给出混合感或透明感。图像按以下等式添加:

图像的算术运算 - 图1

通过在(0,1)之间改变图像的算术运算 - 图2的值, 可以用来对两幅图像或两段视频产生时间上的 画面叠化 (cross-dissolve)效果,就像在幻灯片放映和电影制作中那样(很酷吧?)(译者注:在幻灯片翻页时可以设置为前后页缓慢过渡以产生叠加效果,电影中经常在情节过渡时出现画面叠加效果)。

在这里,我拍了两张图片将它们混合在一起。第一图像的权重为 0.7,第二图像的权重为 0.3。cv.addWeighted()在图像上应用以下等式。

图像的算术运算 - 图3
  1. img1= cv.imread('ml.png')
  2. img2= cv.imread('opencv-logo.png')
  3. dst = cv.addWeighted(img1,0.7,img2,0.3,0)
  4. cv.imshow('dst',dst)
  5. cv.waitKey(0)
  6. cv.destroyAllWindows()

观察以下结果:

图像的算术运算 - 图4

按位操作

这包括按位 AND,OR,NOT 和 XOR 运算。它们在提取图像的某一部分(我们将在后面的章节中看到)、定义和使用非矩形 ROI 等方面非常有用。下面我们将看到如何更改图像的特定区域的示例:

假如我想加一个OpenCV的 logo在一个图像上,如果只是简单的将两张图像想加,则会改变叠加处的颜色。如果进行上面所说的混叠操作,则会得到一个有透明效应的结果,但我希望得到一个不透明的logo。如果logo是一个矩形logo,那可以用上节所讲的ROI来做。但是OpenCV的logo是不规则形状的,所以用下面的bitwise操作来进行。

  1. #加载两张图片
  2. img1 = cv.imread'messi5.jpg'
  3. img2 = cv.imread'opencv-logo-white.png'
  4. #我想在左上角放置一个logo,所以我创建了一个 ROI,并且这个ROI的宽和高为我想放置的logo的宽和高
  5. rowscolschannels = img2.shape
  6. roi = img1 [0rows0cols]
  7. #现在创建一个logo的掩码,通过对logo图像进行阈值,并对阈值结果并创建其反转掩码
  8. img2gray = cv.cvtColorimg2cv.COLOR_BGR2GRAY
  9. retmask = cv.thresholdimg2gray10,255cv.THRESH_BINARY
  10. mask_inv = cv.bitwise_notmask
  11. #现在使 ROI 中的徽标区域变黑
  12. img1_bg = cv.bitwise_androiroimask = mask_inv
  13. #仅从徽标图像中获取徽标区域。
  14. img2_fg = cv.bitwise_andimg2img2mask = mask
  15. #在 ROI 中放置徽标并修改主图像
  16. dst = cv.addimg1_bgimg2_fg
  17. img1 [0rows0cols] = dst
  18. cv.imshow'res'img1
  19. cv.waitKey0
  20. cv.destroyAllWindows()

请参阅下面的结果。左图显示了我们创建的蒙版。右图显示最终结果。为了加深理解,请在上面的代码中显示所有中间图像,尤其是 img1_bg 和 img2_fg。

图像的算术运算 - 图5

其他资源

练习

  1. 使用cv.addWeighted()函数在文件夹中创建图像之间平滑过渡的幻灯片并放映。