opencv-python 小白笔记(7)

(一)查看鼠标事件(events = [i for i in dir(cv2) if ‘EVENT’ in i])

import cv2
events = [i for i in dir(cv2) if 'EVENT' in i]
print (events)

打印结果在下面
Event:
EVENT_MOUSEMOVE //滑动
EVENT_LBUTTONDOWN //左键点击
EVENT_RBUTTONDOWN //右键点击
EVENT_MBUTTONDOWN //中键点击
EVENT_LBUTTONUP //左键放开
EVENT_RBUTTONUP //右键放开
EVENT_MBUTTONUP //中键放开
EVENT_LBUTTONDBLCLK //左键双击
EVENT_RBUTTONDBLCLK //右键双击
EVENT_MBUTTONDBLCLK //中键双击

flags: 代表鼠标的拖拽事件,以及键盘鼠标联合事件,共有32种事件:
EVENT_FLAG_LBUTTON //左鍵拖曳
EVENT_FLAG_RBUTTON //右鍵拖曳
EVENT_FLAG_MBUTTON //中鍵拖曳
EVENT_FLAG_CTRLKEY //(8~15)按Ctrl不放事件
EVENT_FLAG_SHIFTKEY //(16~31)按Shift不放事件
EVENT_FLAG_ALTKEY //(32~39)按Alt不放事件

(二)创建鼠标事件的回调函数(cv2.setMouseCallback)

创建鼠标事件回调函数,当鼠标事件发生时就会被执行。比如左键按下,松开,左键双击等。可以通过鼠标事件获得相对应的图片上的坐标,根据这些信息可以做想做的事。所有鼠标事件回调函数都有一个统一的格式,不同的地方是被调用后的功能。

看代码:

import cv2
import numpy as np

#创建回调函数
def MouseAction(event,x,y,flags,param):

    if event == cv2.EVENT_LBUTTONDOWN:
        print("左键点击")
    elif event==cv2.EVENT_RBUTTONDOWN :
        print("右键点击")
    elif flags==cv2.EVENT_FLAG_LBUTTON:
        print("左鍵拖曳")
    elif event==cv2.EVENT_MBUTTONDOWN :
        print("中键点击")


img = np.zeros((500,500,3),np.uint8)
cv2.namedWindow('image')
cv2.setMouseCallback('image',MouseAction)

while True:
    cv2.imshow('image', img)
    if cv2.waitKey(1)&0xFF == ord('q'):#按q键退出
        break
cv2.destroyAllWindows()

看左下角
在这里插入图片描述
当我看到鼠标事件,不禁让我想到了单片机外部中断

(三)鼠标事件画图(自定义画图函数)

import cv2
import numpy as np

# 当鼠标按下时为True
drawing = False
# 如果mode为true时绘制矩形,按下'l'变成绘制曲线
mode = True
ix, iy = -1, -1


# 创建回调函数
def draw_something(event, x, y, flags, param):
    global ix, iy, drawing, mode
    # 当按下左键时返回起始位置坐标
    if event == cv2.EVENT_LBUTTONDOWN:
        drawing = True
        print("左键点击")
        ix, iy = x, y
    # 当左键按下并移动时绘制图形,event可以查看移动,flag查看是否按下
    elif event == cv2.EVENT_MOUSEMOVE and flags == cv2.EVENT_FLAG_LBUTTON:
        print("左键拖拽")
        if drawing == True:
            if mode == True:
                cv2.rectangle(img, (ix, iy), (x, y), (0, 255, 0), -1)#还是原谅色
            else:
                # 绘制圆圈,小圆点连在一起就成了线,3代表笔画的粗细
                cv2.circle(img, (x, y), 3, (0, 0, 255), -1)#总是原谅色

    # 当鼠标松开时停止绘图
    elif event == cv2.EVENT_LBUTTONUP:
        drawing == False


'''
下面在主循环中奖'l'键与模式转换绑定在一起
'''
img = np.zeros((501, 501, 3), np.uint8)
cv2.namedWindow('image')
cv2.setMouseCallback('image', draw_something)
while True:
    cv2.imshow('image', img)
    k = cv2.waitKey(1)
    if k == ord('l'):
        mode = not mode
    elif k == ord('q'):
        break
cv2.destroyAllWindows()

在这里插入图片描述
还有很多的用法,多试试吧

(四)Trackbar的使用(cv2.getTrackbarPos,cv2.creatTrackbar)

这需要cv2.getTrackbarPos();cv2.creatTrackbar()函数
cv2.getTrackbarPos()参数详情:
滑动条的名字,滑动条被放置窗口的名字,滑动条默认的位置,滑动条最大的值,回调函数,每次滑动都会调用回调函数,回调函数通常都会含有一个默认参数,就是滑动条的位置。
这里我们用Trackbar创建调色板,窗口默认打开为原谅色

import cv2
import numpy as np

def nothing(a):#回调函数,啥也没有
    pass

#创建一个黑色画板
img = np.zeros((513,513,3),np.uint8)
cv2.namedWindow('image')

cv2.createTrackbar('switch','image',0,1,nothing)
cv2.createTrackbar('R','image',0,255,nothing)
cv2.createTrackbar('G','image',0,255,nothing)
cv2.createTrackbar('B','image',0,255,nothing)

while True:
    s = cv2.getTrackbarPos('switch', 'image')
    r = cv2.getTrackbarPos('R','image')
    g = cv2.getTrackbarPos('G', 'image')
    b = cv2.getTrackbarPos('B', 'image')

    if s == 0:
        img[:]=[0,255,0] #默认为原谅色
    else:
        img[:]=[b,g,r]

    cv2.imshow('image',img)
    k=cv2.waitKey(1)
    if k == ord('q'):#按q键退出
        break

cv2.destroyAllWindows()

在这里插入图片描述

(五)图像颜色的提取

前面我们介绍了Trackbar的使用,其实是为了这一节做铺垫(这节巨好玩)
首先我们先看一张图片

import cv2
import numpy as np


img = cv2.imread('1.jpg')
img=cv2.resize(img,None,fx=0.15,fy=0.15)#因为这里是手机拍的图片,太大了,所以resize
cv2.imshow("img", img)
cv2.waitKey(0)

在这里插入图片描述
现在我们要提取图片中美工刀的颜色,在这之前,我们先普及一下什么是HSV,并且我们为什么要用HSV。我就不解释了,这里有两篇文章我觉的写的很好,推荐一下
https://zhuanlan.zhihu.com/p/67930839
https://blog.csdn.net/qq_26271655/article/details/88406140
这里两篇都有介绍HSV模型,并且都用解释为什么要用HSV

我总结一下就是:RGB颜色空间更加面向于工业,而HSV更加面向于用户,大多数做图像识别这一块的都会运用HSV颜色空间,因为HSV颜色空间表达起来更加直观!

好回到我们的问题,提取美工刀的颜色上

注:在 OpenCV 的 HSV 格式中,H(色彩/色度)的取值范围是 [0,179], S(饱和度)的取值范围 [0,255],V(亮度)的取值范围 [0,255]

import cv2
import numpy as np

def empty(a):
    pass


cv2.namedWindow("TrackBars")
cv2.resizeWindow("TrackBars",650,250)
cv2.createTrackbar("Hue Min","TrackBars",0,179,empty)
cv2.createTrackbar("Hue Max","TrackBars",0,179,empty)
cv2.createTrackbar("Sat Min","TrackBars",0,255,empty)
cv2.createTrackbar("Sat Max","TrackBars",0,255,empty)
cv2.createTrackbar("Val Min","TrackBars",0,255,empty)
cv2.createTrackbar("Val Max","TrackBars",0,255,empty)

while True:

    img = cv2.imread('1.jpg')
    img = cv2.resize(img, None, fx=0.13, fy=0.13)
    imgHSV = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
    h_min = cv2.getTrackbarPos("Hue Min","TrackBars")
    h_max = cv2.getTrackbarPos("Hue Max", "TrackBars")
    s_min = cv2.getTrackbarPos("Sat Min", "TrackBars")
    s_max = cv2.getTrackbarPos("Sat Max", "TrackBars")
    v_min = cv2.getTrackbarPos("Val Min", "TrackBars")
    v_max = cv2.getTrackbarPos("Val Max", "TrackBars")
    
    print(h_min,h_max,s_min,s_max,v_min,v_max)
    
    lower=np.array([h_min,s_min,v_min])
    upper=np.array([h_max,s_max,v_max])
    mask=cv2.inRange(imgHSV,lower,upper)#下面会有解释

    cv2.imshow("img", img)
    cv2.imshow("imgHsv", imgHSV)
    cv2.imshow("mask", mask)

    cv2.waitKey(1)

在这里插入图片描述
cv2.inRange()函数的参数有三个:
第一个参数:hsv指的是原图
第二个参数:lower_red指的是图像中低于这个lower_red的值,图像值变为0
第三个参数:upper_red指的是图像中高于这个upper_red的值,图像值变为0
而在lower~upper之间的值变成255

这里我们调节Trackbar,使的mask图中的红色部分呈现为白色而非红色部分为黑色。如Trackbar上的数值所示,这就是你想提取的颜色在HSV空间范围

这里我们注意说四件事(应该说是小技巧):

第一,相信小伙伴也发现了图中红色部分的提取并不完美,这是因为红色在HSV模型中,它的取值范围是两个并集,所以无论我怎么调节TrackBar都无法兼顾所有的红色。

第二,小伙伴们在提取某个图片的某种颜色是,一定要选择图片质量较小的图片,否则你在拖动Trackbar时,会因为图片的计算量太大而失去时效性(意思就是:你这边拖动Trackbar到了一个理想值,而mask图像中的显示却发生了延迟,从而错过了最佳的值),举个例子像我们平常处理的lena大小只有462KB,而今天处理的图片大小有11.2M。

第三,在设置Trackbar窗口时,一定要注意大小,否则你的窗口可能无法显示所有的TrackBar

第四,当你无论怎么调节Trackbar时都无法想要的效果时,可以百度一下你想提取的颜色在HSV空间的大概范围,在这一范围上继续微调得到你想要的颜色

(六)提取具有单一颜色的物体(cv2.bitwise_and)

所以,你只会用以上的操作提取颜色,不你还可以用它提取具有单一颜色的物体

import cv2
import numpy as np


def empty(a):
    pass


cv2.namedWindow("TrackBars")
cv2.resizeWindow("TrackBars", 650, 250)
cv2.createTrackbar("Hue Min", "TrackBars", 0, 179, empty)
cv2.createTrackbar("Hue Max", "TrackBars", 0, 179, empty)
cv2.createTrackbar("Sat Min", "TrackBars", 0, 255, empty)
cv2.createTrackbar("Sat Max", "TrackBars", 0, 255, empty)
cv2.createTrackbar("Val Min", "TrackBars", 0, 255, empty)
cv2.createTrackbar("Val Max", "TrackBars", 0, 255, empty)

while True:
    img = cv2.imread('1.jpg')
    img = cv2.resize(img, None, fx=0.13, fy=0.13)
    imgHSV = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    h_min = cv2.getTrackbarPos("Hue Min", "TrackBars")
    h_max = cv2.getTrackbarPos("Hue Max", "TrackBars")
    s_min = cv2.getTrackbarPos("Sat Min", "TrackBars")
    s_max = cv2.getTrackbarPos("Sat Max", "TrackBars")
    v_min = cv2.getTrackbarPos("Val Min", "TrackBars")
    v_max = cv2.getTrackbarPos("Val Max", "TrackBars")

    print(h_min, h_max, s_min, s_max, v_min, v_max)

    lower = np.array([h_min, s_min, v_min])
    upper = np.array([h_max, s_max, v_max])
    mask = cv2.inRange(imgHSV, lower, upper)  # 下面会有解释

    img_output=cv2.bitwise_and(img,img,mask=mask)

    cv2.imshow("img", img)
    cv2.imshow("imgHsv", imgHSV)
    cv2.imshow("mask", mask)
    cv2.imshow("img_output", img_output)

    cv2.waitKey(1)

在这里插入图片描述
cv2.bitwise_and(img,img,mask=mask)
利用mask进行“与”操作,即mask图像白色区域是对需要处理图像像素的保留,mask图像黑色区域是对需要处理图像像素的删除

如果你觉的图片很乱,可以用之前的多层图像堆叠函数,试试吧

(七)结语

学习opencv有很多的方法,我的建议是你可以加一些群,可以充分利用B站,CSDN,和百度。

在我的博客中,我不会讲解opencv的算法实现(当然我也不太会),我只会讲解一些函数的调用,不理解就多改一些参数,多尝试尝试,慢慢你就理解来。相信你总有一天可以说opencv不过“Ctrl+C,Crtl+V”

如果有什么错误的地方,还请大家批评指正,最后,希望小伙伴们都能有所收获。
在这里插入图片描述

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值