图片就是矩阵,图片的加法运算就是矩阵的加法运算,这就要求加法运算的两张图片的shape必须是相同的。
# 图片加法
import cv2
import numpy as np
# 读取图片
cat = cv2.imread('./cat.jpg') # shape (100, 100, 3)
dog = cv2.imread('./dog.jpg') # shape (100, 100, 3)
# 加法要求两张图片大小一致
print(cat.shape)
print(dog.shape)
# 在做加法之前需要把图片的形状变为一致
# 可以通过ndarray的切片方式取出完全一样的形状
# 从0切到100可以用[0:100]或[:100]左闭右开
new_cat = cat[:100, :100]
# cv2.add 加法操作要求两个图片的长宽、通道数相同
new_img = cv2.add(new_cat, dog)
cv2.imshow('img', np.hstack((new_cat, dog, new_img)))
cv2.waitKey(0)
cv2.destroyAllWindows()
add的规则就是两个图对应位置的元素相加,如果超过255,则回滚至255。
图片还可以和单个数字进行运算:
# 单个数值加减
import cv2
import numpy as np
cat = cv2.imread('./cat.jpg') # shape (100, 100, 3)
dog = cv2.imread('./dog.jpg') # shape (100, 100, 3)
# 超出255的值,会使用 (dog + 100) % 255 来计算
new_dog = dog + 100
cv2.imshow('img', np.hstack((dog, new_dog)))
cv2.waitKey(0)
cv2.destroyAllWindows()
# 图片减法
import cv2
import numpy as np
# 读取图片
cat = cv2.imread('./cat.jpg')
dog = cv2.imread('./dog.jpg')
new_img = cv2.subtract(cat, dog)
cv2.imshow('img', np.hstack((cat, dog, new_img)))
cv2.waitKey(0)
cv2.destroyAllWindows()
subtract的规则就是两个图对应位置的元素相减,如果小于0,则回滚至0。
# 图片乘法
import cv2
import numpy as np
# 读取图片
cat = cv2.imread('./cat.jpg')
dog = cv2.imread('./dog.jpg')
new_img = cv2.multiply(cat, dog)
cv2.imshow('img', np.hstack((cat, dog, new_img)))
cv2.waitKey(0)
cv2.destroyAllWindows()
# 图片除法
import cv2
import numpy as np
# 读取图片
cat = cv2.imread('./cat.jpg')
dog = cv2.imread('./dog.jpg')
new_img = cv2.divide(cat, dog)
cv2.imshow('img', np.hstack((cat, dog, new_img)))
cv2.waitKey(0)
cv2.destroyAllWindows()
α∗img1+β∗img2+γ\alpha * img_1 + \beta * img_2 + \gamma α∗img1+β∗img2+γ
# 图像的融合
# 不是简单的加法运算,相当于将图片进行了一次线性运算
# 通过调整图片的权重来调整融合图片中哪一张图所占的比重更大一些
import cv2
import numpy as np
cat = cv2.imread('./cat.jpg')
dog = cv2.imread('./dog.jpg')
new_img = cv2.addWeighted(cat, 0.4, dog, 0.6, 0)
cv2.imshow('img', np.hstack((cat, dog, new_img)))
cv2.waitKey(0)
cv2.destroyAllWindows()
# OpenCV的逻辑运算 —— 与或非 异或
# OpenCV中的逻辑运算就是对应位置的元素进行 与或非 异或 运算
import cv2
import numpy as np
cat = cv2.imread('./cat.jpg')
dog = cv2.imread('./dog.jpg')
# 非操作
cat_not = cv2.bitwise_not(cat)
cv2.imshow('not', np.hstack((cat, cat_not)))
print(cat[:2, :2])
print(cat_not[:2, :2])
cv2.waitKey(0)
cv2.destroyAllWindows()
非运算的本质就是用255去做减法得到黑白反转的图片:
output >>
[[[25 29 30]
[42 46 47]]
[[30 33 37]
[41 46 47]]]
[[[230 226 225]
[213 209 208]]
[[225 222 218]
[214 209 208]]]
# 与操作
# 204 & 213 二进制后逻辑运算再转为十进制
# OpenCV中的非,0反过来是255
import cv2
import numpy as np
cat = cv2.imread('./cat.jpg')
dog = cv2.imread('./dog.jpg')
cat_and = cv2.bitwise_and(cat, dog)
cv2.imshow('not', np.hstack((cat, dog, cat_and)))
cv2.waitKey(0)
cv2.destroyAllWindows()
与操作的结果永远小于等于两个数,所以与操作后图片颜色会整体变暗。
# 或操作
import cv2
import numpy as np
cat = cv2.imread('./cat.jpg')
dog = cv2.imread('./dog.jpg')
cat_or = cv2.bitwise_or(cat, dog)
cv2.imshow('not', np.hstack((cat, dog, cat_or)))
cv2.waitKey(0)
cv2.destroyAllWindows()
或操作的结果永远大于等于两个数,所以与操作后图片颜色会整体变亮,超过255则回滚至255。
# 异或操作
import cv2
import numpy as np
cat = cv2.imread('./cat.jpg')
dog = cv2.imread('./dog.jpg')
cat_xor = cv2.bitwise_xor(cat, dog)
cv2.imshow('not', np.hstack((cat, dog, cat_xor)))
cv2.waitKey(0)
cv2.destroyAllWindows()
# 图像的放大与缩小
import cv2
import numpy as np
# 导入图片
dog = cv2.imread('./dog.jpg')
# x,y放大1.5倍
new_dog = cv2.resize(dog, dsize=(150, 150), interpolation=cv2.INTER_NEAREST)
new_dog2 = cv2.resize(dog, (150, 150), interpolation=cv2.INTER_LINEAR) # 默认效果
new_dog3 = cv2.resize(dog, (150, 150), interpolation=cv2.INTER_CUBIC)
new_dog4 = cv2.resize(dog, (150, 150), interpolation=cv2.INTER_AREA)
# 横向纵向拉伸
new_dog_xy = cv2.resize(dog, dsize=None, fx=0.5, fy=0.5, interpolation=cv2.INTER_LINEAR)
cv2.imshow('dog', np.hstack((new_dog, new_dog2, new_dog3, new_dog4)))
cv2.imshow('dog_xy', new_dog_xy)
cv2.waitKey(0)
cv2.destroyAllWindows()
例题:
import cv2
import numpy as np
# 导入图片
dog = cv2.imread('./dog.jpg') # (100, 100, 3)
# 创建LOGO,两个纯色矩形
logo = np.zeros((80, 80, 3), np.uint8)
# 绘制LOGO
logo[10:30, 10:30] = [0,0,255] # 红
logo[20:40, 20:40] = [0,255,0] # 绿
# 构造掩码 mask 作为一个抠取部分来抠取LOGO
mask = np.zeros((80, 80), np.uint8)
mask[10:30, 10:30] = 255
mask[20:40, 20:40] = 255
m = cv2.bitwise_not(mask)
cv2.imshow('logo_mask', np.hstack((mask, m)))
# 选取dog添加LOGO的位置
roi = dog[0:80, 0:80]
# roi与m进行与操作,先roi和roi做与运算,再喝mask做与运算
# 如果结果是True返回原图的像素,否则返回0(255和任何颜色与都是True,0和任何颜色与都是0)
temp = cv2.bitwise_and(roi, roi, mask=m)
# 求和叠加图片
dst = cv2.add(temp, logo)
# 在dog上还原
dog[:80, :80] = dst
cv2.imshow('roi_temp_dst', np.hstack((roi, temp, dst)))
cv2.imshow('result', dog)
cv2.waitKey(0)
cv2.destroyAllWindows()