我正在构建一个 PyQt 应用程序,其中一个小部件正在显示网络摄像头视频源。 对于小部件,我基本上使用来自 geeksforgeeks.com.
的 QCamera 示例中稍微修改的代码。我正在使用的(最小版本)代码:
class Camera(QCameraViewfinder):
def __init__(self, parent=None):
super(Camera, self).__init__(parent)
self.available_cameras = QCameraInfo.availableCameras()
def select_camera(self, i):
self.camera = QCamera(self.available_cameras[i])
self.camera.setViewfinder(self)
self.camera.start()
这在我的机器 A(笔记本电脑上的 Arch)上工作正常,但在我的机器 B(在 Lenovo Thinkcentre 上新安装的 Debian)上没有检测到可用的相机。
self.available_cameras
是空的。
我使用相同的网络摄像头(并尝试了两个不同的),它们在 dmesg
中显示为 USB HD Camera
,我可以通过 VLC、guvcview 等访问摄像头源...
如果有任何帮助并指出问题所在,我将不胜感激。 PyQt 从哪里获取相机列表也很有洞察力。谢谢!
更新: 我能够解决这个问题,ekhumoro 为我指明了正确的方向。缺少一些 qt 软件包,我通过运行(重新)安装了所有这些软件包:
apt install qtmultimedia5-*
结果是缺少gstreamer库的错误,所以我安装了gstreamer:
apt install gstreamer1.0-plugins-*
现在已发现相机并显示提要,但滞后很多。但现在这是一个不同的问题。
您可以使用OpenCV来捕获相机。 OpenCV 不支持音频,但因为它使用 numpy 为您提供图像,所以您可以对图像本身有很多控制,而且速度很快。
import cv2
from PyQt6.QtCore import *
from PyQt6.QtWidgets import *
from PyQt6.QtGui import *
class SynchObject(QObject):
synch_SIGNAL = pyqtSignal()
def __init__(self, parent=None):
super().__init__(parent)
self.sinch = QTimer()
self.sinch.timeout.connect(self.update)
self.sinch.start(1000 // 60)
def update(self):
self.synch_SIGNAL.emit()
class VideoMixer(QWidget):
monitorSize = (640, 480)
_programFrame = None
def __init__(self, synchObject, parent=None):
super().__init__(parent)
self.synchObject = synchObject
self.resolution = (1920, 1080)
self.fps = 60
self.previewMonitor = QLabel()
self.input1 = None
self.initUI()
self.initStyle()
self.initDemoMode()
self.initConnections()
def initUI(self):
mainLayout = QVBoxLayout()
mainLayout.addWidget(self.previewMonitor)
self.setLayout(mainLayout)
def initStyle(self):
self.previewMonitor.setFixedSize(self.monitorSize[0], self.monitorSize[1])
def initDemoMode(self):
self.input1 = cv2.VideoCapture(5) # put here the index of your camera
def initConnections(self):
self.synchObject.synch_SIGNAL.connect(self.updateFrame)
def updateFrame(self):
# there is a best way to do this, but this is just a demo
self._previewFrame = self.input1.read()[1]
self._previewFrame = cv2.resize(self._previewFrame, self.monitorSize)
# you do not need to invert BGR in RGB, because the QImage will do this for you
prwImage = QImage(self._previewFrame.data, self._previewFrame.shape[1], self._previewFrame.shape[0],
QImage.Format.Format_BGR888)
self.previewMonitor.setPixmap(QPixmap.fromImage(prwImage))
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
synchObject = SynchObject()
w = VideoMixer(synchObject)
w.show()
sys.exit(app.exec())
我使用 OpenCV、NumPy 和 PyQt6 用 Python 编写了一个视频混合器。目前我已经在 Windows 上实现了它,因为我对使用像 WASAPI 这样的音频库感兴趣,但很大一部分代码也可以在 Linux 上使用。