OpenCV的图形用户界面(Graphical User Interface, GUI)和绘图等相关功能也是很有用的功能,无论是可视化,图像调试还是我们这节要实现的标注任务,都可以有所帮助。

窗口循环

OpenCV显示一幅图片的函数是cv2.imshow(),第一个参数是显示图片的窗口名称,第二个参数是图片的array。不过如果直接执行这个函数的话,什么都不会发生,因为这个函数得配合cv2.waitKey()一起使用。cv2.waitKey()指定当前的窗口显示要持续的毫秒数,比如cv2.waitKey(1000)就是显示一秒,然后窗口就关闭了。比较特殊的是cv2.waitKey(0),并不是显示0毫秒的意思,而是一直显示,直到有键盘上的按键被按下,或者鼠标点击了窗口的小叉子才关闭。cv2.waitKey()的默认参数就是0,所以对于图像展示的场景,cv2.waitKey()或者cv2.waitKey(0)是最常用的。

cv2.waitKey()参数不为零的时候则可以和循环结合产生动态画面。Python的itertools模块中的cycle函数可以把一个可遍历结构编程一个无限循环的迭代器。cv2.waitKey()返回的就是键盘上出发的按键。对于字母就是ascii码,特殊按键比如上下左右等,则对应特殊的值,其实这就是键盘事件的最基本用法。

鼠标和键盘事件

cv2.waitKey()就是获取键盘消息的最基本方法。下面这段循环代码就能够获取键盘上按下的按键,并在终端输出:

while key != 27:
cv2.imshow('Honeymoon Island', img)
key = cv2.waitKey()
# 如果获取的键值小于256则作为ascii码输出对应字符,否则直接输出值
msg = '{} is pressed'.format(chr(key) if key < 256 else key)
print(msg)

通过这个程序我们能获取一些常用特殊按键的值。

需要注意的是在不同的操作系统里这些值可能是不一样的。鼠标事件比起键盘事件稍微复杂一点点,需要定义一个回调函数,然后把回调函数和一个指定名称的窗口绑定,这样只要鼠标位于画面区域内的事件就都能捕捉到。把下面这段代码插入到上段代码的while之前,就能获取当前鼠标的位置和动作并输出:

# 定义鼠标事件回调函数
def on_mouse(event, x, y, flags, param): # 鼠标左键按下,抬起,双击
if event == cv2.EVENT_LBUTTONDOWN:
print('Left button down at ({}, {})'.format(x, y))
elif event == cv2.EVENT_LBUTTONUP:
print('Left button up at ({}, {})'.format(x, y))
elif event == cv2.EVENT_LBUTTONDBLCLK:
print('Left button double clicked at ({}, {})'.format(x, y)) # 鼠标右键按下,抬起,双击
elif event == cv2.EVENT_RBUTTONDOWN:
print('Right button down at ({}, {})'.format(x, y))
elif event == cv2.EVENT_RBUTTONUP:
print('Right button up at ({}, {})'.format(x, y))
elif event == cv2.EVENT_RBUTTONDBLCLK:
print('Right button double clicked at ({}, {})'.format(x, y)) # 鼠标中/滚轮键(如果有的话)按下,抬起,双击
elif event == cv2.EVENT_MBUTTONDOWN:
print('Middle button down at ({}, {})'.format(x, y))
elif event == cv2.EVENT_MBUTTONUP:
print('Middle button up at ({}, {})'.format(x, y))
elif event == cv2.EVENT_MBUTTONDBLCLK:
print('Middle button double clicked at ({}, {})'.format(x, y)) # 鼠标移动
elif event == cv2.EVENT_MOUSEMOVE:
print('Moving at ({}, {})'.format(x, y)) # 为指定的窗口绑定自定义的回调函数
cv2.namedWindow('Honeymoon Island')
cv2.setMouseCallback('Honeymoon Island', on_mouse)

标注小工具

基本思路是对要标注的图像建立一个窗口循环,然后每次循环的时候对图像进行一次拷贝。鼠标在画面上画框的操作,以及已经画好的框的相关信息在全局变量中保存,并且在每个循环中根据这些信息,在拷贝的图像上再画一遍,然后显示这份拷贝的图像。

基于这种实现思路,使用上我们采用一个尽量简化的设计:

- 输入是一个文件夹,下面包含了所有要标注物体框的图片。如果图片中标注了物体,则生成一个相同名称加额外后缀名的文件保存标注信息。

- 标注的方式是按下鼠标左键选择物体框的左上角,松开鼠标左键选择物体框的右下角,鼠标右键删除上一个标注好的物体框。所有待标注物体的类别,和标注框颜色由用户自定义,如果没有定义则默认只标注一种物体,定义该物体名称叫“Object”。

- 方向键的←和→用来遍历图片,↑和↓用来选择当前要标注的物体,Delete键删除一张图片和对应的标注信息。

每张图片的标注信息,以及自定义标注物体和颜色的信息,用一个元组表示,第一个元素是物体名字,第二个元素是代表BGR颜色的tuple或者是代表标注框坐标的元组。对于这种并不复杂复杂的数据结构,我们直接利用Python的repr()函数,把数据结构保存成机器可读的字符串放到文件里,读取的时候用eval()函数就能直接获得数据。这样的方便之处在于不需要单独写个格式解析器。如果需要可以在此基础上再编写一个转换工具就能够转换成常见的Pascal VOC的标注格式或是其他的自定义格式。

在这些思路和设计下,我们定义标注信息文件的格式的例子如下:

('Hill', ((221, 163), (741, 291)))
('Horse', ((465, 430), (613, 570)))

元组中第一项是物体名称,第二项是标注框左上角和右下角的坐标。这里之所以不把标注信息的数据直接用pickle保存,是因为数据本身不会很复杂,直接保存还有更好的可读性。自定义标注物体和对应标注框颜色的格式也类似,不过更简单些,因为括号可以不写,具体如下:

'Horse', (255, 255, 0)
'Hill', (0, 255, 255)
'DiaoSi', (0, 0, 255)

第一项是物体名称,第二项是物体框的颜色。使用的时候把自己定义好的内容放到一个文本里,然后保存成和待标注文件夹同名,后缀名为labels的文件。比如我们在一个叫samples的文件夹下放上一些草原的照片,然后自定义一个samples.labels的文本文件。把上段代码的内容放进去,就定义了小山头的框为黄色,骏马的框为青色,以及红色的屌丝。

opencv(5)GUI的更多相关文章

  1. 使用Qt创建第一个OpenCV的Gui应用

    写在前面 学习OpenCV有一些小日子了,发现群里还有很多初学OpenCV的人像我当初一样跌跌撞撞到处找资料,所以在这里把学习笔记分享给大家,希望有志学习OpenCV进行计算机视觉活动的小伙伴们能少走 ...

  2. EmguCV学习 与opencv的区别和联系

    openCV是因特尔的一个开源的视觉库,里面几乎包含了所有的图像处理的经典算法,并且采用C和少量的C++编写,运行效率很高,对于做图像处理这方面工作的,认识opencv是必须的工作.不过opencv有 ...

  3. opencv 61篇

    (一)--安装配置.第一个程序 标签: imagebuildincludeinputpathcmd 2011-10-21 16:16 41132人阅读 评论(50) 收藏 举报  分类: OpenCV ...

  4. 图像显示与加载——opencv(转)

    cvLoadImage() 函数:IplImage* cvLoadImage("图像名称",参数): 函数作用:加载图片: 函数返回值:为IplImage结构体: 参数说明:参数值 ...

  5. opencv在arm和x86在移植

    一个.开发环境 操作系统:fedora14 Opencv版本号:2.0 Qt版本号:4.7 arm:mini6410 交叉编译工具:arm-linux-gcc-4.5.1 二.安装与配置 Linux系 ...

  6. OpenCV学习笔记:opencv_highgui模块

    一,简介 本模块为跨平台的gui/IO组件,支持平台包括windows,linux,mac,IOS,android,可支持图像/视频/摄像头的读取显示以及转码. 二,分析 本模块为跨平台的gui/IO ...

  7. OpenCV学习笔记(六十二)——《OpenCV Computer Version with Python》阅读摘要

    如今python火啊.每次OpenCV自带的ml模块都让我直呼坑爹,索性准备用python来做OpenCV后期的机器学习算法的处理.于是赶紧拿起这本书读读. 适合OpenCV和python都有一定基础 ...

  8. Qt QImage与OpenCV Mat转换

    本系列文章由 @yhl_leo 出品,转载请注明出处. 文章链接: http://blog.csdn.net/yhl_leo/article/details/51029382 应一个朋友的要求,整理总 ...

  9. opencv数据结构与基本绘图

    #include <opencv2\core\core.hpp>//核心组件 #include <opencv2\opencv.hpp>//GUI,包含媒体输入输出,视频捕捉. ...

随机推荐

  1. android studio 怎么做屏幕适配?

    一.关于布局适配建议1.不要使用绝对布局2.尽量使用match_parent 而不是fill_parent .3.能够使用权重的地方尽量使用权重(android:layout_weight)4.如果是 ...

  2. fzyzojP3580 -- [校内训练-互测20180315]小基的高智商测试

    题目还有一个条件是,x>y的y只会出现一次(每个数直接大于它的只有一个) n<=5000 是[HNOI2015]实验比较 的加强版 g(i,j,k)其实可以递推:g(i,j,k)=g(i- ...

  3. python学习(22) 访问数据库

    原文链接:http://www.limerence2017.com/2018/01/11/python22/ 本文介绍python如何使用数据库方面的知识. SQLite SQLite是一种嵌入式数据 ...

  4. mac python2.7.10 升级到 3.6

    第一步: 下载当前最新版本 Python3.6,下载地址:https://www.python.org/downloads/ 第二步: 安装下载好的包,安装完成后的目录如下: /Library/Fra ...

  5. Liunx操作指令搜素引擎

    链接:http://wangchujiang.com/linux-command/c/vi.html

  6. Linux根目录解析

    根目录结构如下: 1. / - 根目录: 每一个文件和目录都从这里开始. 只有root用户具有该目录下的写权限.此目录和/root目录不同,/root目录是root用户的主目录. 2. /bin - ...

  7. a标签伪元素选择器

    a{ color: black; } /*未访问的链接*/ a:link{ color: red; } /*访问过的链接*/ a:visited{ color: green; } /*鼠标经过时*/ ...

  8. Angular5基本入门

    基本环境安装 首先,确定安装了nodejs与npm,angular 5要求node版本在6.9.x以上.npm版本在 3.x.x以上: 1.安装@angular/cli npm install -g ...

  9. wait&waitpid状态值

    [wait&waitpid状态值] 1.  python 中 os.system 的返回值的format与wait的返回值status一致: On Unix, the return value ...

  10. 数据库日志文件(databasename_log.ldf)太大 如何清除

    在SQL2008中清除日志就必须在简单模式下进行,等清除动作完毕再调回到完全模式.方案一:完全命令模式USE[master] GO ALTER DATABASE DNName SET RECOVERY ...