Python库cv2第一课:cv2的认识与入门(下)

        由于今日(12/9)上下午在做车速与车道的实践调查,下午一觉睡到晚上,我觉得,这个学习内容得推迟一天了。

        因此,接着继续学习cv2这个库的入门。上一小节我们学到了利用cv2这个库进行图片的读取、操作、绘制、调整色彩、储存。到目前为止,我们已经能够将一些简单的图案进行复杂化了,并进行叠加与改变。

        因此,接下来,我们将继续进行cv2这个库的入门学习。

一、基础事件

⭐1、按位运算

        按位运算是一个叠加图层的基础方法,它主要用于对图像叠加logo或者添加文字。比起传统的ps拖入图片来说,他的叠加方式也有反转模式与非反转模式,只需要简单理解其文字表达的意思,就能快速运用此五个基础函数。

        这里是一个难点部分,位运算其实是二进制的运算,我们生活中对十进制使用习惯了,因此,对于二进制确实习惯不过来。

        在这之前,我们需要了解一下什么是位运算,位运算一共分为三大类:与(&)(AND)、或(|)(OR)、异或(^)(XOR)、非(~)(NOT)、左移(<<)、右移(>>)。

        在这之前,我们必须先学习以下三个重要的概念:原码、反码、补码。

        原码:正数的源码是正数本身,负数的原码为四比特首位换为1。

        反码:正数的反码是其本身,负数的反码为所有数字取相反即可。

        补码:正数的补码为本身,负数的补码为反码+1即可。

        首先是“与运算”,两个二进制的同位数字仅全为1的时候,该位数字为一,否则为0。

        “或运算”,指的是两个二进制数字只要存在一个数字为1,该位便为1。

        “非运算”,否定某个二进制数字的全部原数字。交换各个位置上的0和1。

        “异或运算”,同位数字相同则取“0”,不同则肯定取“1”。

        “向左移”,指的原始位置上的数左移两个位置,右边不足位置补“0”。

        另外还有一个重要参数为mask,运用mask的时候,创建一个新的mask矩阵,此矩阵一般为标量。原图像矩阵(24位深度或8位深度)要与mask掩码(只能是8位深度)进行图像叠加。若掩膜位置rgb为0,则该像素位置三通道置0,生成黑色遮罩,只有掩膜不为0才会输出源图像的像素值。这里对于mask的理解我不知道有没有学到位???

        我在这里也尝试跟进了一个基础的按位运算的程序,首先,我运用绘图工具,绘制了两个简单的线条图:

# 按位运算
# 想要了解此功能,必须先绘制两个图案进行叠加比较
# 引入一个白板
img_white_1 = cv2.imread('white.jpg', 1)
img_white_2 = cv2.imread('white.jpg', 1)
# 绘制数个矩形和圆形
print(img_white_1.shape)
# 绘制形状1
cv2.rectangle(img_white_1, (20, 10), (60, 50), (0, 0, 0), -1)
cv2.rectangle(img_white_1, (140, 10), (180, 50), (0, 0, 0), 1)
cv2.ellipse(img_white_1, (270, 30), (20, 20), 0, 0, 360, (0, 0, 0), -1)
cv2.rectangle(img_white_1, (20, 110), (60, 150), (0, 0, 0), 1)
cv2.ellipse(img_white_1, (160, 130), (20, 20), 0, 0, 360, (0, 0, 0), -1)
cv2.rectangle(img_white_1, (140, 210), (180, 250), (0, 0, 0), 1)
cv2.rectangle(img_white_1, (20, 210), (60, 250), (0, 0, 0), -1)
cv2.ellipse(img_white_1, (270, 130), (20, 20), 0, 0, 360, (0, 0, 0), 1)
cv2.ellipse(img_white_1, (270, 230), (20, 20), 0, 0, 360, (0, 0, 0), -1)
# 绘制形状2
cv2.rectangle(img_white_2, (20, 10), (60, 50), (0, 0, 0), 1)
cv2.rectangle(img_white_2, (140, 10), (180, 50), (0, 0, 0), -1)
cv2.ellipse(img_white_2, (270, 30), (20, 20), 0, 0, 360, (0, 0, 0), 1)
cv2.rectangle(img_white_2, (20, 110), (60, 150), (0, 0, 0), -1)
cv2.ellipse(img_white_2, (160, 130), (20, 20), 0, 0, 360, (0, 0, 0), 1)
cv2.rectangle(img_white_2, (140, 210), (180, 250), (0, 0, 0), -1)
cv2.rectangle(img_white_2, (20, 210), (60, 250), (0, 0, 0), 1)
cv2.ellipse(img_white_2, (270, 130), (20, 20), 0, 0, 360, (0, 0, 0), -1)
cv2.ellipse(img_white_2, (270, 230), (20, 20), 0, 0, 360, (0, 0, 0), 1)
# cv2.imwrite('white_wite_1.jpg', img_white_1)
# cv2.imwrite('white_wite_2.jpg', img_white_2)

A                                                                     B             

        接下来,进行按位运算:

# 调用刚绘制的图案进行按位运算
draw_2 = cv2.imread('white_wite_1.jpg')
draw_3 = cv2.imread('white_wite_2.jpg')
# 按位运算
and_calcu = cv2.bitwise_and(draw_2,draw_3,mask=None)
or_calcu = cv2.bitwise_or(draw_2,draw_3,mask=None)
xor_calcu = cv2.bitwise_xor(draw_2,draw_3,mask=None)
cv2.imwrite('AND.jpg',and_calcu)
cv2.imwrite('OR.jpg',or_calcu)
cv2.imwrite('XOR.jpg',xor_calcu)
cv2.imwrite('NOT_2.jpg',cv2.bitwise_not(draw_2))
cv2.imwrite('NOT_3.jpg',cv2.bitwise_not(draw_3))

        其输出的结果如下:

 AND与运算                                                          OR或运算                  

NOR异或运算                                                   NOA_A非运算                 

        它的本质是将该位置的像素点用单通道RGB的方式表达出来,接着将其转换为二进制进行按位计算。按位运算基础知识到此结束,这个板块用的好其实应该可以算一个高级抠图的功能了,初步学习感觉。

        利用此逻辑,我们可以尝试给图片添加一个logo,在添加之前,我们需要认识一个能够创建掩码mask矩阵的函数:threshold()函数。

        retval, dst = cv.threshold( src, thresh, maxval, type[, dst] )

        我们只需要了解此函数的用法即可,其主要参数为:

        src:源图像,可以为8位的灰度图,也可以为32位的彩色图像。(两者有区别)

        dst:输出图像(一般这个为掩膜mask,一般只存在255和0两个数值)

        thresh:阈值(大于等于此值直接更改为最大值maxval,小于此阈值直接归0,被蒙版)

        maxval:dst图像中最大值(一般设置为255,其实只要不是0就可,用于透明该位置。)

        type:阈值类型

2、鼠标事件

        接下来学习的部分有鼠标事件,这个板块我也不是第一次接触了。在Java的app开发中,可以对一个小模块(某个按钮)设置鼠标悬停事件、点击事件、预览事件、连击事件等等。

        在python中也同样有这样的情况存在。在开始之前,我花时间维护了一下代码,让文件的图片进行创建入同一个文件夹“image_introdu/”,我依次加入了这个前缀,其实一般来说应当采用绝对路径或者相对路径,仅采用名称的话,在一些相对大的项目经常暴多,因为重复名还是较高的。

        在cv2中,设置鼠标事件的通用函数为:setMouseCallback() 函数。

        对此函数,其中有许多的参数,分别用于实现鼠标的事件(例如鼠标三个键的单击、双击、悬浮、释放、滚动滑轮上下等)。由于其涉及到def定义,因此,其基本上已经到了pytho基础上知识的后期认识了。在这里,其具体的参数设置如下:

鼠标参数设置规则
cv.EVENT_MOUSEMOVE当鼠标指针移到窗口上时。
cv.EVENT_LBUTTONDOWN表示鼠标左键被按下。
cv.EVENT_RBUTTONDOWN鼠标右键被按下的事件。
cv.EVENT_MBUTTONDOWN表示鼠标中键被按下。
cv.EVENT_LBUTTONUP当鼠标左键被释放时。
cv.EVENT_RBUTTONUP当鼠标右键被释放时。
cv.EVENT_MBUTTONUP表示释放鼠标中键。
cv.EVENT_LBUTTONDBLCLK双击鼠标左键时发生此事件。
cv.EVENT_RBUTTONDBLCLK表示双击鼠标右键。
cv.EVENT_MBUTTONDBLCLK表示双击鼠标中键。
cv.EVENT_MOUSEWHEEL向前滚动为正,向后滚动为负。

         鼠标函数的调用方式同样为SetMouseCallback(“window”,mousefuction),因此,我们在某个窗口,或者某个文件上使用该函数的时候,往往是需要先定义一个简单的参数的,这个参数就是鼠标点击或者悬浮停止所产生的一个反馈。

        这里这一小节我没想到,我学习的时间就是一整个晚上,主要是很多东西没学会,加上确实二进制的按位运算给忘光了,不同于十进制,不用就完全丢掉了忘了。

        

  • 26
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值