在图像处理过程中,经常需要对图像进行加法运算,可以通过加号运算符“+”对图像进行加法运算,也可以通过 cv2.add()函数对图像进行加法运算
通常情况下,在灰度图像中,像素用8 个比特位(一个字节)来表示,像素值的范围是[0.255]两个像素值在进行加法运算时,求得的和很可能超过 255. 上述两种不同的加法运算方式,对超过 255 的数值的处理方式是不一样的
3.1.1 加号运算符
使用加号运算符“+”对图像 a(像素值为 a)和图像 b(像素值为 b)进行求和运算时遵循以下规则:
式中,mod是取模运算,“ mod(a+b,256)”表示计算“a+b 的和除以 256 取余数”
根据上述规则,两个点进行加法运算时:
1.如果两个图像对应像素值的和小于或等于 255 则直接相加得到运算结果,例如,像
素值 28 和像素值 36 相加,得到计算结果64
2.如果两个图像对应像素值的和大于 255 则将运算结果对 256 取模,例如 255+58=313
大于 255.则计算(255+58)%256=57 得到计算结果 57
当然,上述公式也可以简化为a+b = mod(a+b,256) 在运算时无论相加的和是否大于255都对数值 256 取模
【例 3.1】使用随机数数组模拟灰度图像,观察使用“+”对像素值求和的结果。
分析:通过将数组的数值类型定义为 dtype= np.uint8,可以保证数组值的范围在[0,255] 之间
编码如下:
import numpy as np
img1=np.random.randint(0,256,size=[3,3],dtype=np.uint8)
img2=np.random.randint(0,256,size=[3,3],dtype=np.uint8)
print("img1=\n",img1)
print("img2=\n",img2)
print("img1+img2=\n",img1+img2)
从上述程序可以看到,使用“+”计算两个 256 级灰度图像内像素值的和时,运算结果对 256 取模。
需要注意,本例题中的加法要进行取模,这是由数组的类型 dtype=np.uint8 所规定的
3.1.2 cv2.add()函数
cv2.add()函数可以用来计算图像像素值相加的和,其语法格式为计算结果一 cv2.add(像素值 a,像素值 b)
使用函数 cv2.add()对像素值a 和像素值b 进行求和运算时,会得到像素值对应图像的饱和值(最大值)。
例如,8 位灰度图像的饱和值为 255,因此,在对8 位灰度图的像素值求和时
遵循以下规则
根据上述规则,在 256 级的灰度图像(8 位灰度图)中的两个像素点进行加法运算时·
1.如果两个像素值的和小于或等于 255,则直接相加得到运算结果。例如,像素值 28和
像素值 36 相加,得到计算结果 64
2.如果两个像素值的和大于 255,则将运算结果处理为饱和值 255,例如 255+58=313,大
于 255,则得到计算结果 255
需要注意,函数 cv2.add()中的参数可能有如下三种形式
形式 1:计算结果= cv2.add(图像 1,图像 2),两个参数都是图像,此时参与运算的图像大小和类型必须保持一致
形式 2:计算结果=cv2.add(数值,图像),第1 个参数是数值,第2 个参数是图像,此时将超过图像饱和值的数值处理为饱和值(最大值)
形式 3:计算结果=cv2.add(图像,数值),第1 个参数是图像,第2 个参数是数值,此时将超过图像饱和值的数值处理为饱和值(最大值)
【例 3.2】使用随机数组模拟灰度图像,观察函数 cv2.add() 对像素值求和的结果
根据题目要求,编写程序如下:
import numpy as np
import cv2
img1=np.random.randint(0,256,size=[3,3],dtype=np.uint8)
img2=np.random.randint(0,256,size=[3,3],dtype=np.uint8)
print("img1=\n",img1)
print("img2=\n",img2)
img3=cv2.add(img1,img2)
print("cv2.add(img1,img2)=\n",img3)
运行结果:
img1=
[[244 107 79]
[ 94 49 235]
[202 254 173]]
img2=
[[196 24 189]
[ 99 231 179]
[164 51 183]]
cv2.add(img1,img2)=
[[255 131 255]
[193 255 255]
[255 255 255]]
【例 3.3】分别使用加号运算符和函数cv2.add()计算两幅灰度图像的像素值之和,观察处理结果
根据题目要求,编写程序如下:
import cv2
a=cv2.imread("C:\\Users\\Administrator\\Desktop\\opencv\\lena.bmp",0)
b=a
result1=a+b
result2=cv2.add(a,b)
cv2.imshow("original",a)
cv2.imshow("result1",result1)
cv2.imshow("result2",result2)
cv2.waitKey()
cv2.destroyAllWindows()
在本例中,首先读取了图像 lena并将其标记为变量 a:接下米,使用语句“b=a”将图lena 复制到变量b内:最后,分别使用“+”和函数 cv2.add(a,b) 计算a和b 之和
运行程序,
左图是原始图像 lena
中间的图是使用加号运算符将图像 lema 自身相加的结果
右图是使用函数 cv2.add(a,b)将图像 lena 自身相加的结果
使用加号运算符计算图像像素值的和时,将和大于 255 的值进行了取模处理,取模后大于 255 的这部分值变得更小了,导致本来应该更亮的像素点变得更暗了,相加所得的图像看起来并不自然。
使用函数 cv2.add(a,b) 计算图像像素值的和时,将和大于 255 的值处理为饱和值 255.图像像素值相加后让图像的像素值增大了,图像整体变亮。