图像的加减法与按位运算
两张素材:
普通加减法
两张同形图像的矩阵进行相加减。或者一张图像的各位置的值加减同一个常数。
符号加减
由于图像载入时,矩阵的dtype自动被设置为np.uint8
,故矩阵的元素值范围始终在[0,255]之间。
+
-
符号的运算规则是:
a
+
b
=
{
a
+
b
a
+
b
≤
255
m
o
d
(
a
+
b
,
256
)
a
+
b
>
255
a+b= \begin{cases} a+b & a+b\le 255 \\ mod(a+b,256) & a+b>255 \end{cases}
a+b={a+bmod(a+b,256)a+b≤255a+b>255
a − b = { a − b a − b ≥ 0 m o d ( a − b , 256 ) a + b < 0 a-b= \begin{cases} a-b & a-b\ge 0\\ mod(a-b,256) & a+b<0 \end{cases} a−b={a−bmod(a−b,256)a−b≥0a+b<0
其中mod
代表取模运算
import cv2
import numpy as np
# 导入图像
image1 = cv2.imread("./monalisa.png")
image2 = cv2.imread("./mask.png")
# 建立窗口
cv2.namedWindow("add1", cv2.WINDOW_NORMAL | cv2.WINDOW_KEEPRATIO)
cv2.namedWindow("add2", cv2.WINDOW_NORMAL | cv2.WINDOW_KEEPRATIO)
cv2.namedWindow("add3", cv2.WINDOW_NORMAL | cv2.WINDOW_KEEPRATIO)
cv2.namedWindow("sub1", cv2.WINDOW_NORMAL | cv2.WINDOW_KEEPRATIO)
cv2.namedWindow("sub2", cv2.WINDOW_NORMAL | cv2.WINDOW_KEEPRATIO)
cv2.namedWindow("sub3", cv2.WINDOW_NORMAL | cv2.WINDOW_KEEPRATIO)
# 操作
add1=image1+image2
add2=image1+image1
add3=image1+120
sub1=image1-image2
sub2=image2-image1
sub3=image1-120
# 显示图像
cv2.imshow("add1", add1)
cv2.imshow("add2", add2)
cv2.imshow("add3", add3)
cv2.imshow("sub1", sub1)
cv2.imshow("sub2", sub2)
cv2.imshow("sub3", sub3)
key = chr(cv2.waitKey())
if key == "1":
print("图像显示结束")
cv2.destroyAllWindows()
函数加减
cv2.add(src1, src2)
cv2.subtract(src1, src2)
与符号加减有所不同的是,到达255和0的临界点后,值会保持这个临界点。
运算规则:
a
+
b
=
{
a
+
b
a
+
b
≤
255
255
a
+
b
>
255
a+b= \begin{cases} a+b & a+b\le 255 \\ 255 & a+b>255 \end{cases}
a+b={a+b255a+b≤255a+b>255
a − b = { a − b a − b ≥ 0 0 a + b < 0 a-b= \begin{cases} a-b & a-b\ge 0\\ 0 & a+b<0 \end{cases} a−b={a−b0a−b≥0a+b<0
import cv2
import numpy as np
# 导入图像
image1 = cv2.imread("./monalisa.png")
image2 = cv2.imread("./mask.png")
# 建立窗口
cv2.namedWindow("add1", cv2.WINDOW_NORMAL | cv2.WINDOW_KEEPRATIO)
cv2.namedWindow("add2", cv2.WINDOW_NORMAL | cv2.WINDOW_KEEPRATIO)
cv2.namedWindow("add3", cv2.WINDOW_NORMAL | cv2.WINDOW_KEEPRATIO)
cv2.namedWindow("sub1", cv2.WINDOW_NORMAL | cv2.WINDOW_KEEPRATIO)
cv2.namedWindow("sub2", cv2.WINDOW_NORMAL | cv2.WINDOW_KEEPRATIO)
cv2.namedWindow("sub3", cv2.WINDOW_NORMAL | cv2.WINDOW_KEEPRATIO)
# 操作
add1=cv2.add(image1,image2)
add2=cv2.add(image1,image1)
add3=cv2.add(image1,120)
sub1=cv2.subtract(image1,image2)
sub2=cv2.subtract(image2,image1)
sub3=cv2.subtract(image1,120)
# 显示图像
cv2.imshow("add1", add1)
cv2.imshow("add2", add2)
cv2.imshow("add3", add3)
cv2.imshow("sub1", sub1)
cv2.imshow("sub2", sub2)
cv2.imshow("sub3", sub3)
key = chr(cv2.waitKey())
if key == "1":
print("图像显示结束")
cv2.destroyAllWindows()
图像加权和
图像加权和,指的是在进行图像像素相加时,给予图像不同的权重,起到"融合"的效果:
d
s
t
=
s
r
c
1
×
α
+
s
r
c
2
×
β
+
γ
dst=src1\times\alpha +src2\times\beta+\gamma
dst=src1×α+src2×β+γ
其中,
α
\alpha
α、
β
\beta
β 分别是图像src1
,src2
的权重 ,
γ
\gamma
γ 用以调节亮度
对应的函数为:
dst=cv2.addWeighted(src1, alpha, src2, beta, gamma)
如:
import cv2
import numpy as np
# 导入图像
image1 = cv2.imread("./monalisa.png")
image2 = cv2.imread("./mask.png")
# 建立窗口
cv2.namedWindow("add1", cv2.WINDOW_NORMAL | cv2.WINDOW_KEEPRATIO)
cv2.namedWindow("add2", cv2.WINDOW_NORMAL | cv2.WINDOW_KEEPRATIO)
cv2.namedWindow("add3", cv2.WINDOW_NORMAL | cv2.WINDOW_KEEPRATIO)
# 操作
add1=cv2.addWeighted(image1,0.6,image2,0.4,4)
add2=cv2.addWeighted(image1,0.85,image2,0.15,4)
add3=cv2.addWeighted(image1,0.6,image2,0.4,40)
# 显示图像
cv2.imshow("add1", add1)
cv2.imshow("add2", add2)
cv2.imshow("add3", add3)
key = chr(cv2.waitKey())
if key == "1":
print("图像显示结束")
cv2.destroyAllWindows()
按位运算
按位运算,指的是将两个数字转化为二进制,再进行一位一位的逻辑运算(与,或,非,异或),最后将结果再转化回十进制
按位与
基本规则:
0 | 1 | |
0 | 0 | 0 |
1 | 0 | 1 |
全真为真,其余为假
推论:
- 任何一个8位二进制数与11111111(十进制的255)进行按位与运算,结果是它本身
- 任何一个8位二进制数与00000000(十进制的0)进行按位与运算,结果是它本身
如 163 & 124
163二进制为:10100011
124二进制为:01111100
按位与结果为:00100000 ,转化为十进制为32
即163 & 124=32
cv2.bitwise_and(src1,src2)
根据推论,效果是与255对应的位置像素值不变,与0对应的位置变为0
如:
import cv2
import numpy as np
# 导入图像
image1 = cv2.imread("./monalisa.png")
image2 = np.zeros(image1.shape,dtype=np.uint8)
image2[50:220,110:230]=[255,255,255]
# 建立窗口
cv2.namedWindow("image1", cv2.WINDOW_NORMAL | cv2.WINDOW_KEEPRATIO)
cv2.namedWindow("image2", cv2.WINDOW_NORMAL | cv2.WINDOW_KEEPRATIO)
cv2.namedWindow("bit and", cv2.WINDOW_NORMAL | cv2.WINDOW_KEEPRATIO)
# 操作
bitand=cv2.bitwise_and(image1,image2)
# 显示图像
cv2.imshow("image1",image1)
cv2.imshow("image2",image2)
cv2.imshow("bit and", bitand)
key = chr(cv2.waitKey())
if key == "1":
print("图像显示结束")
cv2.destroyAllWindows()
按位或
基本规则:
0 | 1 | |
0 | 0 | 1 |
1 | 1 | 1 |
有真为真,无真为假
如 163 | 124
163二进制为:10100011
124二进制为:01111100
按位或结果为:11111111 ,转化为十进制为255
即163 | 124=255
cv2.bitwise_or(src1,src2)
按位非
基本规则:
结果 | |
0 | 1 |
1 | 0 |
如,~163
163二进制为:10100011
按位非结果为:01011100,转化为十进制为92
即~163=92
cv2.bitwise_not(src)
按位异或
基本规则:
0 | 1 | |
0 | 0 | 1 |
1 | 1 | 0 |
又称半加运算,不进位的二进制加法
推论:
- 某个数与同一个数连续进行两次按位异或运算,得到的还是它本身。
如 163 ^ 124
163二进制为:10100011
124二进制为:01111100
按位异或结果为:11011111 ,转化为十进制为223
即163 ^ 124=223
223与124再次按位异或:10100011
即163本身
cv2.bitwise_xor(src1,src2)
一张图片与另一张图片连续进行两次按位异或,得到的是本身(可用于加密)
import cv2
import numpy as np
# 导入图像
image1 = cv2.imread("./monalisa.png")
image2 = np.random.randint(0,255,image1.shape,dtype=np.uint8)
# 建立窗口
cv2.namedWindow("image1", cv2.WINDOW_NORMAL | cv2.WINDOW_KEEPRATIO)
cv2.namedWindow("image2", cv2.WINDOW_NORMAL | cv2.WINDOW_KEEPRATIO)
cv2.namedWindow("bit xor 1", cv2.WINDOW_NORMAL | cv2.WINDOW_KEEPRATIO)
cv2.namedWindow("bit xor 2", cv2.WINDOW_NORMAL | cv2.WINDOW_KEEPRATIO)
# 操作
a=cv2.bitwise_xor(image1,image2)
b=cv2.bitwise_xor(a,image2)
# 显示图像
cv2.imshow("image1",image1)
cv2.imshow("image2",image2)
cv2.imshow("bit xor 1", a)
cv2.imshow("bit xor 2", b)
key = chr(cv2.waitKey())
if key == "1":
print("图像显示结束")
cv2.destroyAllWindows()