I am developing a GUI on Raspberry Pi 3 with Qt designer and writing code in Python with PyQt. The GUI will communicate through serial port to a serial device and shall also be streaming live video from a webcam attached to Rpi3 USB.
To start with, I found a simple GUI with two push buttons (Begin
and Stop
) for the webcam as required by me. But the stream was little slow. So, I took examples from PyImageSearch and initiated a thread to do the webcamstreaming.
import sys
import cv2
import numpy as np
from threading import Thread
from PyQt4 import QtGui, QtCore, Qt, uic
from PyQt4.QtCore import pyqtSlot
class WebcamStream():
def __init__(self,src=0):
self.capture = cv2.VideoCapture(src)
(self.ret, self.readFrame) = self.capture.read()
self.stopped = False
self.currentFrame=np.array([])
def start(self):
print "Stream_Start"
t = Thread(target=self.update, args=())
t.daemon = True
t.start()
return self
def update(self):
"""
capture frame and reverse RBG BGR and return opencv image
"""
while True:
if self.stopped:
return
(self.ret, self.readFrame) = self.capture.read()
self.currentFrame=cv2.cvtColor(self.readFrame,cv2.COLOR_BGR2RGB)
print "Image_Updated"
def read(self):
print "Read_File"
return self.readFrame
def stop(self):
self.stopped = True
def captureNextFrame(self):
self.read()
if(self.ret==True):
self.currentFrame=cv2.cvtColor(self.readFrame,cv2.COLOR_BGR2RGB)
print "Frame_captured"
def convertFrame(self):
""" converts frame to format suitable for QtGui """
try:
height,width=self.currentFrame.shape[:2]
img=QtGui.QImage(self.currentFrame,
width,
height,
QtGui.QImage.Format_RGB888)
img=QtGui.QPixmap.fromImage(img)
self.previousFrame = self.currentFrame
print "Frame_converted"
return img
except:
return None
class Gui(QtGui.QMainWindow):
def __init__(self,parent=None):
QtGui.QWidget.__init__(self,parent)
uic.loadUi('mainWindow.ui', self)
self.show()
self.video = WebcamStream(src=0).start()
#self._timer = QtCore.QTimer(self)
#self._timer.timeout.connect(self.play)
self.Stopp=True
self.update()
def play(self):
try:
while self.Stopp:
#self.video.captureNextFrame()
self.videoFrame.setPixmap(self.video.convertFrame())
self.videoFrame.setScaledContents(True)
cv2.waitKey(2)
except TypeError:
print "No frame"
@pyqtSlot()
def on_ButtonBegin_clicked(self):
#self._timer.start(100)
self.play()
@pyqtSlot()
def on_ButtonStop_clicked(self):
#self._timer.stop()
self.Stopp=False
self.video.stop()
cv2.destroyAllWindows()
def main():
app = QtGui.QApplication(sys.argv)
ex = Gui()
ex.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
But the stream is still sluggish. I haven't done programming with threading and even don't know whether I have done it right. But I have to do threading as I have to further use the Rpi3 GPIO and serial lines.