opencv视屏流嵌入wxpython框架
前几篇博客分享搭建人脸识别与情绪判断的环境和源码,但是没有UI,界面很难看,一打开就是opencv弹出的一个视屏框。处女座的我看着非常难受,于是决定做一个UI,稍微规矩好看一点,再怎么说,这样的话也算是一个小软件,不再是运行源码了。
上网到处查了一圈之后,发现这是一个空缺,好像没有人在做这个,看到的唯一一个有点相似的是用wxpython制作一个视屏播放器。和这个显示opencv的实时视屏还是有点差距的,但是也有指导作用。
使用版本:python-3.6.3(anaconda) opencv-3.4.1 wxpython-4.0.1
运行流程:
1、运行程序时,先显示封面页
2、用户点击【start】后开始opencv读取视屏,dlib开始处理,并进行情绪判断
3、用户点击【close】后,结束视屏,回到封面页。等待再次点击开始
一、实例化frame、添加控件
def __init__(self,parent,title):
wx.Frame.__init__(self,parent,title=title,size=(600,600))
self.panel = wx.Panel(self)
self.Center() # 封面图片
self.image_cover = wx.Image(COVER, wx.BITMAP_TYPE_ANY).Scale(350,300)
# 显示图片在panel上
self.bmp = wx.StaticBitmap(self.panel, -1, wx.Bitmap(self.image_cover)) start_button = wx.Button(self.panel,label='Start')
close_button = wx.Button(self.panel,label='Close') self.Bind(wx.EVT_BUTTON,self.learning_face,start_button)
self.Bind(wx.EVT_BUTTON,self.close_face,close_button)
这段初始化的程序,就添加了一个图片,两个按钮,并为按钮绑定了各自的动作函数。这里使用wx.Image方法读取一个任意格式的照片,交给staticbitmap,开始在panel面板上显示这个图片。
二、基于GridBagSizer的界面布局
界面布局有很多方法可以使用,这里使用gridbagsizer进行界面布局。
它把一个面板抽象成一个网格,我们可以想象在excel中的样子,格子的大小比例根据自己的设置进行放大缩小。但是总面积不变。 # 基于GridBagSizer的界面布局
# 先实例一个对象
self.grid_bag_sizer = wx.GridBagSizer(hgap=5,vgap=5)
# 注意pos里面是先纵坐标后横坐标
self.grid_bag_sizer.Add(self.bmp, pos=(0, 0), flag=wx.ALL | wx.EXPAND, span=(4, 4), border=5)
self.grid_bag_sizer.Add(start_button, pos=(4, 1), flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, span=(1, 1), border=5)
self.grid_bag_sizer.Add(close_button, pos=(4, 2), flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, span=(1, 1), border=5) self.grid_bag_sizer.AddGrowableCol(0,1)
self.grid_bag_sizer.AddGrowableRow(0,1)
self.panel.SetSizer(self.grid_bag_sizer)
# 界面自动调整窗口适应内容
self.grid_bag_sizer.Fit(self)
使用Add方法把控件添加到网格中,pos是坐标,span是这个控件需要跨越的行列数,这两个参数基本上就可以确定一个控件的位置和大小了。
下面的fit方法就是确保这个控件会随着面板的拖大拖小而进行相应的比例移动。
三、按钮动作
既然控件的位置格式都摆放整齐了,下面就是他们的动作绑定了。
点击开始,会开始opencv读取视屏,然后把每一帧图片交给dlib进行人脸识别与特征点的标定,然后在进行显示。
原来是调用opencv的imshow方法来进行显示的,具体这句话为:cv2.imshow("camera", im_rd),那么我们想让这一帧显示在wxpython的框架内怎办呢?
把刚才的封面页换成opencv的每一帧不就可以了吗!
cv2.imshow("camera", im_rd),是循环显示它的每一帧图片,只是换了个方法而已,其实原理都是一样 的。循环显示每一帧图片,就成了视屏;
所以归根结底,这个问题就是显示一个图片的问题。
好像还是有点不对。我们显示图片的格式是JPG图片,那么这个 im_rd 是什么格式呢?
还记得这一段码:
# cap.read()
# 返回两个值:
# 一个布尔值true/false,用来判断读取视频是否成功/是否到视频末尾
# 图像对象,图像的三维矩阵
flag, im_rd = self.cap.read()
他是一个三维的矩阵。
这时,我们需要用下面的方法对这一帧的数据进行转化,显示、
# 现将opencv截取的一帧图片BGR转换为RGB,然后将图片显示在UI的框架中
height,width = im_rd.shape[:2]
image1 = cv2.cvtColor(im_rd, cv2.COLOR_BGR2RGB)
pic = wx.Bitmap.FromBuffer(width,height,image1)
# 显示图片在panel上
self.bmp.SetBitmap(pic)
self.grid_bag_sizer.Fit(self)
这样就可以将视屏的每一帧数据显示在wxpython的panel面板上面。
四、简单多线程
在我能够点击start开始在框架内部显示视屏的时候,我想拖动一下这个框架,但是程序竟然卡死了!无响应???what??
查了资料才知道,我们的程序只有一个线程,这时程序正在while死循环里面进行视屏显示,占用了这唯一的一个线程,如果我们进行UI操作的话,程序就会被崩溃。
解决办法就是,创建一个新的线程,让按钮的动作函数在这个新的子线程中执行,主线程我们进行UI的操作,比如框架的拖动,放大缩小。
def learning_face(self,event):
"""使用多线程,子线程运行后台的程序,主线程更新前台的UI,这样不会互相影响"""
import _thread
# 创建子线程,按钮调用这个方法,
_thread.start_new_thread(self._learning_face, (event,))
这时,我们点击按钮start后,开始执行这个方法,先创建一个子线程,然后在这个方法中调用之前那个方法。就是对之前的那个方法进行了进一步的封装。
这样就不会出现卡死的现象了。


完整程序代码:https://gitee.com/Andrew_Qian/codes/acm80fr6ekjwgpz27bthd35
opencv视屏流嵌入wxpython框架的更多相关文章
- OpenCV视屏跟踪
#include <stdio.h> #include <iostream> #include "opencv2/imgproc/imgproc.hpp" ...
- opencv读取并播放avi视屏
视屏的本质是一些静态的图像的集合,opencv可以不断读取视屏中的图片,显示,就产生了类似电影的效果. 这样也就可以通过opencv对实时的视屏流进行处理了. #include "stdaf ...
- iOS:简易的音视屏播放框架XYQPlayer
一.前缀 一直都想好好学学音视频这方面的知识,抽了几个周末参考一些资料,尝试着写了一个简易的音视频播放框架,支持音视频播放.视频截图.音乐缓存,其实吧,也就是尽可能的封装罢了,方便以后自己使用.目前只 ...
- 【学习笔记】兄弟连LINUX视屏教程(沈超 李明)
发现自己的linux水平楞个瓜皮,找个视屏教程学习一哈 1 linux系统简介 1.1 UNIX和Linux发展史 unix发展历史:1969年,美国贝尔实验室的肯.汤普森开发出unix系统,1971 ...
- MPEG-1视屏压缩标准
MPEG-1标准包括5个部分 图像的四种类型: I帧: B帧:双向帧间预测 P帧: D帧:只含有16分量,为快放设计 压缩前需要帧重排 视屏码流结构 I帧压缩 p帧压缩 b帧压缩 其他压缩算法 MPE ...
- FFmpeg + php 视屏转换
什么是FFmpeg? FFmpeg是一个开源免费跨平台的视频和音频流方案,属于自由软件,采用LGPL或GPL许可证(依据你选择的组件).它提供了录制.转换以及流化音视频的完整解决方案.它包含了非常先进 ...
- 原创:Equinox OSGi应用嵌入Jersey框架搭建REST服务
一.环境 eclipse版本:eclipse-luna 4.4 jre版本:1.8 二.Equinox OSGi应用嵌入Jersey框架搭建REST服务 1.新建插件工程HelloWebOSGI a. ...
- session失效后,登录页面嵌入iframe框架
在登录页面的onload方法中加入以下代码解决: //防止登录页面嵌入iframe框架 if (top.location != self.location){ top.location=self.lo ...
- wndows程序设计之书籍知识与代码摘录-获取视屏显示器像素等参数GetsystemMetrics
以下的代码段用于获取视屏显示器的高度宽度,以像素为单位. int sxScreen, cyScreen; cxScreen = GetSystemMetrics (SM_CXSCREEN); cySc ...
随机推荐
- mysql 查询select语句汇总
数据准备: 创建表: create table students( id int unsigned primary key auto_increment not null, name varchar( ...
- MVC、MVP以及MVVM分析
网上现在MVC.MVP以及MVVM的讲解一搜一箩筐,根据了网上大多数的文章,根据我的思考习惯进行了总结. MVC介绍及分析: 各层的职责如下所示: Models: 数据层,负责数据的处理和获取的数据接 ...
- Hive函数:SUM,AVG,MIN,MAX
转自:http://lxw1234.com/archives/2015/04/176.htm,Hive分析窗口函数(一) SUM,AVG,MIN,MAX 之前看到大数据田地有关于max()over(p ...
- Struts(二十三):使用声名式验证
Struts2工程中的验证分为两种: 1.基于XWork Validation Framework的声明式验证:Struts2提供了一些基于XWork Validation Framework的内建验 ...
- Spring学习之AOP与事务
一.概述 在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是OOP的延续, ...
- JS中的数据类型和转换
一.JS中的数据类型 js中的数据类型可以分为五种:number .string .boolean. underfine .null. number:数字类型 ,整型浮点型都包括. string:字符 ...
- Vue项目结构说明
简单介绍目录结构 http://blog.csdn.net/u013778905/article/details/53864289 (别人家的链接,留给我自己看的)
- 非黑即白--谷歌OCR光学字符识别
# coding=utf-8 #非黑即白--谷歌OCR光学字符识别 # 颜色的世界里,非黑即白.computer表示深信不疑. # 今天研究一下OCR光学识别庞大领域中的众多分支里的一个开源项目的一个 ...
- C#调用Python,报错No module named os
C#调用Python 环境:Windows 8.1,已经安装Python2.7(C:\Python27),配置了环境变量. 已经安装VS2013,VS2017 1.安装IronPython 下载地址h ...
- 远程连接服务器jupyter notebook、浏览器以及深度学习可视化方法
h1 { counter-reset: h2counter; } h2 { counter-reset: h3counter; } h3 { counter-reset: h4counter; } h ...