主要记录一下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
这个计算规则我也不明白,希望大佬指点,尝试了一些值可以参考一下。(结果会偏向较大的像素值)
长方形 | 圆形 | 结果 |
100 | 255 | 255 |
100 | 100 | 100 |
100 | 80 | 118 |
运算的主体部分大概是这样,但是逻辑运算一般喜欢和掩膜一起使用,提取出自己感兴趣的区域。很多例子里都是这样使用的,网上可以找到很多这里推荐一个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的运算结果(总是小于较小的那个值)
rectangle | circle | result of and |
255 | 20 | 20 |
100 | 80 | 64 |
100 | 50 | 32 |
相较于其他博客,我的博客记录了较多的细节,回答了自己心中的一些疑问