Given the following PyQt code, I can perfectly capture the webcam's streaming video.
Now, I want to modify code, so a button named ''capture'' button is added that once pressed captures the streaming video and saves the image. How can I do this?
The obtained small image will be used to query an object recognition server.
import sys
from PyQt4 import QtGui, QtCore
import cv2class QtCapture(QtGui.QWidget):def __init__(self, *args):super(QtGui.QWidget, self).__init__()self.fps = 24self.cap = cv2.VideoCapture(*args)self.video_frame = QtGui.QLabel()lay = QtGui.QVBoxLayout()lay.setMargin(0)lay.addWidget(self.video_frame)self.setLayout(lay)def setFPS(self, fps):self.fps = fpsdef nextFrameSlot(self):ret, frame = self.cap.read()# My webcam yields frames in BGR formatframe = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)img = QtGui.QImage(frame, frame.shape[1], frame.shape[0], QtGui.QImage.Format_RGB888)pix = QtGui.QPixmap.fromImage(img)self.video_frame.setPixmap(pix)def start(self):self.timer = QtCore.QTimer()self.timer.timeout.connect(self.nextFrameSlot)self.timer.start(1000./self.fps)def stop(self):self.timer.stop()def deleteLater(self):self.cap.release()super(QtGui.QWidget, self).deleteLater()class ControlWindow(QtGui.QWidget):def __init__(self):QtGui.QWidget.__init__(self)self.capture = Noneself.start_button = QtGui.QPushButton('Start')self.start_button.clicked.connect(self.startCapture)self.quit_button = QtGui.QPushButton('End')self.quit_button.clicked.connect(self.endCapture)self.end_button = QtGui.QPushButton('Stop')vbox = QtGui.QVBoxLayout(self)vbox.addWidget(self.start_button)vbox.addWidget(self.end_button)vbox.addWidget(self.quit_button)self.setLayout(vbox)self.setWindowTitle('Control Panel')self.setGeometry(100,100,200,200)self.show()def startCapture(self):if not self.capture:self.capture = QtCapture(0)self.end_button.clicked.connect(self.capture.stop)# self.capture.setFPS(1)self.capture.setParent(self)self.capture.setWindowFlags(QtCore.Qt.Tool)self.capture.start()self.capture.show()def endCapture(self):self.capture.deleteLater()self.capture = Noneif __name__ == '__main__':import sysapp = QtGui.QApplication(sys.argv)window = ControlWindow()sys.exit(app.exec_())
I added the "Capture" button, and placed a switch in the nextFrameSlot()
method of the QtCapture
class. Hope it will work as you expected.
import sys
from PyQt4 import QtGui, QtCore
import cv2class QtCapture(QtGui.QWidget):def __init__(self, *args):super(QtGui.QWidget, self).__init__()self.fps = 24self.cap = cv2.VideoCapture(*args)self.video_frame = QtGui.QLabel()lay = QtGui.QVBoxLayout()lay.setMargin(0)lay.addWidget(self.video_frame)self.setLayout(lay)# ------ Modification ------ #self.isCapturing = Falseself.ith_frame = 1# ------ Modification ------ #def setFPS(self, fps):self.fps = fpsdef nextFrameSlot(self):ret, frame = self.cap.read()# ------ Modification ------ ## Save images if isCapturingif self.isCapturing:cv2.imwrite('img_%05d.jpg'%self.ith_frame, frame)self.ith_frame += 1# ------ Modification ------ ## My webcam yields frames in BGR formatframe = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)img = QtGui.QImage(frame, frame.shape[1], frame.shape[0], QtGui.QImage.Format_RGB888)pix = QtGui.QPixmap.fromImage(img)self.video_frame.setPixmap(pix)def start(self):self.timer = QtCore.QTimer()self.timer.timeout.connect(self.nextFrameSlot)self.timer.start(1000./self.fps)def stop(self):self.timer.stop()# ------ Modification ------ #def capture(self):if not self.isCapturing:self.isCapturing = Trueelse:self.isCapturing = False# ------ Modification ------ #def deleteLater(self):self.cap.release()super(QtGui.QWidget, self).deleteLater()class ControlWindow(QtGui.QWidget):def __init__(self):QtGui.QWidget.__init__(self)self.capture = Noneself.start_button = QtGui.QPushButton('Start')self.start_button.clicked.connect(self.startCapture)self.quit_button = QtGui.QPushButton('End')self.quit_button.clicked.connect(self.endCapture)self.end_button = QtGui.QPushButton('Stop')# ------ Modification ------ #self.capture_button = QtGui.QPushButton('Capture')self.capture_button.clicked.connect(self.saveCapture)# ------ Modification ------ #vbox = QtGui.QVBoxLayout(self)vbox.addWidget(self.start_button)vbox.addWidget(self.end_button)vbox.addWidget(self.quit_button)# ------ Modification ------ #vbox.addWidget(self.capture_button)# ------ Modification ------ #self.setLayout(vbox)self.setWindowTitle('Control Panel')self.setGeometry(100,100,200,200)self.show()def startCapture(self):if not self.capture:self.capture = QtCapture(0)self.end_button.clicked.connect(self.capture.stop)# self.capture.setFPS(1)self.capture.setParent(self)self.capture.setWindowFlags(QtCore.Qt.Tool)self.capture.start()self.capture.show()def endCapture(self):self.capture.deleteLater()self.capture = None# ------ Modification ------ #def saveCapture(self):if self.capture:self.capture.capture()# ------ Modification ------ #if __name__ == '__main__':import sysapp = QtGui.QApplication(sys.argv)window = ControlWindow()sys.exit(app.exec_())