四、图像的算术与位运算
1、算术运算
图像的算术运算包含:图像的加法运算、图像的减法运算、图像的乘法运算以及图像的除法运算,下面将一一介绍。
1.1 加法
OpenCV使用 add() 来执行图像的加法运算,add()
用法如下所示:
cv2.add(src1, src2)
参数说明:
- src1, src2:进行加法运算的两张图像。
注意1: 图片就是矩阵,图片的加法运算就是矩阵的加法运算,这就要求加法运算的两张图像的shape必须是相同的。
print(cat.shape) print(dog.shape)
(480, 640, 3) (480, 640, 3)
注意2:如果不相同,则可以使用切片的方法使之相同:
big_dog = cv2.imread('../resource/big.jpg') print(big_dog.shape) big_dog = big_dog[0:480, 0:640] print(big_dog.shape)
(2832, 4240, 3) (480, 640, 3)
代码实现:
import cv2 import numpy as np cat = cv2.imread('../resource/r_cat.jpg') dog = cv2.imread('../resource/r_dog.jpg') cat_dog = cv2.add(cat, dog) cv2.imshow('cat_dog_1', np.hstack((cat, dog))) cv2.imshow('cat_dog_2', cat_dog) cv2.waitKey(0) cv2.destroyAllWindows()
原图像:
加法运算之后的图像:
注意3: add() 加法操作就是将两个图像对应位置的元素相加,如果超过255,则全部变成255。
print(cat[:1, :1]) print(dog[:1, :1]) print(cat_dog[:1, :1])
[[[155 154 156]]] [[[156 110 0]]] [[[255 255 156]]]
注意4: 图像还可以和单个数字进行运算:
print(cat[:2, :2]) cat += 100 cv2.imshow('cat+100', cat) print(cat[:2, :2])
[[[155 154 156] [155 154 156]] [[157 156 158] [158 157 159]]] # + 100 之后 [[[255 254 0] [255 254 0]] [[ 1 0 2] [ 2 1 3]]]
每个元素和100进行加法运算,超过255的数字,会被截断,相当于 % 256
1.2 减法
OpenCV使用 subtract() 来执行图像的减法运算,subtract()
用法如下所示:
cv2.subtract(src1, src2)
参数说明:
- src1, src2:进行减法运算的两张图像。(含义是 src1 - src2)
import cv2 cat = cv2.imread('../resource/r_cat.jpg') dog = cv2.imread('../resource/r_dog.jpg') cat_dog = cv2.subtract(cat, dog) cv2.imshow('cat-dog', cat_dog) cv2.waitKey(0) cv2.destroyAllWindows()
对应位置的元素相减,减完若小于0,则统一变成0。
print(cat[:2, :2]) print(dog[:2, :2]) print(cat_dog[:2, :2])
[[[155 154 156] [155 154 156]] [[157 156 158] [158 157 159]]] [[[156 110 0] [157 111 0]] [[156 110 0] [157 111 0]]] # cat - dog [[[ 0 44 156] [ 0 43 156]] [[ 1 46 158] [ 1 46 159]]]
1.3 乘法
OpenCV使用 multiply() 来执行图像的乘法运算,multiply()
用法如下所示:
cv2.multiply(src1, src2)
参数说明:
- src1, src2:进行乘法运算的两张图像。
import cv2 cat = cv2.imread('../resource/r_cat.jpg') dog = cv2.imread('../resource/r_dog.jpg') cat_dog = cv2.multiply(cat, dog) cv2.imshow('cat-dog', cat_dog) cv2.waitKey(0) cv2.destroyAllWindows()
1.4 除法
OpenCV使用 divide() 来执行图像的除法运算,divide()
用法如下所示:
cv2.divide(src1, src2)
参数说明:
- src1, src2:进行除法运算的两张图像。
import cv2 cat = cv2.imread('../resource/r_cat.jpg') dog = cv2.imread('../resource/r_dog.jpg') cat_dog = cv2.divide(cat, dog) cv2.imshow('cat-dog', cat_dog) cv2.waitKey(0) cv2.destroyAllWindows()
2、图像的融合
图像的融合操作相当于对图像进行线性运算:w1 * x1 + w2 * x2 + b
addWeighted()
用法:
cv2.addWeighted(src1, alpha, src2, beta, gamma)
参数说明:
- src1, src2:进行操作的图像
- alpha, beta:权重参数
- gamma:偏差(静态权重)
import cv2 cat = cv2.imread('../resource/r_cat.jpg') dog = cv2.imread('../resource/r_dog.jpg') cat_dog = cv2.addWeighted(cat, 0.3, dog, 0.7, 0) cv2.imshow('cat-dog', cat_dog) cv2.waitKey(0) cv2.destroyAllWindows()
3、位运算
3.1 非
bitwise_not()
用法:
cv2.bitwise_not(src)
参数说明:
- src:进行操作的图像
import cv2 import numpy as np # 黑色 img1 = np.zeros((480, 640), np.uint8) # 白色 img1[120:360, 160:480] = 255 img_not = cv2.bitwise_not(img1) cv2.imshow('img', np.hstack((img1, img_not))) cv2.waitKey(0) cv2.destroyAllWindows()
3.2 与
bitwise_and()
用法:
cv2.bitwise_and(src1, src2)
参数说明:
- src1, src2:进行操作的图像
import cv2 import numpy as np img1 = np.zeros((480, 640), np.uint8) img2 = np.zeros((480, 640), np.uint8) img1[0:360, 0:480] = 255 img2[120:480, 160:640] = 255 img_and = cv2.bitwise_and(img1, img2) cv2.imshow('img1 img2', np.hstack((img1, img2))) cv2.imshow('img_and', img_and) cv2.waitKey(0) cv2.destroyAllWindows()
原图像:
与操作之后图像:
3.3 或
bitwise_or()
用法:
cv2.bitwise_or(src1, src2)
参数说明:
- src1, src2:进行操作的图像
import cv2 import numpy as np img1 = np.zeros((480, 640), np.uint8) img2 = np.zeros((480, 640), np.uint8) img1[0:360, 0:480] = 255 img2[120:480, 160:640] = 255 img_or = cv2.bitwise_or(img1, img2) cv2.imshow('img1 img2', np.hstack((img1, img2))) cv2.imshow('img_or', img_or) cv2.waitKey(0) cv2.destroyAllWindows()
原图像:
或操作之后图像:
3.4 异或
bitwise_xor()
用法:
cv2.bitwise_xor(src1, src2)
参数说明:
- src1, src2:进行操作的图像
import cv2 import numpy as np img1 = np.zeros((480, 640), np.uint8) img2 = np.zeros((480, 640), np.uint8) img1[0:360, 0:480] = 255 img2[120:480, 160:640] = 255 img_xor = cv2.bitwise_xor(img1, img2) cv2.imshow('img1 img2', np.hstack((img1, img2))) cv2.imshow('img_xor', img_xor) cv2.waitKey(0) cv2.destroyAllWindows()
原图像:
异或操作之后图像:
4、制作LOGO
要求:制作一个LOGO,并使其贴在某图像上。
import cv2 import numpy as np # 导入图像 dog = cv2.imread('../resource/r_dog.jpg') # 创建LOGO logo = np.zeros((200, 200, 3), np.uint8) # 绘制LOGO logo[20:120, 20:120] = [0, 0, 255] logo[80:180, 80:180] = [0, 255, 0] # 掩码 mask = np.zeros((200, 200), np.uint8) mask[20:120, 20:120] = 255 mask[80:180, 80:180] = 255 # cv2.imshow('mask', mask) m = cv2.bitwise_not(mask) # cv2.imshow('m', m) # 选择dog添加LOGO的位置 roi = dog[0:200, 0:200] # roi与m进行与操作,先roi和roi做与运算,然后结果再和mask做与运算,如果与的结果是True,那么返回原图的像素,否则返回0 tmp = cv2.bitwise_and(roi, roi, mask=m) # cv2.imshow('tmp', tmp) dst = cv2.add(tmp, logo) # cv2.imshow('dst', dst) # 在dog上还原 dog[:200, :200] = dst cv2.imshow('dog', dog) # cv2.imshow('LOGO', logo) cv2.waitKey(0) cv2.destroyAllWindows()