opencv基础09-图像运算
什么是图像运算?
在图像处理过程中,经常需要对图像进行加法运算。可以通过加号运算符“+”对图像进行加法运算,也可以通过 cv2.add()函数对图像进行加法运算。
通常情况下,在灰度图像中,像素用 8 个比特位(一个字节)来表示,像素值的范围是[0,255]。
两个像素值在进行加法运算时,求得的和很可能超过 255。上述两种不同的加法运算方式,对超过 255 的数值的处理方式是不一样的。
图像运算能干嘛?
图像运算是指对图像进行各种数学和逻辑操作的过程,可以用于许多功能场景。以下是一些图像运算在不同功能场景下的应用:
图像增强和预处理:图像运算可以用于增强和预处理图像,如对比度增强、亮度调整、颜色校正、噪声去除、图像平滑和锐化等。这在图像处理、计算机视觉和图像分析中常用于提高图像质量和准确性。
特征提取和描述符:图像运算可用于提取图像中的特征和描述符,如边缘检测、角点检测、纹理分析和形状描述等。这在目标检测、图像匹配、物体识别和图像检索等领域中非常重要。
图像分割和区域提取:图像运算可以用于图像分割和区域提取,如阈值分割、基于边缘的分割、区域增长和分水岭算法等。这在图像分析、计算机视觉和医学图像处理中常用于提取感兴趣的区域和物体。
图像合成和融合:图像运算可以用于图像合成和融合,如图像叠加、混合模式、泊松融合和全景图像拼接等。这在图像合成、图像编辑和增强现实等应用中常用于创建合成图像和增强效果。
图像变换和几何操作:图像运算可以用于图像的变换和几何操作,如图像缩放、旋转、平移、仿射变换和透视变换等。这在图像配准、图像校正和图像变换等领域中非常有用。
图像分析和模式识别:图像运算可以用于图像分析和模式识别任务,如形状识别、运动分析、纹理分类和目标跟踪等。这在计算机视觉、机器学习和人工智能等领域中广泛应用。
图像压缩和编码:图像运算可以用于图像压缩和编码,如基于变换的压缩、预测编码和无损压缩等。这在数字图像传输、存储和通信中常用于减小图像文件大小和提高传输效率。
总而言之,图像运算在图像处理、计算机视觉、图像分析和模式识别等领域具有广泛的应用。它们可以用于处理、增强、分析和理解图像,从而实现不同的功能和应用场景。
加号运算符
使用加号运算符“+”对图像 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。
当然,上述公式也可以简化为𝑎 + 𝑏 = mod(𝑎 + 𝑏, 256),在运算时无论相加的和是否大于255,都对数值 256 取模。
示例
使用随机数数组模拟灰度图像,观察使用“+”对像素值求和的结果。
分析:通过将数组的数值类型定义为 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=
[[ 86 14 150]
[ 29 157 182]
[153 51 205]]
img2=
[[140 47 210]
[225 104 35]
[ 20 42 7]]
img1+img2=
[[226 61 104]
[254 5 217]
[173 93 212]]
从上述程序可以看到,使用“+”计算两个 256 级灰度图像内像素值的和时,运算结果会
对 256 取模。
需要注意,本例题中的加法要进行取模,这是由数组的类型 dtype=np.uint8 所规定的。
cv2.add()函数
函数 cv2.add()可以用来计算图像像素值相加的和,其语法格式为:
计算结果=cv2.add(像素值 a,像素值 b)
使用函数 cv2.add()对像素值 a 和像素值 b 进行求和运算时,会得到像素值对应图像的饱和值(最大值)。
例如,8 位灰度图像的饱和值为 255,因此,在对 8 位灰度图的像素值求和时,遵循以下规则:
根据上述规则,在 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 个参数是数值,此时将超过图像饱和值的数值处理为饱和值(最大值)。
形式2,3 看着有点蒙,我们直接上代码看效果
形式1 示例代码:
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=
[[ 80 210 173]
[112 85 13]
[158 230 45]]
img2=
[[ 9 221 81]
[255 2 127]
[124 147 9]]
cv2.add(img1,img2)=
[[ 89 255 254]
[255 87 140]
[255 255 54]]
形式2 示例代码:
import numpy as np
import cv2
#读取图像,并以灰度图像的方式显示,参数为0
a = cv2.imread("lena.png",0)
# 将图像转换为NumPy数组
image_np = np.array(a)
print("image_np=\n",image_np)
cv2.imshow("original",a)
#对图像进行加法运算
result2=cv2.add(100,a)
image_np_r = np.array(result2)
print("image_np_r=\n",image_np_r)
cv2.imshow("result2",result2)
cv2.waitKey()
cv2.destroyAllWindows()
像素值运算结果:
image_np=
[[139 144 141 ... 103 103 103]
[142 143 140 ... 105 105 105]
[144 137 145 ... 105 103 102]
...
[117 119 123 ... 50 50 50]
[115 118 119 ... 50 50 53]
[109 116 117 ... 50 53 56]]
image_np_r=
[[239 244 241 ... 203 203 203]
[242 243 240 ... 205 205 205]
[244 237 245 ... 205 203 202]
...
[217 219 223 ... 150 150 150]
[215 218 219 ... 150 150 153]
[209 216 217 ... 150 153 156]]
从结果看图片所有的像素点都加了100,
运行显示效果:
形式3 示例代码:
import numpy as np
import cv2
#读取图像,并以灰度图像的方式显示,参数为0
a = cv2.imread("lena.png",0)
cv2.imshow("original",a)
#对图像进行加法运算
result2=cv2.add(a,100)
cv2.imshow("result2",result2)
cv2.waitKey()
cv2.destroyAllWindows()
运行效果:
发现亮度也提高了
更多效果自己多实验,看代码是看不出所以然的