opencv-python的图像基础逻辑运算及细节、注意事项(与或非及掩膜)

主要记录一下bitwise_and(),cv.cv,bitwise_or(),cv.bitwise_not()这三个最基础的逻辑运算(与或非)

首先cv.bitwise_not()

 参数如图,虽然参数列表上面有三个参数,但是我使用的时候一般都是只用一个参数

circle = np.zeros((280,300),dtype="uint8")
cv.circle(circle,(150,150),50,255,-1) 
rectangle = np.zeros((280,300),dtype="uint8")
cv.rectangle(rectangle,(90,120),(220,170),255,-1)

#cv.bitwise_not(circle,inv_circle,mask=rectangle)
inv_circle=cv.bitwise_not(circle,mask=rectangle)#等于上一句

我最开始的时候有疑问,我想着灰度是一个范围内的值,并不是二值,那么对他做not运算会是怎么样呢

我用以下代码做实验 

circle = np.zeros((280,300),dtype="uint8")
cv.circle(circle,(150,150),50,20,-1)
inv_circle=cv.bitwise_not(circle)

cv.imshow('circle',circle)
cv.imshow('invcircle',inv_circle)

结果

控制台查看圆心处的灰度值

可以看到not之后的结果和原来相加是等于255的(和猜想的一样)

接下来我们测试第三个参数,mask,掩膜,这个掩膜可以看做为是在原来图像上指定要操作的区域,只要掩膜的灰度不为0(实际上很多掩膜的灰度值都是255),那么对应原图的这个像素点就要参与最后的逻辑运算,我个人认为可以理解为原图先和掩膜做与运算,最后再进行你想要的逻辑操作(如果不对请网友们指出)。下面这个例子可以说明这个问题

circle = np.zeros((280,300),dtype="uint8")
cv.circle(circle,(150,150),50,50,-1) # para:(src img,position of the circle,GRB,thickness of edge)
rectangle = np.zeros((280,300),dtype="uint8")
cv.rectangle(rectangle,(90,120),(220,170),100,-1)

inv_circle_with_mask=cv.bitwise_not(circle,mask=rectangle)
inv_circle=cv.bitwise_not(circle)
cv.imshow('circle',circle)
cv.imshow('rectangle',rectangle)
cv.imshow('invcircle',inv_circle)
cv.imshow('invcircle_with_mask',inv_circle_with_mask)

结果如下 

可以明显看到原来的circle在和rectangle做了与运算后,在做not运算得到了第一张图片,因为长方形之外的区域并没有因为not运算而变白。而这里rectangle的灰度值并不会影响掩膜的效果,我试过掩膜的灰度值为100和灰度值为255都是一样的结果。 

cv.bitwise_or()和cv.bitwise_and()

注意: src1和src2需要有相同的通道数量和尺寸,否者报错

参数如图二者的参数几乎一致,只是运算种类不一样,我就单单记录一下or操作

circle = np.zeros((280,300),dtype="uint8")
cv.circle(circle,(150,150),50,150,-1) # para:(src img,position of the circle,radiums,BGR,thickness of edge)
rectangle = np.zeros((280,300),dtype="uint8")
cv.rectangle(rectangle,(90,120),(220,170),100,-1)

orimg= cv.bitwise_or(circle,rectangle)
cv.imshow('circle',circle)
cv.imshow('rectangle',rectangle)
cv.imshow('orimg',orimg)

cv.waitKey(0)
cv.destroyAllWindows()

 

结果分析:交叉的部分变白了不少,无交叉的部分保持原像素值。交叉的部分是如何计算的我也不清楚。。。这个例子里圆是150,矩形是100,最后的中间位置(圆心)是246

In   [49]:orimg[150,150]
Out[49]: 246

这个计算规则我也不明白,希望大佬指点,尝试了一些值可以参考一下。(结果会偏向较大的像素值)

不同像素值做OR运算后的结果表
长方形圆形结果
100255255
100100100
10080118

 运算的主体部分大概是这样,但是逻辑运算一般喜欢和掩膜一起使用,提取出自己感兴趣的区域。很多例子里都是这样使用的,网上可以找到很多这里推荐一个https://blog.csdn.net/Lily_9/article/details/83143120

接下来可以体会一下包括掩膜的运算:

import cv2 as cv
import numpy as np

cat=cv.imread("cat.jpg",0)
dog=cv.imread("dog.jpg",-1)
cat1=cv.imread("cat.jpg",-1)

circle = np.zeros((280,300),dtype="uint8")
cv.circle(circle,(150,150),50,150,-1)
rectangle = np.zeros((280,300),dtype="uint8")
cv.rectangle(rectangle,(90,120),(220,170),100,-1)

andimg= cv.bitwise_and(cat1,dog,mask=rectangle)
orimg= cv.bitwise_or(cat1,cat1,mask=circle)

 

结果可以看到,掩膜就是告诉程序,只要在两张图片的这片区域进行运算!也可以理解为,两张图片先和mask做and运算,然后再进行需要的操作。这里左上图可以看到,and运算明显把狗的嘴巴(灰度值很低)的位置取代了原来猫的鼻子的位置。但是常规使用用于提取特征的时候,函数参数的src1和src2是同一张图片。(同一张图片对自身做or或者and运算得到本身)再依靠掩膜,获得我们想要的特征。

再提一点,有关and操作的像素值规律和or相反,我用测试or相同的方法测试了and的运算结果(总是小于较小的那个值)

rectanglecircleresult of and
2552020
1008064
1005032

 相较于其他博客,我的博客记录了较多的细节,回答了自己心中的一些疑问

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值