python-openCV学习笔记(2)-图像运算

图像加法运算

在图像处理过程中,经常需要对图像进行加法运算,可以通过加号运算符”+“对图像进行加法运算,也可以通过cv2.add()函数对图像进行加法运算
通常情况下,在灰度图像中,像素用8个比特位(1个字节)来表示,像素值的范围是[0,255],两个像素值在进行加法运算时,求得的和很有可能超过255,上面两种不同的加法运算方式,对超过255的数值的处理方式是不一样的。

加号运算符

使用加号运算符”+“对图像a(像素值为a)和图像b(像素值为b)进行求和时,遵循以下规则:
a + b = { a + b , a+b<=255 m o d ( a + b , 256 ) , a+b>255 a+b= \begin{cases} a+b, & \text{a+b<=255} \\ mod(a+b,256), & \text{a+b>255} \end{cases} a+b={a+b,mod(a+b,256),a+b<=255a+b>255
式子中,mod()是取模运算,”mod(a+b,256)“表示计算”a+b的和除以256取余数“。

img1 = np.random.randint(0,256,size=[3,3],dtype=np.uint8)
img2 = np.random.randint(0,256,size=[3,3],dtype=np.uint8)
print("img1=\n",img1)
print("img2=\n",img2)
print("img1+img2=\n",img1+img2)

注意:取模在数组类型定义dtype=np.uint8时已经完成

cv2.add{}函数

函数cv2.add()可以用来计算图像像素值相加的和,其语法格式为:
计算结果=cv2.add(像素值a,像素值b)
使用函数cv2.add()对像素值a和像素b进行求和运算时,会得到像素值的对应图像的饱和值(最大值)。遵循以下规则:
a + b = { a + b , a+b<=255 255 , a+b>255 a+b= \begin{cases} a+b, & \text{a+b<=255} \\ 255, & \text{a+b>255} \end{cases} a+b={a+b,255,a+b<=255a+b>255

图像加权和

所谓图像加权和,就是在计算两幅图像的像素值之和时,将每幅图像的权重考虑进来,可以用公式表示为:
d s t = s a t u r a t e ( s r c 1 ∗ a + s r c 2 ∗ b + c ) dst=saturate(src1*a+src2*b+c) dst=saturate(src1a+src2b+c)
OpenCV中提供了函数cv2.addWeighted(),用来实现图像的加权和(混合、融合),该函数的语法格式为
dst=cv2.addWeighted(src1,alpha,src2,beta,gamma)
其中,参数alpha和beta是src1和src2所对应的系数,它们的和可以等于1,也可以不等于1。需要注意,式中参数gamma的值可以是0,但该参数是必选参数。

img1 = np.ones((3,4),dtype=np.uint8)
gamma=3
img3=cv2.addWeighted(img1,0.6,img2,5,gamma)
print("img3=\n",img)

按位逻辑运算

逻辑运算在图像处理过程中经常要按照位进行逻辑运算,常见的位运算函数如下。

函数名称基本含义
cv2.bitwise_and()按位与
cv2.bitwise_or()按位或
cv2.bitwise_xor()按位异或
cv2.bitwise_not()按位取反

按位与运算

在与运算中,当参与与运算的两个逻辑值都是真时,结果为真,其他为假。
在OpenCV中,可以使用cv2.bitwise_and()函数来实现按位与运算,格式如下:
dat = cv2_bitwise_and(src1,src2[,mask]])
式中,
dst表示与输入值具有同样大小的array输出值。
src1表示第一个array或scalar类型的输入值
scr2表示第二个array或scalar类型的输入值
mask表示可选操作掩码,8为单通道array

a = cv2.imread("lena.jpg",0)
b = np.zeros(a.shape,dtype=np.uint8)
b[100:400,200:400]=255
b[100:500,100:200]=255
c=cv2.bitwise_and(a,b)
cv2.imshow("a",a)
cv2.imshow("b",b)
cv2.imshow("c",c)
cv2.waitKey()
cv2.destroyAllWindows()

按位或运算

在或运算中,当参与或运算的两个逻辑值其中至少一个为真时,结果为真,其他为假。
在OpenCV中,可以使用cv2.bitwise_and()函数来实现按位或运算,格式如下:
dat = cv2_bitwise_or(src1,src2[,mask]])
式中,
dst表示与输入值具有同样大小的array输出值。
src1表示第一个array或scalar类型的输入值
scr2表示第二个array或scalar类型的输入值
mask表示可选操作掩码,8为单通道array

按位非运算

非运算是取反操作,满足如下逻辑:
当运算数为真时,结果为假。
当运算数为假时,结果为真。
在OpenCV中,可以使用cv2.bitwise_not()函数来实现按位非运算,格式如下:
dat = cv2_bitwise_or(src[,mask]])
式中,
dst表示与输入值具有同样大小的array输出值。
src表示array或scalar类型的输入值
mask表示可选操作掩码,8为单通道array

按位异或运算

异或运算也叫半加运算,当两个逻辑值不同时,为真,其他为假
在OpenCV中,可以使用cv2.bitwise_xor()函数来实现按位异或运算,格式如下:
dat = cv2_bitwise_xor(src1,scr2[,mask]])
式中,
dst表示与输入值具有同样大小的array输出值。
src1表示第一个array或scalar类型的输入值
scr2表示第二个array或scalar类型的输入值
mask表示可选操作掩码,8为单通道array

掩模

OpenCV中的很多函数都会指定一个掩模,也被称为掩码。
当使用掩模参数时,操作只会在掩模值为非空的像素点上执行,并将其他像素点的值置为0.

img1=np.ones((4,4),dtype=np.uint8)*3
img2=np.ones((4,4),dtype=np.uint8)*5
mask=np.zeros((4,4),dtype=np.uint8)
mask[2:4,2:4]=1
img3=np.ones((4,4),dtype=np.uint8)*66
print("img1=\n",img1)
print("img2=\n",img2)
print("mask=\n",mask)
print("初始值img3=\n",img3)
img3=cv2.add(img1,img2,mask=mask)
print("求和后mg3=\n",img3)
img1=np.ones((4,4),dtype=np.uint8)*3
img2=np.ones((4,4),dtype=np.uint8)*5
print("img1=\n",img1)
print("img2=\n",img2)
img3=cv2.add(img1,img2)
print("cv2.add(img1,img2)=\n",img3)
img4=cv2.add(img1,6)
print("cv2.add(img1,6)=\n",img4)
img5=cv2.add(6,img2)
print("cv2.add(6,img2)=\n",img5)

位平面分解

将灰度图像中处于同一比特位上的二进制像素值进行组合,得到一幅二进制图像,该图像被称为灰度图像的一个位平面,这个过程被称为位平面分解。
通过提取灰度图像像素点二进制像素值的每一比特位的组合,可以得到多个位平面图像。图像中全部像素值的a(i)值所构成的位平面,称为第i个位平面(第i层)。在8位灰度图中,可以组成8个二进制值图像,即可以将原图分解为8个位平面。其中,由图像中的每个像素的a(0)值(即从右边数第0个二进制位,第0个比特位)组成的,我们称之为第0个位平面,也可以称为第0层,即是由二进制位的第0位构成的。其也称为”最低有效位“位平面。由图像中的每个像素的a(7)值(即从右边数第7个二进制位,第7个比特位)组成的,也称为”最高有效位“位平面。
针对RGB图像,如果将R、G、B通道中的每一个通道对应的位平面进行合并,即可组成新的RGB彩色图像。例如,针对一幅RGB图像,将其R通道的第3个位平面、G通道的第3个位平面、B通道的第3个位平面进行合并,则可以构成一幅新的RGB彩色图像,我们称之为原始图像的第3个位平面。

下面以灰度图像为例,介绍位平面分解的具体步骤
1.图像预处理
2.构造提取矩阵,使用按位与操作能够很方便地将一个数值指定位上的数值提取出来。
3.提取位平面,将灰度图像与提取矩阵进行按位与运算,得到各个位平面。
4.阈值处理,因为每次提取位平面后,要想让二值位平面能够以黑白颜色显示出来,就要将得到的二值位平面进行阈值处理,将其中大于零的值处理为255
5.显示图像。

lena = cv2.imread("lena.jpg",0)
cv2.imshow("lena",lena)
r,c=lena.shape
x=np.zeros((r,c,8),dtype=np.uint8)
for i in range(8):
    x[:,:,i]=2**i
r=np.zeros((r,c,8),dtype=np.uint8)
for i in range(8):
    r[:,:,i]=cv2.bitwise_and(lena,x[:,:,i])
    mask=r[:,:,i]>0
    r[mask]=255
    cv2.imshow(str(i),r[:,:,i])
cv2.waitKey()
cv2.destroyAllWindows()

数字水印

最低有效位指的是一个二进制数中的第0层(即最低位)。最低有效位信息隐藏指的是,将一个需要隐藏的二值图像信息嵌入载体图像的最低有效位,即将载体图像的最低有效位层代替当前需要隐藏的二值图像,从而实现将二值图像隐藏的目的。在必要时直接将载体图像的最低有效位层提取出来,即可得到嵌入在该位上的二值图像,达到提取秘密信息的目的。
这种信息隐藏也被称为数字水印,通过该方式可以实现信息隐藏、版权认证、身份认证等功能。被嵌入载体图像内的信息也被称为数字水印信息。
从位平面的角度考虑,数字水印的处理过程分为下面两步;
1.嵌入过程:将载体图像的第0个位平面替换为数字水印信息。
2.提取过程:将载体图像的最低有效位所构成的第0个位平面提取出来,得到数字水印信息。

#读取原始图像
lena = cv2.imread("lena.jpg",0)
#读取水印图像
watermark = cv2.imread("watermark.jpg",0)
#将水印图像内的值为255处理为1,以方便嵌入
w=watermark[:,:]>0
watermark[w]=1
#读取原始载体图像的shape值
r,c=lena.shape
#==========嵌入过程=================
#生成元素值都是254的数组
t254=np.ones((r,c),dtype=np.uint8)*254
#获取lena图像的高7位
lenaH7=cv2.bitwise_and(lena,t254)
#将watermask嵌入lenaH7内
e=cv2.bitwise_or(lenaH7,watermark)
#================提取过程=======================
#生成元素值都是1的数组
t1=np.ones((r,c),dtype=np.uint8)
#从载体图像内提取水印图像
wm=cv2.bitwise_and(e,t1)
print(wm)
#将水印图像内的值为1处理为255,以方便显示
w=wm[:,:]>0
wm[w]=255
#==============显示===============================
cv2.imshow("lema",lena)
cv2.imshow("wayermask",watermark)
cv2.imshow("e",e)
cv2.imshow("wm",wm)
cv2.waitKey()
cv2.destroyAllWindows()
  • 26
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

全栈小菜花

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值