利用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之类的细节
Oct 13 Python
Python实现LRU算法的2种方法
Jun 24 Python
python装饰器实例大详解
Oct 25 Python
用python制作游戏外挂
Jan 04 Python
PyQt4实现下拉菜单可供选择并打印出来
Apr 20 Python
使用实现XlsxWriter创建Excel文件并编辑
May 04 Python
pycharm安装和首次使用教程
Aug 27 Python
python set集合使用方法解析
Nov 05 Python
浅谈Pycharm最有必要改的几个默认设置项
Feb 14 Python
Python反爬虫伪装浏览器进行爬虫
Feb 28 Python
Python 统计位数为偶数的数字代码详解
Mar 15 Python
python实现横向拼接图片
Mar 23 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
php支持中文字符串分割的函数
2015/05/28 PHP
php实现的双色球算法示例
2017/06/20 PHP
PHP异常类及异常处理操作实例详解
2018/12/19 PHP
mysqli扩展无法在PHP7下升级问题的解决
2019/09/10 PHP
Yii框架 session 数据库存储操作方法示例
2019/11/18 PHP
PHP常量及变量区别原理详解
2020/08/14 PHP
解决PHP Opcache 缓存刷新、代码重载出现无法更新代码的问题
2020/08/24 PHP
js split 的用法和定义 js split分割字符串成数组的实例代码
2012/05/13 Javascript
使用coffeescript编写node.js项目的方法汇总
2015/08/05 Javascript
全面解析bootstrap格子布局
2016/05/22 Javascript
js不间断滚动的简单实现
2016/06/03 Javascript
EasyUI中在表单提交之前进行验证
2016/07/19 Javascript
jQuery过滤选择器经典应用
2016/08/18 Javascript
jQuery EasyUI tree 使用拖拽时遇到的错误小结
2016/10/10 Javascript
jQuery右下角悬浮广告实例
2016/10/17 Javascript
Bootstrap select实现下拉框多选效果
2016/12/23 Javascript
vue-router 学习快速入门
2017/03/01 Javascript
jQuery remove()过滤被删除的元素(推荐)
2017/07/18 jQuery
vue2.0 axios跨域并渲染的问题解决方法
2018/03/08 Javascript
vue百度地图 + 定位的详解
2019/05/13 Javascript
详解三种方式在React中解决绑定this的作用域问题并传参
2020/08/18 Javascript
[01:38]完美世界高校联赛决赛花絮
2018/12/02 DOTA
跟老齐学Python之玩转字符串(1)
2014/09/14 Python
浅析Python中的多进程与多线程的使用
2015/04/07 Python
Python入门_学会创建并调用函数的方法
2017/05/16 Python
浅谈python中的正则表达式(re模块)
2017/10/17 Python
Python字符串对象实现原理详解
2019/07/01 Python
python os.fork() 循环输出方法
2019/08/08 Python
python openpyxl模块的使用详解
2021/02/25 Python
领先的钻石和订婚戒指零售商:Diamonds-USA
2016/12/11 全球购物
台湾流行服饰购物平台:OB严选
2018/01/21 全球购物
澳大利亚墨尔本的在线时装店:LORETA
2018/09/14 全球购物
斯福泰克软件测试面试题
2015/02/16 面试题
关于幼儿的自我评价
2013/12/18 职场文书
2014年后勤管理工作总结
2014/12/01 职场文书
课外活动总结
2015/02/04 职场文书