第一次用pyqt/pyside,遇到了很多问题。所有遇到的问题都是在视频发布这块遇到的,但最终还是成功了,在这里把遇到的问题总结一下。
读取视频中的帧,逐帧显示,显示的格式必须是Qimage,但是用cv2读取的帧格式是numpy array,必须把它转换成为Qimage,于是尝试了:
1. 利用pyqtgraph:
将numpy类型的frame通过pyqtgraph 转换为Qimage,随后通过setPixmap显示,程序在IDLE执行正确,但是在发布的时候,遇到了很多恶心的问题,由于是帮别人做,本人没有那么多时间去解决这个问题,于是采用了第二种办法。
frame,stat=pyqtgraph.makeARGB(frame, lut=None, levels=None, scale=None, useRGBA=True)
frame=pyqtgraph.makeQImage(frame, alpha=None, copy=True ,transpose=False)#
frame=QPixmap.fromImage(frame)
self.pictureLabel.setPixmap(frame)
2.利用PIL将图像保存,随后再通过Qimage读取,直接转换为Qimage格式:
但是用遇到了新的问题,通过cv2.VideoCapture("001.avi")读取的视频文件,通过下面的转化,颜色通道居然乱了,本人尝试过利用numpy.roll()将通道翻转,但效果不理想,而且减慢了速度,实在无奈~,于是有尝试了第三种办法
frame=Image.fromarray(frame)
frame.save('2.jpg')
self.image.load("2.jpg")
self.pictureLabel.setPixmap(QPixmap.fromImage(self.image))
3.利用cv2.cv.fromarray()转换读取的numpy帧,然后保存再读取~
这次成功了,通过pyinstaller打包以后终于可以正常显示了。
frame=cv2.cv.fromarray(frame)
cv2.cv.SaveImage('2.jpg',frame)
self.image.load("2.jpg")
self.pictureLabel.setPixmap(QPixmap.fromImage(self.image))
以上三种方法在IDLE中执行没有错误,就是在打包发布的时候遇到了错误。而且在包含pyqtgraph库的时候,打包发布过程中遇到了很多困难,最终迫使我放弃了使用pyqtgraph.
在利用pyinstaller打包的时候,也遇到了一些问题,本文用的是pyinstaller 2.1 版本.
首先cd进入pyinstaller , python setup.py install, 随后执行 python pyinstaller -F -w yourpy.py (-F是打包为一个文件,-w是windows版,没有小黑窗)。
建议在每一次打包之前都执行一次 python setup.py install (因此会避免很多麻烦)
在视频窗口的背景上放了一张图片,设为背景,如果他没有显示,在C:\Python27\Lib\site-packages\PyQt4\plugins找到imageformats这个文件夹,和exe放在一块,就行了,好了贴上程序:
程序有三个按钮,每个按钮按下去之后,会连续播放两个视频,再按一下会暂停。最终界面如下:
# -*- coding: utf-8 -*-
from PySide.QtGui import *
from PySide.QtCore import *
import PySide
import sys
import cv2
import time
from PIL import Image
import numpy
class MainWindow(PySide.QtGui.QWidget):
## video_list=[\
## r"d:\data\单井ch4扩散视频.mpeg",\
## r"d:\data\单井h2s扩散视频.mpeg",\
## r"d:\data\集气站ch4扩散视频.mpeg",\
## r"d:\data\集气站h2s扩散视频.mpeg",\
## r"d:\data\输气管线ch4扩散视频.mpeg",\
## r"d:\data\输气管线h2s扩散视频.mpeg",\
## ]
def __init__(self,parent = None):
PySide.QtGui.QWidget.__init__(self)
self.setWindowTitle(u'天然气泄漏fluent数值模拟视频演示')
self.status_1= 0 # 0: init 1:play vedio 2:camera
self.status_2= 0
self.status_3= 0
## self.video_1_0=self.video_list[0]
## self.video_1_1=self.video_list[1]
## self.video_2_0=self.video_list[2]
## self.video_2_1=self.video_list[3]
## self.video_3_0=self.video_list[4]
## self.video_3_1=self.video_list[5]
## self.video_1_0=r"d:\data\单井ch4扩散视频.mpeg"
## self.video_1_1=r"d:\data\单井h2s扩散视频.mpeg"
## self.video_2_0=r"d:\data\集气站ch4扩散视频.mpeg"
## self.video_2_1=r"d:\data\集气站h2s扩散视频.mpeg"
## self.video_3_0=r"d:\data\输气管线ch4扩散视频.mpeg"
## self.video_3_1=r"d:\data\输气管线h2s扩散视频.mpeg"
####
self.video_1_0=r"d:\data\001.mpeg"
self.video_1_1=r"d:\data\002.mpeg"
self.video_2_0=r"d:\data\003.mpeg"
self.video_2_1=r"d:\data\004.mpeg"
self.video_3_0=r"d:\data\005.mpeg"
self.video_3_1=r"d:\data\006.mpeg"
self.next_video_flag=False
self.image = QImage()
#set video file
self.playCapture_1_0 = cv2.VideoCapture(self.video_1_0)
self.playCapture_1_1 = cv2.VideoCapture(self.video_1_1)
self.playCapture_2_0 = cv2.VideoCapture(self.video_2_0)
self.playCapture_2_1 = cv2.VideoCapture(self.video_2_1)
self.playCapture_3_0 = cv2.VideoCapture(self.video_3_0)
self.playCapture_3_1 = cv2.VideoCapture(self.video_3_1)
self.playButton_1 = QPushButton(u"输送管线")
self.playButton_2 = QPushButton(u"单井")
self.playButton_3 = QPushButton(u"集气站")
vbox = QVBoxLayout() #vertical layout
vbox.addWidget(self.playButton_1)
vbox.addWidget(self.playButton_2)
vbox.addWidget(self.playButton_3)
self.pictureLabel = QLabel("picture")
hbox=QHBoxLayout()
hbox.addStretch(0)
hbox.addLayout(vbox)
hbox.addWidget(self.pictureLabel)
self.setLayout(hbox)
self.set_background()
# set timeout
self.timer_1 = Timer() # save video
self.timer_2 = Timer() # save video
self.timer_3 = Timer() # save video
self.playTimer_1 = Timer("updatePlay()")
self.playTimer_2 = Timer("updatePlay()")
self.playTimer_3 = Timer("updatePlay()")
self.connect(self.playTimer_1, SIGNAL("updatePlay()"), self.PlayVideo_1)
self.connect(self.playTimer_2, SIGNAL("updatePlay()"), self.PlayVideo_2)
self.connect(self.playTimer_3, SIGNAL("updatePlay()"), self.PlayVideo_3)
#self.connect(exitButton, SIGNAL("clicked()"), app, SLOT("quit()"))
self.connect(self.playButton_1, SIGNAL("clicked()"), self.VideoPlayPause_1)
self.connect(self.playButton_2, SIGNAL("clicked()"), self.VideoPlayPause_2)
self.connect(self.playButton_3, SIGNAL("clicked()"), self.VideoPlayPause_3)
def set_background(self):
self.image.load(r"d:/data/background.jpg")
self.pictureLabel.setPixmap(QPixmap.fromImage(self.image))
def PlayVideo_1(self):
if self.next_video_flag==False and self.status_1==1 and self.status_2!=1 and self.status_3!=1 :
stat,frame = self.playCapture_1_0.read()
if stat==False:
self.next_video_flag=True
else :
#print 'frame'
frame=cv2.cv.fromarray(frame)
cv2.cv.SaveImage('2.jpg',frame)
self.image.load("2.jpg")
self.pictureLabel.setPixmap(QPixmap.fromImage(self.image))
if self.next_video_flag==True and self.status_1==1 and self.status_2!=1 and self.status_3!=1 :
stat,frame = self.playCapture_1_1.read()
if stat==False:
self.next_video_flag=False
self.playTimer_1.stop()
self.timer_1.stop()
self.set_background()
self.status_1, playStr=(1,u"输送管线")
self.playButton_1.setText(playStr)
self.playCapture_1_0 = cv2.VideoCapture(self.video_1_0)
self.status_1=0
else :
frame=cv2.cv.fromarray(frame)
cv2.cv.SaveImage('2.jpg',frame)
self.image.load("2.jpg")
self.pictureLabel.setPixmap(QPixmap.fromImage(self.image))
def PlayVideo_2(self):
if self.next_video_flag==False and self.status_2==1 and self.status_1!=1 and self.status_3!=1 :
stat,frame = self.playCapture_2_0.read()
if stat==False:
self.next_video_flag=True
else :
frame=cv2.cv.fromarray(frame)
cv2.cv.SaveImage('2.jpg',frame)
self.image.load("2.jpg")
self.pictureLabel.setPixmap(QPixmap.fromImage(self.image))
if self.next_video_flag==True and self.status_2==1 and self.status_1!=1 and self.status_3!=1 :
stat,frame = self.playCapture_2_1.read()
if stat==False:
self.next_video_flag=False
self.playTimer_2.stop()
self.timer_2.stop()
self.set_background()
self.status_2, playStr=(1,u"单井")
self.playButton_2.setText(playStr)
self.playCapture_2_0 = cv2.VideoCapture(self.video_2_0)
self.status_2=0
else :
frame=cv2.cv.fromarray(frame)
cv2.cv.SaveImage('2.jpg',frame)
self.image.load("2.jpg")
self.pictureLabel.setPixmap(QPixmap.fromImage(self.image))
def PlayVideo_3(self):
if self.next_video_flag==False and self.status_3==1 and self.status_2!=1 and self.status_1!=1 :
stat,frame = self.playCapture_3_0.read()
if stat==False:
self.next_video_flag=True
else :
frame=cv2.cv.fromarray(frame)
cv2.cv.SaveImage('2.jpg',frame)
self.image.load("2.jpg")
self.pictureLabel.setPixmap(QPixmap.fromImage(self.image))
if self.next_video_flag==True and self.status_3==1 and self.status_2!=1 and self.status_1!=1 :
stat,frame = self.playCapture_3_1.read()
if stat==False:
self.next_video_flag=False
self.playTimer_3.stop()
self.timer_3.stop()
self.set_background()
self.status_3, playStr=(1,u"集气站")
self.playButton_3.setText(playStr)
self.playCapture_3_0 = cv2.VideoCapture(self.video_3_0)
self.status_3=0
else :
frame=cv2.cv.fromarray(frame)
cv2.cv.SaveImage('2.jpg',frame)
self.image.load("2.jpg")
self.pictureLabel.setPixmap(QPixmap.fromImage(self.image))
def VideoPlayPause_1(self):
self.playCapture_2_0 = cv2.VideoCapture(self.video_2_0)
self.playCapture_2_1 = cv2.VideoCapture(self.video_2_1)
self.playCapture_3_0 = cv2.VideoCapture(self.video_3_0)
self.playCapture_3_1 = cv2.VideoCapture(self.video_3_1)
self.status_1, playStr = ((1,u'暂停'),
(0,u"输送管线"),
(1,u'暂停'))[self.status_1]
self.playButton_1.setText(playStr)
if self.status_1 is 1: #play video
self.timer_1.stop()
self.playTimer_1.start()
else:
self.playTimer_1.stop()
def VideoPlayPause_2(self):
self.playCapture_1_0 = cv2.VideoCapture(self.video_1_0)
self.playCapture_1_1 = cv2.VideoCapture(self.video_1_1)
self.playCapture_3_0 = cv2.VideoCapture(self.video_3_0)
self.playCapture_3_1 = cv2.VideoCapture(self.video_3_1)
self.status_2, playStr = ((1,u'暂停'),
(0,u"单井"),
(1,u'暂停'))[self.status_2]
self.playButton_2.setText(playStr)
if self.status_2 is 1: #play video
self.timer_2.stop()
self.playTimer_2.start()
else:
self.playTimer_2.stop()
def VideoPlayPause_3(self):
self.playCapture_1_0 = cv2.VideoCapture(self.video_1_0)
self.playCapture_1_1 = cv2.VideoCapture(self.video_1_1)
self.playCapture_2_0 = cv2.VideoCapture(self.video_2_0)
self.playCapture_2_1 = cv2.VideoCapture(self.video_2_1)
self.status_3, playStr= ((1,u'暂停'),
(0,u"集气站"),
(1,u'暂停'))[self.status_3]
self.playButton_3.setText(playStr)
if self.status_3 is 1: #play video
self.timer_3.stop()
self.playTimer_3.start()
else:
self.playTimer_3.stop()
class Timer(QThread):
def __init__(self, signal = "updateTime()", parent = None):
super(Timer, self).__init__(parent)
self.stoped = False
self.signal = signal
self.mutex = QMutex()
def run(self):
with QMutexLocker(self.mutex):
self.stoped = False
while True:
if self.stoped:
return
self.emit(SIGNAL(self.signal))
time.sleep(0.04)
def stop(self):
with QMutexLocker(self.mutex):
self.stoped = True
def isStoped(self):
with QMutexLocker(self.mutex):
return self.stoped
if __name__ == "__main__":
import PySide
app = QApplication(sys.argv)
main = MainWindow()
main.show()
sys.exit(app.exec_())