图像的算术运算
目标
- 学习对图像的几种算术运算,如加法,减法,按位运算等。
- 您将学习以下函数:cv.add(),cv.addWeighted()等。
图像加法
您可以通过 OpenCV 函数,cv.add()或简单地通过 numpy 操作将两个图像相加,res = img1 + img2。两个图像应该具有相同的深度和类型,或者第二个图像可以是像素值,比如(255,255,255),白色值。
注意 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)[4]
在将两个图象相加时会发现 OpenCV 函数能够提供更好的结果,所以尽可能地选择 OpenCV 函数。
图像混合
这也是将图像相加,但是对图像赋予不同的权重,从而给出混合感或透明感。图像按以下等式添加:
通过在(0,1)之间改变
的值, 可以用来对两幅图像或两段视频产生时间上的 画面叠化 (cross-dissolve)效果,就像在幻灯片放映和电影制作中那样(很酷吧?)(译者注:在幻灯片翻页时可以设置为前后页缓慢过渡以产生叠加效果,电影中经常在情节过渡时出现画面叠加效果)。
在这里,我拍了两张图片将它们混合在一起。第一图像的权重为 0.7,第二图像的权重为 0.3。cv.addWeighted()在图像上应用以下等式。
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 运算。它们在提取图像的某一部分(我们将在后面的章节中看到)、定义和使用非矩形 ROI 等方面非常有用。下面我们将看到如何更改图像的特定区域的示例:
假如我想加一个OpenCV的 logo在一个图像上,如果只是简单的将两张图像想加,则会改变叠加处的颜色。如果进行上面所说的混叠操作,则会得到一个有透明效应的结果,但我希望得到一个不透明的logo。如果logo是一个矩形logo,那可以用上节所讲的ROI来做。但是OpenCV的logo是不规则形状的,所以用下面的bitwise操作来进行。
#加载两张图片img1 = cv.imread('messi5.jpg')img2 = cv.imread('opencv-logo-white.png')#我想在左上角放置一个logo,所以我创建了一个 ROI,并且这个ROI的宽和高为我想放置的logo的宽和高rows,cols,channels = img2.shaperoi = img1 [0:rows,0:cols]#现在创建一个logo的掩码,通过对logo图像进行阈值,并对阈值结果并创建其反转掩码img2gray = cv.cvtColor(img2,cv.COLOR_BGR2GRAY)ret,mask = cv.threshold(img2gray,10,255,cv.THRESH_BINARY)mask_inv = cv.bitwise_not(mask)#现在使 ROI 中的徽标区域变黑img1_bg = cv.bitwise_and(roi,roi,mask = mask_inv)#仅从徽标图像中获取徽标区域。img2_fg = cv.bitwise_and(img2,img2,mask = mask)#在 ROI 中放置徽标并修改主图像dst = cv.add(img1_bg,img2_fg)img1 [0:rows,0:cols] = dstcv.imshow('res',img1)cv.waitKey(0)cv.destroyAllWindows()
请参阅下面的结果。左图显示了我们创建的蒙版。右图显示最终结果。为了加深理解,请在上面的代码中显示所有中间图像,尤其是 img1_bg 和 img2_fg。
其他资源
练习
- 使用cv.addWeighted()函数在文件夹中创建图像之间平滑过渡的幻灯片并放映。
