概述
摘要
- 加法运算
- 加权和
- 按位逻辑运算
- 掩模
- 位平面分解
- 加密和解密
- 数字水印
1 加法运算
在图像处理过程中,需要对图片进行加法运算。可以通过运算符+进行加法运算,也可以通过cv2.add()函数进行加法运算。我们以灰度图为例,假设图1中的某一像素值为a,图2中的某一像素值为b。
1.1 运算符+
因为灰度图中的数据类型为uint8,运算符+的运算规则如下:
a + b = { a + b , a + b < 256 m o d ( a + b ) , a + b > 255 a+b=begin{cases} a+b, & a+b<256\ mod(a+b), & a+b>255 end{cases} a+b={a+b,mod(a+b),a+b<256a+b>255
1.2 cv2.add()函数
cv2.add()函数的运算规则如下:
a
+
b
=
{
a
+
b
,
a
+
b
<
256
255
,
a
+
b
>
255
a+b=begin{cases} a+b, & a+b<256\ 255, & a+b>255 end{cases}
a+b={a+b,255,a+b<256a+b>255
我们举一个例子比较运算符+和cv2.add()函数的差别
import cv2
import numpy as np
def add_operator():
image1 = np.ones((4, 4), dtype=np.uint8) * 250
image2 = np.ones((4, 4), dtype=np.uint8)
image3 = np.ones((4, 4), dtype=np.uint8) * 10
image4 = image1 + image2
image5 = image1 + image3
image6 = cv2.add(image1, image2)
image7 = cv2.add(image1, image3)
print("+ operator: n", image4)
print("+ operator: n", image5)
print("cv2.add function: n", image6)
print("cv2.add function: n", image7)
cv2.waitKey(0)
add_operator()
运算结果如下,可以发现:使用+,若两像素点值和超过255会有一个取余的操作,而使用cv2.add()函数,当两点像素点值和超过255时,取255位运算结果。
2 加权和
当两图不是简单相加,而是按一定权重相加时,可调用cv2.addWeighted()函数
addWeighted(src1, alpha, src2, beta, gamma, dst=..., dtype=...)
src1:图1
alpha: 图1的权重
src2:图2
beta:图2的权重
gamma:亮度调节量
计算公式为:
d
s
t
=
s
r
c
1
∗
a
l
p
h
a
+
s
r
c
2
∗
b
e
t
a
+
g
a
m
m
a
dst=src1*alpha+src2*beta+gamma
dst=src1∗alpha+src2∗beta+gamma
举一个例子,将图1帆高和图2阳菜合融合在一起
def weight_add():
fg_img = cv2.imread("fg.jpg")
yc_img = cv2.imread("yc.jpg")
fg_img = cv2.resize(fg_img, dsize=(yc_img.shape[1], yc_img.shape[0]))
cv2.imshow("fg_img", fg_img)
cv2.imshow("yc_img", yc_img)
img = cv2.addWeighted(fg_img, 0.5, yc_img, 1, 1)
cv2.imshow("yc&fg", img)
cv2.waitKey(0)
weight_add()
运行结果为:
3 按位逻辑运算
图片之间的按位逻辑运算有按位与,按位或,按位非,按位异或等,逻辑运算规则如下:
算子1 | 算子2 | 与 | 或 | 非(算子1) | 异或 |
---|---|---|---|---|---|
0 | 0 | 0 | 0 | 1 | 0 |
0 | 1 | 0 | 1 | 1 | 1 |
1 | 0 | 0 | 1 | 0 | 1 |
1 | 1 | 1 | 1 | 0 | 0 |
OpenCV库中有对应的库函数:
- 按位与:cv2.bitwise_and()
- 按位或:cv2.bitwise_or()
- 按位非:cv2.bitwise_not()
- 按位异或:cv2.bitwise_xor()
下面我们举一个例子,随机生成一个4*4的灰度图,分别与0矩阵进行按位与,或,非,异或操作
def logic_operation():
image1 = np.random.randint(0, 256, size=(4, 4), dtype=np.uint8)
image2 = np.zeros((4, 4), dtype=np.uint8)
print("image1: n", image1)
#1 按位与
print("and: n", cv2.bitwise_and(image1, image2))
#2 按位或
print("or: n", cv2.bitwise_or(image1, image2))
#3 按位非
print("not: n", cv2.bitwise_not(image1))
#4 按位异或
print("xor: n", cv2.bitwise_xor(image1, image2))
logic_operation()
运算结果为
我们对image第0行第0列元素(21)进行分析:
21的二进制表示为:0001 0101
00的二进制表示为:0000 0000
与:0000 0000,十进制为0
或:0001 0101,十进制为21
非:1110 1010,十进制为234
异或: 0001 0101,十进制为21
4 掩模
掩模是用选定的图像、图形或物体,对处理的图像(全部或局部)进行遮挡,来控制图像处理的区域或处理过程。掩模中为0的部分表示遮挡的部分,掩模中为1的部分表示感兴趣或需要处理的部分。
以cv2.add()函数举例子
def mask_op():
image1 = np.ones((3, 3), dtype=np.uint8) * 3
image2 = np.ones((3, 3), dtype=np.uint8) * 7
mask1 = np.zeros((3, 3), dtype=np.uint8)
mask1[2][2] = 1
image3 = cv2.add(image1, image2, mask=mask1)
print("image3: n", image3)
mask_op()
程序运行结果为
5 位平面分解
图片的数据类型为uint8(8位无符整型),将图片矩阵中相同的位组合,得到位平面,一张图片有八个位平面。可通过按位与的方法把位平面提出出来
举一个例子,将阳菜图片的位平面提取并显示出来
def bit_plane():
image = cv2.imread("yc.jpg")
bit0 = np.ones(image.shape, dtype=np.uint8)
bit1 = bit0 * 2
bit2 = bit1 * 2
bit3 = bit2 * 2
bit4 = bit3 * 2
bit5 = bit4 * 2
bit6 = bit5 * 2
bit7 = bit6 * 2
bit0_image = cv2.bitwise_and(image, bit0)
bit1_image = cv2.bitwise_and(image, bit1)
bit2_image = cv2.bitwise_and(image, bit2)
bit3_image = cv2.bitwise_and(image, bit3)
bit4_image = cv2.bitwise_and(image, bit4)
bit5_image = cv2.bitwise_and(image, bit5)
bit6_image = cv2.bitwise_and(image, bit6)
bit7_image = cv2.bitwise_and(image, bit7)
cv2.imshow("bit0", bit0_image)
cv2.imshow("bit1", bit1_image)
cv2.imshow("bit2", bit2_image)
cv2.imshow("bit3", bit3_image)
cv2.imshow("bit4", bit4_image)
cv2.imshow("bit5", bit5_image)
cv2.imshow("bit6", bit6_image)
cv2.imshow("bit7", bit7_image)
cv2.waitKey(0)
bit_plane()
程序运行结果为
6 加密和解密
a与b进行两次异或运算结果还是等于a,利用这一性质可对图像进行加密和解密,原图像与密钥矩阵进行一次异或运算得到加密图像(加密),加密图像与密钥再进行一次异或运算得到原图像(解密)。
举个例子,用帆高给阳菜加密
def En_decryption():
fg_image = cv2.imread("fg.jpg")
yc_image = cv2.imread("yc.jpg")
fg_image = cv2.resize(fg_image, dsize=(yc_image.shape[1], yc_image.shape[0]))
encryption = cv2.bitwise_xor(yc_image, fg_image)
decryption = cv2.bitwise_xor(encryption, fg_image)
cv2.imshow("encryption", encryption)
cv2.imshow("decryption", decryption)
cv2.waitKey(0)
En_decryption()
运算结果为
7 数字水印
由5可以找到一张图片可以分解为8个位平面,而位平面0对于整个图片的影响权重是最小的,因此,我们可以用位平面7到位平面1来保存图片信息,而位平面0用来储存其他数据,例如数字水印。
例如,随机生成一个数字水印,并把他嵌入图片中
def Water_Mark():
image = cv2.imread("yc.jpg", 0)
#1 将图片的所有像素的二进制表示的第0位置0
image = cv2.bitwise_and(image, 254)
cv2.imshow("yc", image)
#2 随机生成一个数字水印,并把他嵌入图片中
wm = np.random.randint(0, 2, size=image.shape, dtype=np.uint8)
image = cv2.bitwise_or(image, wm)
cv2.imshow("yc&wm", image)
#3 数字水印的提取,即提取位平面0
wm_ = cv2.bitwise_and(image, 1)
print("提取出的数字水印:n", wm_)
print("数字水印为:n", wm)
cv2.waitKey(0)
Water_Mark()
程序运行的结果为
最后
以上就是故意饼干为你收集整理的OpenCV(Python)学习日记1-图像运算1 加法运算2 加权和3 按位逻辑运算4 掩模5 位平面分解6 加密和解密7 数字水印的全部内容,希望文章能够帮你解决OpenCV(Python)学习日记1-图像运算1 加法运算2 加权和3 按位逻辑运算4 掩模5 位平面分解6 加密和解密7 数字水印所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复