13. 图像的加法运算(cv2.add)
14. 图像与标量相加(cv2.add)
15. 图像的加权加法(cv2.addWeight)
16. 不同尺寸的图像加法
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 13
img1 = cv2.imread('0.jpg', flags=1)
img2 = cv2.imread('1.jpg', flags=1)
img1 = cv2.resize(img1, (400, 400)) # resize为相同尺寸
img2 = cv2.resize(img2, (400, 400))
img3 = cv2.add(img1, img2) # 饱和运算,大于255的结果为255
img4 = np.add(img1, img2) # 模运算,取余255
plt.subplot(221)
plt.title('img1')
plt.axis('off')
cv2.cvtColor(img1, cv2.COLOR_BGR2RGB)
plt.imshow(img1)
plt.subplot(222)
plt.title('img2')
plt.axis('off')
cv2.cvtColor(img2, cv2.COLOR_BGR2RGB)
plt.imshow(img2)
plt.subplot(223)
plt.title('img3')
plt.axis('off')
cv2.cvtColor(img3, cv2.COLOR_BGR2RGB)
plt.imshow(img3)
plt.subplot(224)
plt.title('img4')
plt.axis('off')
cv2.cvtColor(img4, cv2.COLOR_BGR2RGB)
plt.imshow(img4)
plt.show()
注释:饱和加法以255为上限,所有像素只会变的更白(大于原值);取模加法以255为模,会导致部分像素变黑 (小于原值)。 因此,一般情况下应使用 cv2.add 进行饱和加法操作,不宜使用 numpy 取模加法。
# 14
# 对一张图像与一个标量相加时,则将图像所有像素的各通道值分别与标量(1*3)的各通道值相加
img5 = cv2.imread('test.jpg', flags=1)
img5 = cv2.resize(img5, (400, 400))
value = 100
m = np.ones((1, 3), dtype='float')*100
# m = np.array([1,2,3]) 标量数组也可以自己定义
img6 = cv2.add(img5, value) # 和常数相加
img7 = cv2.add(img5, m) # 和标量相加
for i in range(1, 4):
x, y = i*10, i*10
print('img5[x,y] = {},img6[x,y] = {},img7[x,y] = {}'.format(img5[x, y], img6[x, y], img7[x, y]))
plt.subplot(131)
plt.title('img5')
plt.axis('off')
cv2.cvtColor(img5, cv2.COLOR_BGR2RGB)
plt.imshow(img5)
plt.subplot(132)
plt.title('img5 + constant')
plt.axis('off')
cv2.cvtColor(img6, cv2.COLOR_BGR2RGB)
plt.imshow(img6)
plt.subplot(133)
plt.title('img5 + scalar')
plt.axis('off')
cv2.cvtColor(img7, cv2.COLOR_BGR2RGB)
plt.imshow(img7)
plt.show()
for循环中输出如下:
img5[x,y] = [23 98 90],img6[x,y] = [123 98 90],img7[x,y] = [123 198 190]
img5[x,y] = [22 99 91],img6[x,y] = [122 99 91],img7[x,y] = [122 199 191]
img5[x,y] = [ 30 114 106],img6[x,y] = [130 114 106],img7[x,y] = [130 214 206]
注意 cv2.add() 对图像与标量相加时,“常数” 与 “标量” 的区别:
将图像与一个常数 value 相加,只是将 B 通道即蓝色分量与常数相加,而 G、R 通道的数值不变,因此图像发蓝。
将图像与一个标量 scalar 相加,“标量” 是指一个 1x3 的 numpy 数组,此时 B/G/R 通道分别与数组中对应的常数相加,因此图像发白
# 15
img8 = cv2.imread('0.jpg', flags=1)
img9 = cv2.imread('1.jpg', flags=1)
img8 = cv2.resize(img8, (400, 400)) # resize为相同尺寸
img9 = cv2.resize(img9, (400, 400))
img_aw1 = cv2.addWeighted(img8, 0.2, img9, 0.8, 0)
img_aw2 = cv2.addWeighted(img8, 0.5, img9, 0.5, 0)
img_aw3 = cv2.addWeighted(img8, 0.8, img9, 0.2, 0)
plt.subplot(131)
plt.title('alpha = 0.2,beta = 0.8')
plt.axis('off')
cv2.cvtColor(img_aw1, cv2.COLOR_BGR2RGB)
plt.imshow(img_aw1)
plt.subplot(132)
plt.title('alpha = 0.5,beta = 0.5')
plt.axis('off')
cv2.cvtColor(img_aw2, cv2.COLOR_BGR2RGB)
plt.imshow(img_aw2)
plt.subplot(133)
plt.title('alpha = 0.8,beta = 0.2')
plt.axis('off')
cv2.cvtColor(img_aw3, cv2.COLOR_BGR2RGB)
plt.imshow(img_aw3)
plt.show()
cv2.addWeighted(src1, alpha, src2, beta, gamma[, dst[, dtype]])
对两张相同大小和类型的图像按权重相加,可以实现图像的叠加和混合
dst = src1 * alpha + src2 * beta + gamma
scr1, scr2:ndarray 多维数组,表示一个灰度或彩色图像
alpha:第一张图像 scr1 的权重,通常取为 0~1 之间的浮点数
beta:第二张图像 scr2 的权重,通常取为 0~1 之间的浮点数
gamma: 灰度系数,图像校正的偏移量,用于调节亮度
dtype 输出图像的深度,即每个像素值的位数,可选项,默认等于 src1.depth()
返回值:dst,加权加法运算结果的图像数组
alpha,beta,gamma 可调,可以根据需要调整图像的权重,以达到不同的显示效果。推荐取 beta=1-alpha, gamma=0
# 16
# 对于不同尺寸的图像加法,将小图叠加到大图的指定位置
img_l = cv2.imread('0.jpg', flags=1)
img_s = cv2.imread('test.jpg', flags=1)
x, y = 300, 100 # 叠放的位置
wl, hl = img_l.shape[1::-1]
ws, hs = img_s.shape[1::-1]
if (x+ws) > wl: x = wl - ws # 调整图像叠放位置,避免溢出
if (y+hs) > hl: y = hl - hs
imgCrop = img_l[y:hs+y, x:ws+x] # 裁剪为和小图大小相同
imgAdd = cv2.add(imgCrop, img_s) # 裁剪图和小图叠加
imgAddW = cv2.addWeighted(imgCrop, 0.2, img_s, 0.8, 0.0) # 加权加法,裁剪图和小图叠加
imgAddM = np.array(img_l)
imgAddM[y:hs+y, x:ws+x] = imgAddW # 用叠加小图替换原图 imgL 的叠放位置
cv2.imshow("imgAdd", imgAdd)
cv2.imshow("imgAddW", imgAddW)
cv2.imshow("imgAddM", imgAddM)
cv2.waitKey(0)
关于在shape中取h和w,代码解释如下:
a = np.random.rand(400,300,3)
print(a.shape) # (400,300,3)
print(a.shape[1]) # 400
print(a.shape[1:]) # (300,3)
print(a.shape[1::]) # (300,3)
print(a.shape[:-1]) # (400,300)
print(a.shape[:]) # (400,300,3)
print(a.shape[::]) # (400,300,3)
print(a.shape[::-1]) # (3,300,400)
print(a.shape[1::-1]) # (300,400)