利用matplotlib为图片上添加触发事件进行交互


Posted in Python onApril 23, 2020

这篇文章的目的出于实验的需要,我需要对图片上的部分区域做出涂抹标记,本来是选择用opencv做交互的,但在需要进行图像的输出以及鼠标时间添加时,opencv出现错误。

解决方案网上有很多,尝试以后依然bug,这里先做一个记录,有时间再来处理。

错误报告如下:

OpenCV Error: Unspecified error (The function is not implemented. Rebuild the library with Windows, GTK+ 2.x or Carbon support. If you are on Ubuntu or Debian, install libgtk2.0-dev and pkg-config, then re-run cmake or configure script) in cvShowImage, file -------src-dir-------/opencv-2.4.10/modules/highgui/src/window.cpp, line 501
Traceback (most recent call last):
File "test.py", line 20, in <module>
cv2.imshow('img',img)
cv2.error: -------src-dir-------/opencv-2.4.10/modules/highgui/src/window.cpp:501: error: (-2) The function is not implemented. Rebuild the library with Windows, GTK+ 2.x or Carbon support. If you are on Ubuntu or Debian, install libgtk2.0-dev and pkg-config, then re-run cmake or configure script in function cvShowImage

这里我们切换另一种解决方案,利用python的matplotlib库完成图像的输出以及鼠标事件的添加。

点击图片,在图像中鼠标对应位置画点:

# coding=utf-8
from matplotlib import pyplot as plt
import cv2

def on_press(event):
 if event.inaxes == None:
  print "none"
  return 
 #在鼠标的当前位置绘制一个点
 ax.scatter(event.xdata, event.ydata)
 #更新画板
 fig.canvas.draw()

if __name__ == "__main__":
 fileN = r'./0107_1.3.6.1.4.1.14519.5.2.1.6279.6001.263660956768649083933159084365.bmp'
 img = cv2.imread(fileN)
 cv2.imshow('img',img)
 fig = py.figure()
 fig.canvas.mpl_connect("button_press_event", on_press) 
 ax = fig.add_subplot(121)
 ax1 = fig.add_subplot(122)
 ax.imshow(img)
 ax1.imshow(img)
 plt.axis("off")
 plt.show()

先来简单解释一下代码的含义:

fig.canvas.mpl_connect("button_press_event", on_press)#在这个figure上加点击事件,点击后的情况在自己写的on_press()方法里 
def on_press(event): 
  event.inaxes.figure.canvas.draw()#用于图片刷新 
  event.x#事件的坐标用于其他按钮点击和figure点击发生冲突时判断返回 
  event.xdata,event.ydata#鼠标点击的位置,与上面那个坐标表示形式不同

最后的输出结果入下图。我们得到了非常奇怪的结果,如果你自己亲自动手试的话体会应该会更有体会,两边的图像本来应该一样大,但在第一次绘制点的时候,左侧图像出现了闪动,然后尺寸的比例突然发生了变化。

利用matplotlib为图片上添加触发事件进行交互

是的,图像尺寸没有发生变化,但尺寸的比例的确变了,这里我们要做的就是关闭自动变化的尺度比例。

if __name__ == "__main__":
 fileN = r'./0107_1.3.6.1.4.1.14519.5.2.1.6279.6001.263660956768649083933159084365.bmp'
 img = cv2.imread(fileN)
 cv2.imshow('img',img)
 fig = py.figure()
 fig.canvas.mpl_connect("button_press_event", on_press) 
 ax = fig.add_subplot(121)
 ax1 = fig.add_subplot(122)
 ax.imshow(img)
 ax1.imshow(img)
 #关闭自动尺度适配
 ax.set_autoscale_on(False) 
 plt.axis("off")
 plt.show()

当然,我们可以改变绘制标记的样式:

ax.scatter(x,y,c='k',s=25,alpha=1.0,marker='o')
#T:散点的颜色
#s:散点的大小
#alpha:是透明程度

现在我们能够在图像上进行标记了,但这样还不够,程序需要获取这些标记点。

实际上fig.canvas.mpl_connect("button_press_event", on_press)能够进行自定义的多参数传递,如果在每次绘制的时候将数据保存在外部传入的列表中,那么当画板被销毁时,我们就能获取到原来所有的绘制点。

这里介绍两种使用方法:

def on_key(event, arg1, arg2, arg3):
 pass
canvas.mpl_connect('key_press_event', lambda event: on_key(event, plt1, plt2, plt3))

def on_key(event, args_list):
 pass
fig.canvas.mpl_connect('key_press_event', lambda event: on_key(event, [plt1, plt2, plt3]))

这里需要注意的是scatter绘制的点,实际上并没有大小的概念,这个点实质是一个坐标。

如果需要绘制有实际面积的圆形的标记,可以使用matplotlib.patches.Circle

具体的使用如下:

from matplotlib.patches import Circle

fig = plt.figure()
ax = fig.add_subplot(111)
cir = Circle(xy = (event.xdata, event.ydata),facecolor = 'black', edgecolor='black',radius=10, alpha=1.0) 
ax.add_patch(cir)

以上这篇利用matplotlib为图片上添加触发事件进行交互就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python 的 with 语句详解
Jun 13 Python
Python开发常用的一些开源Package分享
Feb 14 Python
用PyQt进行Python图形界面的程序的开发的入门指引
Apr 14 Python
详解TensorFlow查看ckpt中变量的几种方法
Jun 19 Python
PyQt5图形界面播放音乐的实例
Jun 17 Python
使用Python代码实现Linux中的ls遍历目录命令的实例代码
Sep 07 Python
python cv2读取rtsp实时码流按时生成连续视频文件方式
Dec 25 Python
Python3实现mysql连接和数据框的形成(实例代码)
Jan 17 Python
PYQT5 vscode联合操作qtdesigner的方法
Mar 24 Python
python 写一个性能测试工具(一)
Oct 24 Python
如何用Matlab和Python读取Netcdf文件
Feb 19 Python
PyTorch device与cuda.device用法
Apr 03 Python
python中matplotlib实现随鼠标滑动自动标注代码
Apr 23 #Python
使用matplotlib动态刷新指定曲线实例
Apr 23 #Python
Flask模板引擎Jinja2使用实例
Apr 23 #Python
利用pandas向一个csv文件追加写入数据的实现示例
Apr 23 #Python
在matplotlib中改变figure的布局和大小实例
Apr 23 #Python
Python将二维列表list的数据输出(TXT,Excel)
Apr 23 #Python
Python基于DB-API操作MySQL数据库过程解析
Apr 23 #Python
You might like
轻松修复Discuz!数据库
2008/05/03 PHP
PHP flush()与ob_flush()的区别详解
2013/06/03 PHP
php版微信发红包接口用法示例
2016/09/23 PHP
利用 fsockopen() 函数开放端口扫描器的实例
2017/08/19 PHP
thinkPHP5实现数据库添加内容的方法
2017/10/25 PHP
我遇到的参数传递中 双引号单引号嵌套问题
2010/02/11 Javascript
玩转jQuery按钮 请告诉我你最喜欢哪些?
2012/01/08 Javascript
使用javascript控制cookie显示和隐藏背景图
2014/02/12 Javascript
jQuery实现文本展开收缩特效
2015/06/03 Javascript
JS+CSS实现自适应选项卡宽度的圆角滑动门效果
2015/09/15 Javascript
jQuery实用技巧必备(下)
2015/11/03 Javascript
jquery判断当前浏览器的实现代码
2015/11/07 Javascript
全面解析Bootstrap中form、navbar的使用方法
2016/05/30 Javascript
浅析$(function) ready和onload 的区别
2016/09/03 Javascript
详谈Ajax请求中的async:false/true的作用(ajax 在外部调用问题)
2017/02/10 Javascript
AngularJS使用ocLazyLoad实现js延迟加载
2017/07/05 Javascript
bootstrap 日期控件 datepicker被弹出框dialog覆盖的解决办法
2019/07/09 Javascript
vue中实现回车键登录功能
2020/02/19 Javascript
在vant 中使用cell组件 定义图标该图片和位置操作
2020/11/02 Javascript
[51:17]Mineski vs Secret 2019国际邀请赛淘汰赛 败者组 BO3 第一场 8.22
2019/09/05 DOTA
Python迭代器和生成器介绍
2015/03/06 Python
Gauss-Seidel迭代算法的Python实现详解
2019/06/29 Python
Python sys模块常用方法解析
2020/02/20 Python
Python小白垃圾回收机制入门
2020/06/09 Python
python实现感知机模型的示例
2020/09/30 Python
Python利用Pillow(PIL)库实现验证码图片的全过程
2020/10/04 Python
我未来的职业规划范文
2014/01/11 职场文书
指导教师评语
2014/04/26 职场文书
学生检讨书范文
2014/10/30 职场文书
2014年仓库管理员工作总结
2014/11/18 职场文书
商务宴请邀请函范文
2015/02/02 职场文书
汽车4S店销售经理岗位职责
2015/04/02 职场文书
2015年保险公司工作总结
2015/04/24 职场文书
小区环境卫生倡议书
2015/04/29 职场文书
Java实现聊天机器人完善版
2021/07/04 Java/Android
如何设置多台电脑共享打印机?多台电脑共享打印机的方法
2022/04/08 数码科技