Capture webcam video using PyQt

2024/11/14 16:26:21

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_())
Answer

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_())
https://en.xdnf.cn/q/71992.html

Related Q&A

Plot a 3d surface from a list of lists using matplotlib

Ive searched around for a bit, and whhile I can find many useful examples of meshgrid, none shhow clearly how I can get data from my list of lists into an acceptable form for any of the varied ways Ive…

Super fast way to compare if two strings are equal

Obviously, in Python to check whether two strings are equal you can do:"hello word" == "hello world"But what if you are comparing really long strings (in excess of 1m characters)? …

Pandas DataFrames in reportlab

I have a DataFrame, and want to output it to a pdf. Im currently trying to use ReportLab for this, but it wont seem to work. I get an error here:mytable = Table(make_pivot_table(data, pivot_cols, colum…

How to open and close a website using default browser with python

Im trying to write a python script on windows platform to open a webpage(such as Google), and then, after 10 seconds, close this website. Note: Im using Windows 7, Python 2.7.10, and IE

Comparing numpy array with itself by element efficiently

I am performing a large number of these calculations:A == A[np.newaxis].Twhere A is a dense numpy array which frequently has common values.For benchmarking purposes we can use:n = 30000 A = np.random.r…

Kivy: BoxLayout vs. GridLayout

BoxLayout(orientation=vertical) vs. GridLayout(cols=1):They both do the same thing, no? Is there a reason to choose one over the other?

Flask circular dependency

I am developing a Flask application. It is still relatively small. I had only one app.py file, but because I needed to do database migrations, I divided it into 3 using this guide:https://realpython.co…

How to create tox.ini variables

Is there a way to set arbitrary variables within tox.ini?An example would be a project name that might be used in a variety of ways. With a rather complex tox.ini, I find myself copy and pasting all …

How to apply json_normalize on entire pandas column

I have a dataframe with LISTS(with dicts) as column values . My intention is to normalize entire column(all rows). I found way to normalize a single row . However, Im unable to apply the same function …

Configure Vs code version 2.0.0 Build Task for python

I need help in configuring my Vs code to run scripts in python using Cntrl Shift B, I was working fine until Vs code upgraded to version 2.0.0 now it wants me to configure the Build. And I am clueless…