使用 QT 查看来自相机的流式图像

Posted

技术标签:

【中文标题】使用 QT 查看来自相机的流式图像【英文标题】:Using QT to view streaming images from camera 【发布时间】:2011-06-28 00:41:10 【问题描述】:

我有一个软件可以通过网络将 JPG 发送到应该显示这些图像的 GUI 客户端。我基本上想将它们显示到 qt 窗口,但我遇到了 qt 如何显示连续 JPG 的问题。我做了一个测试,看看我是否通过将图像打印到文件中正确获取图像,并且检查正常。主要代码如下:

int main(int argc, char *argv[]) 
    // initialize resources, if needed
    // Q_INIT_RESOURCE(resfile);

    QApplication app(argc, argv);
    CameraWindow cw;
    cw.show();
    //app.setActiveWindow(&cw);
    cw.getData();       // this paints the window  
    return app.exec();

这是初始化小部件的代码:

class CameraWindow : public QDialog 
    Q_OBJECT
    public:
    bool serverConnected;
    void getData();
    CameraWindow()
    
        imgl = new QLabel;
        widget.scrollImage->setWidget(imgl);
        widget.scrollImage->setBackgroundRole(QPalette::Dark);
    
    QLabel *imgl;
    virtual ~CameraWindow();
    private:
    Ui::CameraWindow widget;
;

这是应该将图像绘制到无限循环内的屏幕的代码的相关部分:

getData() 从 main 调用:

while (myrval < Header.imageSize) 
    myrval = myrval + recv(msgsock, (char*) ((int) buff + myrval),
        Header.imageSize- myrval, 0);


//buff contains the jpg at this point
QPixmap imgjpg;
imgjpg.loadFromData((const unsigned char*)buff, Header.imageSize, "JPG");
//scroll image is the parent that displays child
//in this case, the label
imgl->setPixmap(imgjpg);

我让它只适用于从文件加载的一个图像,但是当我对一组流图像使用相同的方法时,这不起作用。我是 Qt 新手,所以我确定我有一个微妙的错误。

非常感谢!

【问题讨论】:

您如何循环调用recv() 并加载图像? (你能把这两个任务分成各自的功能吗?) 【参考方案1】:

因为您处于无限循环中,Qt 可能没有机会处理事件。你可以在 setPixmap 之后尝试调用 QCoreApplication::processEvents 吗?

【讨论】:

啊有趣!这似乎是问题所在。我会尽快尝试这个。谢谢!【参考方案2】:

我建议创建一个 ImageProvider 类来提醒其他人它已准备好图像:

public class ImageProvider : QObject 
    Q_OBJECT
public:
    QPixmap getCurrentImage() const  /* retrieve current image */ 
signals:
    void newImageAvailable();
;

现在您需要一个类来显示它,所以我们称它为 ImageDisplayer 并假设它有一个名为 imageLabel 的标签,上面设置了您当前的图像:

public class ImageDisplayer : QWidget 
    Q_OBJECT
    QLabel *imageLabel;
    ImageProvider *provider; 
public:
    ImageDisplayer(QWidget *parent, ImageProvider *imageProvider) 
        this->imageLabel = /* setup QPixmap */;
        this->imageProvider = imageProvider;
        connect(imageProvider, SIGNAL("newImageAvailable()"), SLOT("setNewImage()"));
    
    public void setNewImage() 
        imageLabel->setPixmap(imageProvider->getCurrentImage());
        update(); // schedule the repaint
    
;

只要 Qt 认为合理,对update 的调用将导致重绘发生。这也允许跳帧和其他事情(您可能不想要)。

最后,您需要确保所有内容都通过您的主小部件连接起来:

public class MainWidget : QMainWindow 
    Q_OBJECT
    ImageDisplayer *imageDisplayer;
    ImageProvider *imageProvider;
public:
    void MainWidget() 
        this->imageProvider = new ImageProvider(/*your dependencies*/);
        this->imageDisplayer = new ImageDisplayer(this, imageProvider);
    

主要是:

int main(int argc, char* argv[]) 
    QApplication app(argc, argv);
    MainWidget w;
    w.show();
    return app.exec();

这可能不是性能最好的实现,但它很简单并且可以满足您的需求。

【讨论】:

我喜欢你的设置,但我仍然很困惑我的主代码会是什么样子?它看起来像这样吗: ImageProvider ip; ImageDisplayer id(&cw, &ip);您有完整示例的链接吗?我无法查看控制流【参考方案3】:

除了 Mason Chang 的回答之外 - 一个更好的方法是让显示器成为一个插槽,然后从计时器调用该插槽。

setTimer 值为 0 实际上是一个循环 - 它会在槽完成后立即调用,但仍允许其他处理。

【讨论】:

以上是关于使用 QT 查看来自相机的流式图像的主要内容,如果未能解决你的问题,请参考以下文章

使用 OpenGL 在 Qt 中显示来自 DirectShow 的原始图像数据

如何使用 Qt/C++ 小部件(不是 QML)从 Android 相机获取图像

如何从 iOS 设备(而不是自己的相机)流式传输 (RTMP) 视频

使用 Qt 显示相机图像给出 HIGHGUI ERROR: V4L/V4L2: VIDIOC_S_CROP

在 UIWebView 中显示来自相机的图像

来自 Android 设备摄像头的视频流