如果需要处理的原图及代码,请移步小编的GitHub地址
传送门:请点击我
如果点击有误:https://github.com/LeBron-Jian/ComputerVisionPractice
在OpenCV中我们经常会遇到一个名字:Mask(掩膜)。很多函数都使用到它,那么这个Mask到底是什么呢,下面我们从图像基本运算开始,一步一步学习掩膜。
1,图像算术运算
图像的算术运算有很多种,比如两幅图像可以相加,相减,相乘,相除,位运算,平方根,对数,绝对值等;图像也可以放大,缩小,旋转,还可以截取其中的一部分作为ROI(感兴趣区域)进行操作,各个颜色通道还可以分别提取对各个颜色通道进行各种运算操作。总之,对图像可以进行的算术运算非常的多。这里先学习图片间的数学运算,图像混合,按位运算。
1.1 图片加法
要叠加两张图片,可以用 cv2.add() 函数,相加两幅图片的形状(高度/宽度/通道数)必须相同, numpy中可以用 res = img1 + img2 相加,但这两者的结果并不相同。
x = np.uint8([250])
y = np.uint8([10])
print(cv2.add(x, y)) # 250+10 = 260 => 255
print(x + y) # 250+10 = 260 % 256 = 4
如果是二值化图片(只有0和255),两者结果是一样的(用 numpy的方式更简便一些)。
这里我们代入图像中看一下:
#encoding:utf-8
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 举一个极端的例子,真的只是运气好,遇到了。。。。
img = cv2.imread('lena.jpg')
img_add = img + 10
img_add2 = cv2.add(img, img_add)
print(img[0:4, :, 0])
print(img_add[0:4, :, 0])
print(img_add2[0:4, :, 0])
'''
这个是 logo1.jpg 的效果
[[246 246 246 ... 246 246 246]
[246 246 246 ... 246 246 246]
[246 246 246 ... 246 246 246]
[246 246 246 ... 246 246 246]]
[[0 0 0 ... 0 0 0]
[0 0 0 ... 0 0 0]
[0 0 0 ... 0 0 0]
[0 0 0 ... 0 0 0]]
[[246 246 246 ... 246 246 246]
[246 246 246 ... 246 246 246]
[246 246 246 ... 246 246 246]
[246 246 246 ... 246 246 246]]
这个是 lena.jpg 的效果
[[126 125 124 ... 128 120 90]
[127 126 124 ... 135 131 96]
[124 123 121 ... 144 138 96]
[116 119 116 ... 73 56 35]]
[[136 135 134 ... 138 130 100]
[137 136 134 ... 145 141 106]
[134 133 131 ... 154 148 106]
[126 129 126 ... 83 66 45]]
[[255 255 255 ... 255 250 190]
[255 255 255 ... 255 255 202]
[255 255 252 ... 255 255 202]
[242 248 242 ... 156 122 80]]
# 我们发现 使用numpy库的加法,则运算结果取模
使用opencv的add()函数,则运算结果当大于255,则取255
'''
注意:OpenCV中的加法与Numpy的加法是有所不同的,OpenCV的加法是一种饱和操作,而Numpy的加法是一种模操作。
Numpy库的加法
其运算方法是:目标图像 = 图像1 + 图像2,运算结果进行取模运算
当像素值 小于等于 255 时,结果为:“图像1 + 图像2”,例如:120+48=168
当像素值 大于255 时,结果为:对255取模的结果,例如:(255 + 64) % 255 = 64
OpenCV的加法
其运算方法是:目标图像 = cv2.add(图像1, 图像2)
当像素值 小于等于 255 时,结果为:“图像1 + 图像2”,例如:120+48=168
当像素值 大于255 时,结果为:255,例如:255 + 64 = 255
两种方法对应的代码如下:
# encoding:utf-8
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 读取图片
img = cv2.imread('logo1.jpg')
test = img
# 方法一:Numpy加法运算
result1 = img + test
# 方法二:OpenCV加法运算
result2 = cv2.add(img, test)
all_pic = np.column_stack((img, result1, result2))
# 显示图像
cv2.imshow('img result1 result2', all_pic)
# cv2.imshow("original", img)
# cv2.imshow("result1", result1)
# cv2.imshow("result2", result2)
# 等待显示
cv2.waitKey(0)
cv2.destroyAllWindows()
原图及其效果图如下:
其中,result1为Numpy的方法,result2为OpenCV的方法。
1.2 图像混合
图像融合通常是指将2张或者两张以上的图像信息融合到1张图像上,融合的图像含有更多的信息,能够更方便人们观察或计算机处理。
图像融合是在图像加法的基础上增加了系数和亮度调节量。
图像融合:目标图像 = 图像1*系数1 + 图像2*系数2 + 亮度调节量
图像混合 cv2.addWeighted() 也是一种图片相加的操作,只不过两幅图片的权重不一样, y 相当于一个修正值:
dst = α*img1 + β*img2 + γ
PS:当 alpha 和 beta 都等于1,则相当于图片相加。
代码如下:
import cv2
import numpy as np
img1 = cv2.imread('lena_small.jpg')
img2 = cv2.imread('opencv_logo_white.jpg')
# print(img1.shape, img2.shape) # (187, 186, 3) (184, 193, 3)
img2 = cv2.resize(img2, (186, 187))
# print(img1.shape, img2.shape)
res = cv2.addWeighted(img1, 0.6, img2, 0.4, 0)
cv2.imshow("res", res)
cv2.waitKey(0)
cv2.destroyAllWindows()
注意这里,两张图片的尺寸必须一致。原图和结果图如下:
1.3 图像矩阵减法
图像矩阵减法与加法其实类似,我们这不多做说明,只贴函数:
函数原型:cv2.subtract(src1, src2, dst=None, mask=None, dtype=None)
src1:图像矩阵1
src1:图像矩阵2
dst:默认选项
mask:默认选项
dtype:默认选项
1.4 按位运算
按位操作有:AND ,OR, NOT,XOR 等。cv2.bitwise_and(), cv2.bitwise_not(), cv2.bitwise_or(), cv2.bitwise_xor()分别执行按位与/或/非/异或运算。下面我们贴一下opencv中的函数
bitwise_or—图像或运算
函数原型:cv2.bitwise_or(src1, src2, dst=None, mask=None)
src1:图像矩阵1
src1:图像矩阵2
ds