[python opencv 计算机视觉零基础到实战] 十九、简易绘画板制作

一、学习目标

  1. 了解事件
  2. 编写一个简易绘画板

二、了解如何制作简易绘画板

2.1 了解鼠标多种事件

上一节我们简单的使用opencv的图形绘制方法,用鼠标绘制了一些内容。上一节所响应的是简单的双击事件EVENT_LBUTTONDBLCLK,在OpenCV的鼠标事件中还有很多。以下将列举出来:

  • EVENT_MOUSEMOVE:鼠标滑动
  • EVENT_LBUTTONDOWN:左键单击
  • EVENT_RBUTTONDOWN:右键单击
  • EVENT_MBUTTONDOWN:中间单击
  • EVENT_LBUTTONUP:左键释放
  • EVENT_RBUTTONUP:右键释放
  • EVENT_MBUTTONUP:中键释放
  • EVENT_LBUTTONDBLCLK:左键双击
  • EVENT_RBUTTONDBLCLK:右键双击
  • EVENT_MBUTTONDBLCLK:中键双击

以上事件在setMouseCallback函数回调后将会传到所执行的函数中,并且以event参数进行对应,取值通过event参数进行取值。

首先我们对一些事件进行监测,先尝试检测CV_EVENT_MOUSEMOVE鼠标滑动事件。代码如下:

import cv2
import numpy as np
def listing(event,x,y,flags,param):if event==cv2.EVENT_MOUSEMOVE:print('EVENT_MOUSEMOVE',' x:',x,' y:',y)
img=np.zeros((600,600,3),np.uint8)
cv2.namedWindow('image')
cv2.setMouseCallback('image',listening)
while(1):cv2.imshow('image',img)if cv2.waitKey(20)&0xFF==27:break
cv2.destroyAllWindows()

以上代码使用listing作为回调后的处理,并且当事件为EVENT_MOUSEMOVE时将会输出事件名以及当前鼠标所在的x和y坐标的位置。

结果如下:
这时我们可以对所有的事件都进行监听,这时候修改listen函数就可以了:

def listening(event,x,y,flags,param):if event==cv2.EVENT_MOUSEMOVE:print('EVENT_MOUSEMOVE 鼠标滑动',' x:',x,' y:',y)elif event==cv2.EVENT_LBUTTONDOWN:print('EVENT_LBUTTONDOWN 左键单击',' x:',x,' y:',y)elif event==cv2.EVENT_RBUTTONDOWN:print('EVENT_RBUTTONDOWN 右键单击',' x:',x,' y:',y)elif event==cv2.EVENT_MBUTTONDOWN:print('EVENT_MBUTTONDOWN 中间单击',' x:',x,' y:',y)elif event==cv2.EVENT_LBUTTONUP:print('EVENT_LBUTTONUP 左键释放',' x:',x,' y:',y)elif event==cv2.EVENT_RBUTTONUP:print('EVENT_RBUTTONUP 右键释放',' x:',x,' y:',y)elif event==cv2.EVENT_MBUTTONUP:print('EVENT_MBUTTONUP 中键释放',' x:',x,' y:',y)elif event==cv2.EVENT_LBUTTONDBLCLK:print('EVENT_LBUTTONDBLCLK 左键双击',' x:',x,' y:',y)elif event==cv2.EVENT_RBUTTONDBLCLK:print('EVENT_RBUTTONDBLCLK 右键双击',' x:',x,' y:',y)elif event==cv2.EVENT_MBUTTONDBLCLK:print('EVENT_MBUTTONDBLCLK 中键双击',' x:',x,' y:',y)

结果如下:

2.2 制作一个简单的绘画板

首先我们对绘制一个拖拽绘制板功能做一个行为分析。我们正常进行拖拽画矩形,一般是按下左键,并且不放手,移动鼠标进行矩形的绘制,直到拖拽至我们觉得合适的位置后,我们开始松开鼠标。

在以上的绘制行为中,一共有几个鼠标事件。有按下鼠标左键事件EVENT_LBUTTONDOWN、鼠标移动事件EVENT_MOUSEMOVE、鼠标左键释放事件EVENT_LBUTTONUP。我们在按下鼠标左键的时候,从当前鼠标的x与y坐标开始绘制矩形,直到我们松开鼠标后停止绘制。

我们写一个函数作为回调的处理:

def draw(event,x,y,flags,param):

随后我们在鼠标按下左键的时候需要记住x与y的坐标位置,并且表示开始绘制,需要一个变量表示绘制状态开启:

if event==cv2.EVENT_LBUTTONDOWN:drawing=Truesx,sy=x,y

注意,由于回调函数每次循环时都会进行调用,若drawing此次为True后下一次不能直接进入绘制,这个时候需要把drawing、sx、sy都设置成全局变量:

drawing=False
sx,sy=0,0

并且在回调处理的函数中需要加入关键字进行声明是全局变量:

global sx,sy,drawing

接下来我们应该判断当前是否已经是按下鼠标左键并且进行了拖拽移动,这两个状态是并列的,所以写个elif语句进行判断:

elif event==cv2.EVENT_MOUSEMOVE and flags==cv2.EVENT_FLAG_LBUTTON:

这个时候在该判断中,使用if语句判断是否已经按下左键后开启了绘制,防止bug的出现,若已经开启了绘制则进行绘制矩形:

cv2.rectangle(img,(sx,sy),(x,y),(0,255,0),-1)

如上代码中为什么起始绘制点是sx与sy呢?那是因为我们按下了鼠标左键后的那个点是绘制起始点,从那个点开始绘制矩形到当前鼠标移动到的x和y坐标处,这样由于每次都覆盖掉原来的图像造成一种错觉,就是在拖拽进行绘制图像,并且进行填充,颜色为(0,255,0)。由于绘制状态不能一直开启,若直接进入了按下左脚与移动时由于保留了上次绘制的绘制开启,那么会造成初始绘制点的丢失,所以我们还需要判断当鼠标左键释放弹起后把绘制状态改为Fasle。代码如下:

elif event==cv2.EVENT_LBUTTONUP:drawing==False

所有完整的代码如下:

import cv2
import numpy as npdrawing=False
sx,sy=0,0def draw(event,x,y,flags,param):global sx,sy,drawingif event==cv2.EVENT_LBUTTONDOWN:drawing=Truesx,sy=x,yelif event==cv2.EVENT_MOUSEMOVE and flags==cv2.EVENT_FLAG_LBUTTON:if drawing==True:cv2.rectangle(img,(sx,sy),(x,y),(0,255,0),-1)elif event==cv2.EVENT_LBUTTONUP:drawing==False
img=np.zeros((600,600,3),np.uint8)
cv2.namedWindow('image')
cv2.setMouseCallback('image',draw)
while(1):cv2.imshow('image',img)if cv2.waitKey(20)&0xFF==27:break
cv2.destroyAllWindows()

结果如下:
该系列首发于ebaina

三、总结

  1. 了解了多个鼠标事件
  2. 通过事件以及灵活运用绘图函数制作了一个简易的绘画板

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/287466.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Web App 和 Native App,哪个是趋势?

2019独角兽企业重金招聘Python工程师标准>>> Web App 和 Native App,哪个是趋势? https://www.zhihu.com/question/19558750 WebAPP与原生APP的交互设计区别 http://www.woshipm.com/ucd/132869.html Web App 开发使用哪种框架比较好&#xf…

基于天地图的应用服务系统设计开发—以甘肃高校招生服务为例

“天地图”是国家测绘地理信息局建设的地理信息综合服务网站。它是“数字中国”的重要组成部分,是国家地理信息公共服务平台的公众版。“天地图”的目的在于促进地理信息资源共享和高效利用,提高测绘地理信息公共服务能力和水平,改进测绘地理信息成果的服务方式,更好地满足…

查缺补漏系统学习 EF Core 6 - 修改实体数据

推荐关注「码侠江湖」加星标,时刻不忘江湖事这是 EF Core 系列的第六篇文章,上一篇文章讲述了 EF Core 中的原始 SQL 语句查询。这篇文章讲一讲 EF Core 如何修改实体数据。点击上方或后方蓝字,阅读 EF Core 系列合集。实体状态在开始学习 EF…

情人节,我表白了CSDN小姐姐后,竟然...【为表白写了一个绘图工具,让我不再手残】

情人节,我表白了CSDN小姐姐后,竟然…竟然有人看了这篇文。 以下图片素材由一个还没写完的工具绘制,稍后会放在CSDN的代码仓库(现在能用了,还没时间改,颜色填充算法还没写,有能力的朋友可以修改一…

【小程序】刘一哥课堂随机点名提问神器V1.0(附源程序)

为了能让我们的孩子们尽量来教室上课,增强课堂的参与度,激发课堂激情,提高学习效率,一哥也是煞费苦心,于是开发出了这么一款课堂点名提问神器,跟大家分享一下。 打开神器,看到的界面是这样子的,我很感激有勇气按时起床并能到教室的每一位有志之士。 点击【开始】按钮,…

Git客户端TortoiseGit(Windows系统)的使用方法

本文环境: 操作系统:Windows XP SP3 Git客户端:TortoiseGit-1.8.8.0-32bit 一、安装Git客户端 全部安装均采用默认! 1. 安装支撑软件 msysgit: https://code.google.com/p/msysgit/downloads/list?qfullinstallerofficialgit 当前…

.Net 在容器中操作宿主机

1方案描述 在 docker 容器中想操作宿主机,一般会使用 ssh 的方式,然后 .Net 通过执行远程 ssh 指令来操作宿主机。本文将使用 交互式 .Net 容器版 中提供的镜像演示 .Net 在容器中如何操作宿主机。2前期准备 1. 宿主机上生成 ssh key生成 ss…

【看动漫学编程】程序员在异世界生个娃 第1篇:太极村

前言 作者文笔比较水,还请见谅。 以下内容还将使用视频动态漫画表现,剪辑完将会贴出链接。 小说剧情为剧情需要,过渡到知识点,部分篇幅可能没有技术知识点还望谅解。 由于没有经费支持,所以画出来的东西是我自己用代码…

【ArcGIS风暴】最牛逼空间数据批处理神器来了:用户自定义工具箱GeoStorm.tbx

【Warming up】在学习和工作的过程中,作者曾写过很多采用ArcGIS模型构建器(Model Builder)、Python代码等批处理方法(感兴趣的GISers可以去【测绘地理信息Big风暴专】栏去交流学习指导),大大的减轻了操作压力,提高了工作效率。今天给大家展示一款神器:自定义工具箱GeoS…

Linux下c/c++项目代码覆盖率的产生方法

最近做了一系列的单元测试相关的工作,除了各种规范及测试框架以外,讨论比较多的就是关于代码覆盖率的产生,c/c与其他的一些高级语言或者脚本语言相比较而言,例如 Java、.Net和php/python/perl/shell等,由于没有这些高级…

C# WPF从后台代码生成行列可变的表格

z概述WPF常用的表格控件是DataGrid,这个控件在前台XAML编写的话,一般列已经固定,然后给每个列去绑定数据,但是如果我的列不固定,随着运算结果变动呢?这时候DataGrid,就比较难实现这个需求&#…

软件架构实践文章链接

2019独角兽企业重金招聘Python工程师标准>>> 架构 InfoQ: 又拍网架构中的分库设计 SNS网站数据库技术分析 - 51CTO.COM 数据库水平切分的实现原理解析 - iBATIS - Java - JavaEye论坛 基于amoeba的mysql分布式数据库学习(一) - Java - JavaEy…

数据库SQL语句学习笔记(6)-使用函数处理数据

1.SQL也可以用函数来处理数据,函数一般是在数据上执行的,为数据的转换和处理提供了方便。但是每一个数据库管理系统(DBMS)都有特定的函数,事实上,只有少数几个函数被所有的DBMS等同地支持。例如&#xff0c…

【遥感物候】Matlab求解一元六次多项式,计算植被生长季始期

一元六次多项式能很好的逼近滤波后的曲线,与二次多项式相比,在拟合植被整个生长季曲线方面有更好的优势,该方法常用来描述北方温带和高纬度地区时序NDVI生长季模式。因此,本文使用一元六次多项式来拟合植被整个生长季曲线,效果很好。那么拟合后,这样解方程呢求生长季参数…

最全面透彻的RabbitMQ指南

概念RabbitMQ是实现了高级消息队列协议(AMQP)的开源消息代理软件(亦称面向消息的中间件)。RabbitMQ服务器是用Erlang语言编写的,而集群和故障转移是构建在开放电信平台框架上的。所有主要的编程语言均有与代理接口通讯…

TensorFlow中RNN实现的正确打开方式

上周写的文章《完全图解RNN、RNN变体、Seq2Seq、Attention机制》介绍了一下RNN的几种结构,今天就来聊一聊如何在TensorFlow中实现这些结构,这篇文章的主要内容为: 一个完整的、循序渐进的学习TensorFlow中RNN实现的方法。这个学习路径的曲线较…

《看聊天记录都学不会C语言?太菜了吧》(2)我说编程很容易你们不服?

若是大一学子或者是真心想学习刚入门的小伙伴可以私聊我,若你是真心学习可以送你书籍,指导你学习,给予你目标方向的学习路线,无套路,博客为证。 本系列文章将会以通俗易懂的对话方式进行教学,对话中将涵盖…

LCD1602,4位数据总线液晶屏时钟,STC12C5A60S2的10位ADC功能程序

/* 程序名:    LCD1602,4位数据总线液晶屏时钟,STC12C5A60S2的10位ADC功能程序 编写时间:  2015年10月4日 硬件支持:  LCD1602液晶屏 STC12C5A60S2 外部12MHZ晶振 接线定义: DB7 --> P1^7DB6…

WPF|黑暗模式的钱包支付仪表盘界面设计

收集下大家的意见,是否需要在文中贴上源码(文末会给出源码链接),请大家踊跃留言。阅读目录效果展示准备简单说明 源码结尾(视频及源码仓库)1. 效果展示欣赏效果:2. 准备创建一个WPF工程&#x…

《看聊天记录都学不会C语言?太菜了吧》(3)人艰不拆,代码都在谈恋爱?!

若是大一学子或者是真心想学习刚入门的小伙伴可以私聊我,若你是真心学习可以送你书籍,指导你学习,给予你目标方向的学习路线,无套路,博客为证。 本系列文章将会以通俗易懂的对话方式进行教学,对话中将涵盖…