win10+Python3.7.3+OpenCV3.4.1入门学习(三)————3.1图像加法运算

Python版本是Python3.7.3,OpenCV版本OpenCV.3.4.1,开发环境为PyCharm

(三)图像运算

针对图像的加法运算、位运算都是比较基础的运算。但是,很多复杂的图像处理功能正是借助这些基础的运算来完成的。所以,牢固掌握基础操作,对于更好地实现图像处理是非常有帮助的。本章简单介绍了加法运算、位运算,并使用它们实现了位平面分解、图像异或加密、数字水印、脸部打码/解码等实例。
3.1 图像加法运算
在图像处理过程中,经常需要对图像进行加法运算。可以通过加号运算符“+”对图像进行加法运算,也可以通过cv2.add()函数对图像进行加法运算。
通常情况下,在灰度图像中,像素用8个比特位(一个字节)来表示,像素值的范围是[0,255]。两个像素值在进行加法运算时,求得的和很可能超过255。上述两种不同的加法运算方式,对超过255的数值的处理方式是不一样的。
3.1.1 加号运算符
使用加号运算符“+”对图像a(像素值为a)和图像b(像素值为b)进行求和运算时,遵循以下规则:
在这里插入图片描述
式中,mod()是取模运算,“mod(a+b, 256)”表示计算“a+b的和除以256取余数”。
根据上述规则,两个点进行加法运算时:
● 如果两个图像对应像素值的和小于或等于255,则直接相加得到运算结果。例如,像素值28和像素值36相加,得到计算结果64。
● 如果两个图像对应像素值的和大于255,则将运算结果对256取模。例如255+58=313,大于255,则计算(255+58)% 256=57,得到计算结果57。
当然,上述公式也可以简化为a+b=mod(a+b,256),在运算时无论相加的和是否大于255,都对数值256取模。
eg1:使用随机数数组模拟灰度图像,观察使用“+”对像素值求和的结果。
分析:通过将数组的数值类型定义为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)

运行程序,得到如下计算结果:

img1=
 [[222 105  83]
 [ 35  82  32]
 [222 167  44]]
img2=
 [[118 231  23]
 [175 149 237]
 [ 85 170  71]]
img1+img2=
 [[ 84  80 106]
 [210 231  13]
 [ 51  81 115]]

从上述程序可以看到,使用“+”计算两个256级灰度图像内像素值的和时,运算结果会对256取模。
需要注意,本例题中的加法要进行取模,这是由数组的类型dtype=np.uint8所规定的。

3.1.2 cv2.add()函数
函数cv2.add()可以用来计算图像像素值相加的和,其语法格式为:

计算结果=cv2.add(像素值a,像素值b)

使用函数cv2.add()对像素值a和像素值b进行求和运算时,会得到像素值对应图像的饱和值(最大值)。例如,8位灰度图像的饱和值为255,因此,在对8位灰度图的像素值求和时,遵循以下规则:
win10+Python3.7.3+OpenCV3.4.1入门学习(三)————3.1图像加法运算_第1张图片
根据上述规则,在256级的灰度图像(8位灰度图)中的两个像素点进行加法运算时:
● 如果两个像素值的和小于或等于255,则直接相加得到运算结果。例如,像素值28和像素值36相加,得到计算结果64。
● 如果两个像素值的和大于255,则将运算结果处理为饱和值255。例如255+58=313,大于255,则得到计算结果255。
需要注意,函数cv2.add()中的参数可能有如下三种形式。
● 形式1:计算结果=cv2.add(图像1,图像2),两个参数都是图像,此时参与运算的图像大小和类型必须保持一致。
● 形式2:计算结果=cv2.add(数值,图像),第1个参数是数值,第2个参数是图像,此时将超过图像饱和值的数值处理为饱和值(最大值)。
● 形式3:计算结果=cv2.add(图像,数值),第1个参数是图像,第2个参数是数值,此时将超过图像饱和值的数值处理为饱和值(最大值)。

eg2:使用随机数组模拟灰度图像,观察函数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=
 [[200  20  81]
 [222  93  61]
 [159  56 209]]
img2=
 [[192 217 239]
 [109  88 226]
 [185 108  60]]
cv2.add(img1,img2)=
 [[255 237 255]
 [255 181 255]
 [255 164 255]]

eg3:分别使用加号运算符和函数cv2.add()计算两幅灰度图像的像素值之和,观察处理结果。
程序如下:

import cv2
a=cv2.imread("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之和。
运行程序,得到如下图所示的运行结果,其中:
● 左图是原始图像lena。
● 中间的图是使用加号运算符将图像lena自身相加的结果。
● 右图是使用函数cv2.add()将图像lena自身相加的结果。
从上述运算结果可以看出:
● 使用加号运算符计算图像像素值的和时,将和大于255的值进行了取模处理,取模后大于255的这部分值变得更小了,导致本来应该更亮的像素点变得更暗了,相加所得的图像看起来并不自然。
● 使用函数cv2.add()计算图像像素值的和时,将和大于255的值处理为饱和值255。图像像素值相加后让图像的像素值增大了,图像整体变亮。
win10+Python3.7.3+OpenCV3.4.1入门学习(三)————3.1图像加法运算_第2张图片win10+Python3.7.3+OpenCV3.4.1入门学习(三)————3.1图像加法运算_第3张图片win10+Python3.7.3+OpenCV3.4.1入门学习(三)————3.1图像加法运算_第4张图片

你可能感兴趣的:(Python-OpenCV,python-opencv,图像处理,图像加法运算)