目录
一、简单数值计算
二、opencv中提供函数进行计算
三、cv2.addWeighted
一、简单数值计算
在opencv中,我们有许多可以获取图像各类数值的办法,许多函数能获得各种方面的数据。但如果我们什么都不用,仅仅对图像上每一个点做加法运算会发生什么?
import cv2
img1 = cv2.imread('3.jpg')
img2 = img1 + 10
print(img1[:5,:,0])
print(img2[:5,:,0])
cv2.imshow('img1', img1)
cv2.imshow('img2', img2)
cv2.waitKey(0)
这里,我们先导入opencv库,然后将名为“3.jpg”的图片读进来。 回忆一下,imread()函数返回的是一个Numpy数组,这个数组通常是三维数组,包含了高度、宽度、通道数。对于彩色图像,通道数一般为3。
第4行让img2=img1+10,相当于给读进来的图像的每一像素的三个通道都加了10。
代码第6行使用数组的知识,创建了一个图像的前 5 行像素的第一个通道的切片,并将其打印出来,最后将原来的图像和改变后的图像显示出来,如下图所示:
可以看到,新的图像已经不成样子了。对比前后输出的两个二维列表可以发现,列表中的每一个值都加了10,但有的直接变成了个位数。 这是因为,列表中的每个值只能从0~255这256个值中选择一个,但254+10=264,已经超出了255的范围,所以在求余256后得到了新的图像值。
接下来我们让两个图像的值直接相加,看看会发生什么。
import cv2
img1 = cv2.imread('3.jpg')
img2 = cv2.imread('4.jpg')
img3 = img1 + img2
print(img3[:5,:,1])
cv2.imshow('img3', img3)
cv2.waitKey(0)
这里,前面的步骤与上面一样,这里多读进来一张图片,并将两张图片直接相加,结果赋值给img3,并将img3显示出来。
可是运行却出现了如下报错:
这个报错的意思是,在执行img1+img2的代码时,程序发现用来相加的两个数组高度、宽度不一样,所以没有办法相加。这告诉我们,在执行图像加法时,两个图像的高度、宽度、通道都必须一致。
我们修改一下代码:
import cv2
img1 = cv2.imread('3.jpg')
img2 = cv2.imread('4.jpg')
img1 = cv2.resize(img1, (272, 245))
img3 = img1 + img2
print(img3[:5,:,1])
cv2.imshow('img3', img3)
cv2.waitKey(0)
这里,我们在执行加法之前加了一个cv2.resize函数,重新设定了img1图像的大小使其与img2相同。这样就能执行加法了,运行结果如下:
看起来还是蛮掉san的。
二、opencv中提供函数进行计算
但其实,opencv中给我们提供了一个加法函数cv2.add(),它与加法的区别在哪里,我们来运行看一下:
import cv2
img1 = cv2.imread('3.jpg')
img2 = cv2.imread('4.jpg')
img1 = cv2.resize(img1, (272, 245))
img3 = cv2.add(img1, img2)
print(img3[:5,:,1])
cv2.imshow('img1', img1)
cv2.imshow('img2', img2)
cv2.imshow('img3', img3)
cv2.waitKey(0)
在输出的列表中可以看到,上次超出255范围被求余的数值,现在统统变成了255,相当于越界的数值被强制设置为了255,不再进行求余操作。
但是很明显,这样的图像相加并没有满足我们的要求,得到的图像都没法看。怎么办呢?opencv也提供了相应的函数给我们使用。
三、cv2.addWeighted
在opencv中,cv2.addWeighted函数用于更加精准的图片叠加。数学计算的公式为:
其中,R代表叠加后的图像, ,代表参与叠加的两个图像,和分别代表两张图像的权重,b代表标量值,加到加权和上。
在代码中,需要这么写:
import cv2
img1 = cv2.imread('3.jpg')
img2 = cv2.imread('4.jpg')
img1 = cv2.resize(img1, (272, 245))
img3 = cv2.addWeighted(img1, 0.4, img2, 0.6, 0)
print(img3[:5,:,1])
cv2.imshow('img1', img1)
cv2.imshow('img2', img2)
cv2.imshow('img3', img3)
cv2.waitKey(0)
这段代码中,cv2.addWeight()传入了五个参数,分别是叠加图像1,图像1的权重,叠加图像2,图像2的权重以及标量值b。
运行结果如下:
这样看起来,图像的叠加就不会显得生硬了。