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 ...
随机推荐
- React-Native(三):React Native是基于React设计的
React Native是基于React js设计的. 参考:<React 入门实例教程> React 起源于 Facebook 的内部项目,因为该公司对市场上所有 JavaScript ...
- c#:ThreadPool实现并行分析,并实现线程同步结束
背景: 一般情况下,经常会遇到一个单线程程序时执行对CPU,MEMORY,IO利用率上不来,且速度慢下问题:那么,怎么解决这些问题呢? 据我个人经验来说有以下两种方式: 1.并行.多线程(Parall ...
- 玩转Ecs服务器之搭建Ftp
以前一直没用过linux,直到阿里搞活动,所以买了台服务器玩玩,熟悉一下linux命令,哈哈. 阿里的官方文档介绍的还是比较详细的,但是你可能还是会遇到一些问题,在这里呢,不推荐配置本地用户的方式,因 ...
- X5 Blink下文字自动变大
在X5 Blink中,页面排版时会主动对字体进行放大,会检测页面中的主字体,当某一块的字体在我们的判定规则中,认为字体的字号较小,并且是页面中的主要字体,就会采用主动放大的操作.这显然不是我们想要的. ...
- javaApplication中如何使用log4j
- POJ2135:Farm Tour
题意:给定一个无向图,从1走到n再从n走回1,每个边只能走一遍,求最短路 题解:可以定义一个源点s,和一个汇点t s和1相连容量为2,费用为0, t和n相连容量为2,费用为0 然后所用的边的容量都定为 ...
- 【 lca倍增模板】
题目描述 对于 n(<100000)个点 n-1 条掉权值的边,有 m 个询问,每条询问求两个结点之间的路径上边权的最小值 输入 第一行 n,表示结点个数,接下来 n-1 行,每行 a b w ...
- ●BZOJ 3545 [ONTAK2010]Peaks(离线)
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=3545 http://www.lydsy.com/JudgeOnline/problem.ph ...
- 【Codeforces Round #431 (Div. 1) D.Shake It!】
·最小割和组合数放在了一起,产生了这道题目. 英文题,述大意: 一张初始化为仅有一个起点0,一个终点1和一条边的图.输入n,m表示n次操作(1<=n,m<=50),每次操作是任选一 ...
- 例 7-10 uva12212(迭代加深搜索)
题意:对于一段数字,每次可以剪切一段连续的自然数,粘贴到任意部分,使其变成升序 思路: 考虑的是进行搜索,深搜并不能保证是最短,广搜感觉每层的情况太多. 迭代加深:枚举搜索深度,然后进行深搜. 这种方 ...