参考依据
官方教程:
https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_core/py_image_arithmetics/py_image_arithmetics.html
目标
- 学习图像的数学运算操作,比如加、减、位运算等
- 可以学会如下函数:cv2.add(),cv2.addWeighted()等
1. Image Addition 图像相加
对于图像的加法运算一般来说有两种,一个是numpy的加法,也可以理解为dtype=uint8的ndarray加法,还有一种就是opencv的add()函数。这两种方式的区别就在于numpy加法是取模运算,而cv2.add()是饱和运算。
img1 = cv2.imread('SWJTU.jpg', -1)
img1 = cv2.resize(img1, (200, 200))
img2 = cv2.imread('UESTC.jpg', -1)
img2 = cv2.resize(img2, (200, 200))
cv2.imshow('1', img1)
cv2.imshow('2', img2)
img3 = img1 + img2 # 取模运算
cv2.imshow('1+2', img3)
img4 = cv2.add(img1, img2) # 饱和运算
cv2.imshow('add(1,2)', img4)
cv2.waitKey(0)
cv2.destroyAllWindows()
x = np.uint8([255])
y = np.uint8([20])
print(x+y) # 取模运算 (255+20) % 256 = 19
print(cv2.add(x,y)) # 饱和运算 (255+20) -> 255
# [19]
# [[255]]
2. Image Blending 图像融合
这其实也是一种图像的加法操作,只不过在这个加法中,给定了各图像的权重,让人在视觉上能够感受到融合/半透明的效果。cv2.addWeighted()提供了这样的一个接口,计算公式如下:
img = cv2.addWeighted(img1, 0.3, img2, 0.7, 0)
cv2.imshow('addWeight', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
3. Bitwise Operations 位运算操作
位运算操作包含了AND、OR、NOT、XOR等操作,这些位运算操作对我们提取图像的非矩形ROI(Region Of Interst)是非常有效的。并且在有些时候,我们想替换一些图像元素,在某些图像拼接其他的图像,但又不想出现那种半透明的现象,就可以使用位运算。
例如:在一张图像的左上角增加‘UESTC’的Logo
img1 = cv2.resize(cv2.imread('0001.jpg'), (1000, 600))
img2 = cv2.resize(cv2.imread('UESTC.jpg'), (180, 180))
row, col, channels = img2.shape # 获取logo的长、宽、通道值
roi = img1[0:row, 0:col] # 确定图像放置logo的位置(左上角)
# 将logo进行灰度化、二值化
img2gray = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY) # 转换为灰度图
ret, mask = cv2.threshold(img2gray, 180, 255, cv2.THRESH_BINARY_INV) # 阈值函数,用于二值化,
# cv2.threshold具体用法可看文章https://blog.csdn.net/qq_36560894/article/details/106816291
# 返回的mask 即背景为0 前景为1
mask_inv = cv2.bitwise_not(mask) # mask_inv 前景为0 背景为1
# roi 在logo图像的背景区域保持原像素值
roi_bg = cv2.bitwise_and(roi, roi, mask=mask_inv)
# logo的前景区域保持为原像素值
logo = cv2.bitwise_and(img2, img2, mask=mask)
# 进行融合
dst = cv2.add(roi_bg, logo)
img1[0:row, 0:col] = dst
cv2.imshow('img',img1)
cv2.waitKey(0)
cv2.destroyAllWindows()