如何将GStreamer捕获的图像直接存入PyQt5变量?
问题描述
我现有一条GStreamer管道,可捕获图像并保存至指定文件夹,命令如下:
gst-launch-1.0 nvarguscamerasrc num-buffers=1 sensor_id=0 ! 'video/x-raw(memory:NVMM), width=4608, height=2592, framerate=14/1, format=NV12' ! nvjpegenc ! filesink location=myImage.jpg
我希望跳过GStreamer存文件的步骤,直接将捕获的图像存入Python变量,以便在PyQt5中用于显示。以下是我计划使用该图像的PyQt5精简代码:
from PyQt5.QtWidgets import QLabel, QMainWindow, QApplication, QWidget, QVBoxLayout from PyQt5.QtGui import QPixmap import sys #Something along the lines of #imageData = getImageFromGstreamer("gst-launch-1.0....") class Menu(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("Title") self.central_widget = QWidget() self.setCentralWidget(self.central_widget) lay = QVBoxLayout(self.central_widget) label = QLabel(self) pixmap = QPixmap('logo.png') # QPixmap(imageData) label.setPixmap(pixmap) self.resize(pixmap.width(), pixmap.height()) lay.addWidget(label) self.show() if __name__ == '__main__': app = QApplication(sys.argv) ex = Menu() sys.exit(app.exec_())
请问PyQt5是否有可直接获取GStreamer输出图像的相关库?
解决方案
PyQt5本身没有直接对接GStreamer的库,但可以通过GStreamer的Python绑定(gst-python)或者PyGObject实现,直接从GStreamer管道获取图像数据,再转换成PyQt5可识别的格式。
具体实现代码
from PyQt5.QtWidgets import QLabel, QMainWindow, QApplication, QWidget, QVBoxLayout from PyQt5.QtGui import QPixmap, QImage import sys import gi gi.require_version('Gst', '1.0') from gi.repository import Gst, GObject # 初始化GStreamer Gst.init(None) GObject.threads_init() def get_image_from_gstreamer(): # 重构GStreamer管道,用appsink替代文件输出 pipeline_str = ( "nvarguscamerasrc num-buffers=1 sensor_id=0 ! " "video/x-raw(memory:NVMM), width=4608, height=2592, framerate=14/1, format=NV12 ! " "nvvidconv ! video/x-raw, format=BGRx ! " "videoconvert ! video/x-raw, format=BGR ! " "appsink emit-signals=True sync=False" ) pipeline = Gst.parse_launch(pipeline_str) appsink = pipeline.get_by_name("appsink0") image_data = None # 处理appsink的新样本信号 def on_new_sample(sink): nonlocal image_data sample = sink.emit("pull-sample") buf = sample.get_buffer() caps = sample.get_caps() # 获取图像尺寸 width = caps.get_structure(0).get_value("width") height = caps.get_structure(0).get_value("height") # 读取缓冲区数据并转换为QImage success, map_info = buf.map(Gst.MapFlags.READ) if success: image = QImage(map_info.data, width, height, QImage.Format_BGR888) image_data = image.copy() buf.unmap(map_info) return False appsink.connect("new-sample", on_new_sample) # 启动管道并等待处理完成 pipeline.set_state(Gst.State.PLAYING) bus = pipeline.get_bus() bus.timed_pop_filtered(Gst.CLOCK_TIME_NONE, Gst.MessageType.EOS | Gst.MessageType.ERROR) pipeline.set_state(Gst.State.NULL) return image_data class Menu(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("GStreamer Image Capture") self.central_widget = QWidget() self.setCentralWidget(self.central_widget) lay = QVBoxLayout(self.central_widget) label = QLabel(self) # 获取图像并转换为QPixmap显示 qimage = get_image_from_gstreamer() if qimage: pixmap = QPixmap.fromImage(qimage) label.setPixmap(pixmap) self.resize(pixmap.width(), pixmap.height()) lay.addWidget(label) self.show() if __name__ == '__main__': app = QApplication(sys.argv) ex = Menu() sys.exit(app.exec_())
关键说明
- 替换原管道的
nvjpegenc ! filesink为nvvidconv ! videoconvert ! appsink,通过appsink直接获取原始图像数据 - 将图像格式转换为BGR,适配QImage的
Format_BGR888格式,方便一键转为QPixmap用于PyQt5显示 - 利用GStreamer的信号机制,在捕获到图像样本时立即处理并停止管道,避免资源占用
内容的提问来源于stack exchange,提问作者DrakeJest
相关产品推荐
相关产品推荐

