Python图像处理(3):视频显示

快乐虾

http://blog.csdn.net/lights_joy/(QQ群:Visual EmbedLinux Tools 375515651)

欢迎转载,但请保留作者信息

1.    用OpenCV进行视频显示

之前用OpenCV做了一个简单的视频显示:

# -*- coding: utf-8 -*-
# 使用OpenCV播放视频
import cv2

wnd = ‘OpenCV Video‘

#获得视频的格式
videoCapture = cv2.VideoCapture(‘f:\\tmp\\cotton.mp4‘)

#获得码率及尺寸
fps = videoCapture.get(cv2.cv.CV_CAP_PROP_FPS)
size = (int(videoCapture.get(cv2.cv.CV_CAP_PROP_FRAME_WIDTH)),
        int(videoCapture.get(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT)))

cv2.namedWindow(wnd, flags=0)
cv2.resizeWindow(wnd, size[0]/2, size[1]/2)

# 读帧
success, frame = videoCapture.read()

while success :
    cv2.imshow(wnd, frame) #显示
    cv2.waitKey(1000 / int(fps)) #延迟
    success, frame = videoCapture.read() #获取下一帧

完全用cv2做视频读取和显示,这个程序有两个问题,一个是cv2窗口的缩放问题导致视频图像的变形,另一个是opencv提供的界面控制功能很弱,甚至于它都不提供在界面上显示按纽的能力,因此我们想办法替换界面显示的部分。

2.    用wxFormBuilder构建界面

wxFormBuilder是一个使用wxWidgets的UI界面设计工具,可以很直观地进行UI设计,并生成C++/Python/Lua/Xrc相关的代码。我们用它构建视频播放器的界面:

在主窗口上留下一个Panel控件用以嵌入matplotlib的窗口。

wxFormBuilder自动生成了Python代码:

# -*- coding: utf-8 -*- 

###########################################################################
## Python code generated with wxFormBuilder (version Jun  5 2014)
## http://www.wxformbuilder.org/
##
## PLEASE DO "NOT" EDIT THIS FILE!
###########################################################################

import wx
import wx.xrc

###########################################################################
## Class MainFrame
###########################################################################

class MainFrame ( wx.Frame ):

	def __init__( self, parent ):
		wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = u"Video Player", pos = wx.DefaultPosition, size = wx.Size( 757,562 ), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL )

		self.SetSizeHintsSz( wx.DefaultSize, wx.DefaultSize )

		self.m_timer = wx.Timer()
		self.m_timer.SetOwner( self, wx.ID_ANY )
		self.m_timer.Start( 40 )

		MainSizer = wx.BoxSizer( wx.VERTICAL )

		ButtonSizer = wx.BoxSizer( wx.HORIZONTAL )

		self.m_btnStart = wx.Button( self, wx.ID_ANY, u"开始", wx.DefaultPosition, wx.DefaultSize, 0 )
		ButtonSizer.Add( self.m_btnStart, 0, wx.ALL, 5 )

		self.m_btnStop = wx.Button( self, wx.ID_ANY, u"停止", wx.DefaultPosition, wx.DefaultSize, 0 )
		ButtonSizer.Add( self.m_btnStop, 0, wx.ALL, 5 )

		MainSizer.Add( ButtonSizer, 0, wx.EXPAND, 5 )

		PanelSizer = wx.StaticBoxSizer( wx.StaticBox( self, wx.ID_ANY, u"Matplotlib 控制区" ), wx.VERTICAL )

		self.m_pnlMatplot = wx.Panel( self, wx.ID_ANY, wx.DefaultPosition, wx.Size( -1,-1 ), 0 )
		MatplotSizer = wx.BoxSizer( wx.VERTICAL )

		self.m_pnlMatplot.SetSizer( MatplotSizer )
		self.m_pnlMatplot.Layout()
		MatplotSizer.Fit( self.m_pnlMatplot )
		PanelSizer.Add( self.m_pnlMatplot, 1, wx.EXPAND |wx.ALL, 5 )

		MainSizer.Add( PanelSizer, 1, wx.EXPAND, 5 )

		self.SetSizer( MainSizer )
		self.Layout()

		self.Centre( wx.BOTH )

		# Connect Events
		self.Bind( wx.EVT_TIMER, self.OnTimer, id=wx.ID_ANY )
		self.m_btnStart.Bind( wx.EVT_BUTTON, self.OnStart )
		self.m_btnStop.Bind( wx.EVT_BUTTON, self.OnStop )

	def __del__( self ):
		pass

	# Virtual event handlers, overide them in your derived class
	def OnTimer( self, event ):
		event.Skip()

	def OnStart( self, event ):
		event.Skip()

	def OnStop( self, event ):
		event.Skip()

直接在此播放器工程中新建一个py文件,再将此代码复制到我们的播放器工程中,加上App和事件循环:

app = wx.App()
frame = MainFrame(None)
frame.Show()
app.MainLoop()

3.    编码问题

在上节中直接在python工程中建立了一个新的py文件并将wxFormBuilder生成的代码复制过来,结果很悲摧:

更改此文件的编码为UTF-8:

再运行就好了:

4.    加上matplotlib显示

接下来加上matplotlib显示功能。

首先在Frame初始化的时候创建matplotlib所需要的canvas:

        self.mpl_control = FigureCanvas(self.m_pnlMatplot, -1, plt.gcf())
        MatplotSizer.Add(self.mpl_control, 1, wx.LEFT | wx.TOP | wx.GROW)

在按下开始的时候打开文件和定时器:

    def OnStart( self, event ):
        self.videoCapture = cv2.VideoCapture(‘f:\\tmp\\cotton.mp4‘)
        if(self.videoCapture == None):
            wx.SafeShowMessage(‘start‘, ‘Open Failed‘)
            return
        self.fps = self.videoCapture.get(cv2.cv.CV_CAP_PROP_FPS)
        self.m_timer.Start(100)

在按下停止的时候停止定时器:

    def OnStop( self, event ):
        self.m_timer.Stop()

在定时器事件中绘图:

    def OnTimer( self, event ):
        success, self.frame = self.videoCapture.read()
        if(success) :
            plt.imshow(self.frame)
            self.mpl_control.draw_idle()

运行的结果就是这样的:

5.    内存泄漏

在上述代码中,运行时存在严重的内存泄漏,在视频播放的时候内存使用率不断上升。

查一下imshow的代码:

    @docstring.dedent_interpd
    def imshow(self, X, cmap=None, norm=None, aspect=None,
               interpolation=None, alpha=None, vmin=None, vmax=None,
               origin=None, extent=None, shape=None, filternorm=1,
               filterrad=4.0, imlim=None, resample=None, url=None, **kwargs):
        """
        Display an image on the axes.
......
        """
......
        im = mimage.AxesImage(self, cmap, norm, interpolation, origin, extent,
                       filternorm=filternorm,
                       filterrad=filterrad, resample=resample, **kwargs)

        im.set_data(X)
        im.set_alpha(alpha)
        if im.get_clip_path() is None:
            # image does not already have clipping set, clip to axes patch
            im.set_clip_path(self.patch)
        #if norm is None and shape is None:
        #    im.set_clim(vmin, vmax)
        if vmin is not None or vmax is not None:
            im.set_clim(vmin, vmax)
        else:
            im.autoscale_None()
        im.set_url(url)

        # update ax.dataLim, and, if autoscaling, set viewLim
        # to tightly fit the image, regardless of dataLim.
        im.set_extent(im.get_extent())

        self.add_image(im)
        return im

在这个函数的末尾使用

self.add_image(im)

将创建出来的图像添加到了图像列表中,而不是替换已经有的图像,这就导致了内存不断上升!知道原因后就容易处理了,修改我们的代码,在显示图像前删除之前的图像:

    # Virtual event handlers, overide them in your derived class
    def OnTimer( self, event ):
        success, self.frame = self.videoCapture.read()
        if(success) :
            if(self.image != None) :
                self.image.remove()
            (b, g, r) = cv2.split(self.frame)
            self.frame = cv2.merge([r,g,b])
            self.image = plt.imshow(self.frame)
            self.mpl_control.draw_idle()

搞定!

??

时间: 2024-10-07 17:53:47

Python图像处理(3):视频显示的相关文章

Python图像处理库PIL中图像格式转换(一)

在数字图像处理中,针对不同的图像格式有其特定的处理算法.所以,在做图像处理之前,我们需要考虑清楚自己要基于哪种格式的图像进行算法设计及其实现.本文基于这个需求,使用python中的图像处理库PIL来实现不同图像格式的转换. 对于彩色图像,不管其图像格式是PNG,还是BMP,或者JPG,在PIL中,使用Image模块的open()函数打开后,返回的图像对象的模式都是"RGB".而对于灰度图像,不管其图像格式是PNG,还是BMP,或者JPG,打开后,其模式为"L". 通

Python图像处理库(1)

转自:http://www.ituring.com.cn/tupubarticle/2024 第 1 章 基本的图像操作和处理 本章讲解操作和处理图像的基础知识,将通过大量示例介绍处理图像所需的 Python 工具包,并介绍用于读取图像.图像转换和缩放.计算导数.画图和保存结果等的基本工具.这些工具的使用将贯穿本书的剩余章节. 1.1 PIL:Python图像处理类库 PIL(Python Imaging Library Python,图像处理类库)提供了通用的图像处理功能,以及大量有用的基本图

Python图像处理类库

本章讲解操作和处理图像的基础知识,将通过大量示例介绍处理图像所需的 Python 工具包,并介绍用于读取图像.图像转换和缩放.计算导数.画图和保存结果等的基本工具.这些工具的使用将贯穿本书的剩余章节. 1.1 PIL:Python图像处理类库 PIL(Python Imaging Library Python,图像处理类库)提供了通用的图像处理功能,以及大量有用的基本图像操作,比如图像缩放.裁剪.旋转.颜色转换等.PIL 是免费的,可以从 http://www.pythonware.com/pr

Python图像处理(1):替换OpenCV

快乐虾 http://blog.csdn.net/lights_joy/(QQ群:Visual EmbedLinux Tools 375515651) 欢迎转载,但请保留作者信息 先前构造图像处理开发环境的时候,用一个别人编译好的安装包将OpenCV安装到了c:\python27\lib\site-packages目录下,但这个OpenCV没有符号表,无法进行C/C++的代码调试.我们用VS编译的OpenCV替换它. 首先修改OpenCV的Python接口工程,将其输出到python的库目录下,

Python图像处理库PIL的ImageOps模块介绍

(Newin 1.1.3)ImageOps模块包含了一些"ready-made"的图像处理操作.这个模块somewhatexperimental,大多数操作只工作在L和RGB图像上. 一.ImageOps模块的函数 1.  Autocontrast 定义:ImageOps.autocontrast(image, cutoff=0)? image 含义:最大图像对比度.这个函数计算一个输入图像的直方图,从这个直方图中去除最亮和最暗的百分之cutoff,然后重新映射图像,以便保留的最暗像素

Python图像处理库(PIL)

Python Imaging Library为您的python程序添加图像处理能力.这个库提供广泛的文件格式支持.高效的内部表示和相当强大的图像处理能力. 核心图像库是为快速访问几种基本像素格式图像设计的.它能为一般的图像处理工具提供一个可靠的基础. 这个Pythonic library可以 装载和保存多种格式文件 Loading and Saving images (diverse formats)  Python Imaging Library的最新版本可以识别并读取多数图像格式.写图像操作

python 图像处理(从安装Pillow开始)

python2.x及以下用的是PIL(图像处理库是 PIL(Python Image Library)),最新版本是 1.1.7  可在http://www.pythonware.com/products/pil/index.htm 下载和学习. 不过从该网站可看出它不支持python3.x Pillow由PIL而来(支持3.x),所以该导入该库使用import PIL 由于本人用的是python 3.4 所以下载的Pillow 关于下载第三方库,有三种方法,之前用的都是 第一种方法 1 下载第

Python_Imaging_Library中文手册、PIL中文手册、python图像处理

Python Imaging Library 中文手册 这是PIL的官方手册,2005年5月6日发布.这个版本涵盖 PIL 1.1.5的全部内容.本中文手册来自Woodpecker.org.cn 啄木鸟社区 你可以在PythonWare library找到改文档其它格式的版本以及先前的版本. 原版出处:http://www.pythonware.com/library/pil/handbook/ 目录 Python Imaging Library 中文手册 第一部分:介绍 概览 介绍 图像归档处

Python图像处理PIL库简介

搬运自本人博客:http://www.xgezhang.com/python_pil.html 最近用到一些简单的图像处理,这里简单介绍一下,Python Imaging Library (PIL)是PythonWare公司提供的免费的图像处理工具包,是python下的图像处理模块,支持多种格式,并提供强大的图形与图像处理功能.虽然在这个软件包上要实现类似MATLAB中的复杂的图像处理算法并不太适合,但是Python的快速开发能力以及面向对象等等诸多特点使得它非常适合用来进行原型开发.对于简单的