执行 OpenCV 函数“VideoWriter.open”后 QT 屏幕崩溃

QT screen crashes after executing OpenCV function 'VideoWriter.open'

提问人:Jorge Augusto Wilchen 提问时间:10/20/2023 最后编辑:Christoph RackwitzJorge Augusto Wilchen 更新时间:10/23/2023 访问量:30

问:

我正在使用 QTCreator IDE 创建我的屏幕,除此之外,我还使用 OpenCV 库从我的网络摄像头捕获帧并将它们显示在 QT 屏幕的 QLabel 中。单击录制按钮时,我的屏幕崩溃了。是什么原因导致的?我能做些什么才能使我的代码能够在不破坏代码的情况下录制相机帧?

调试代码时,当我从代码中执行第 84 行 'videoWriter.open(“/home/guardiantech/Desktop/video.mp4”, cv::VideoWriter::fourcc('M', 'J', 'P ', 'G'), fps, cv::Size(frame_width, frame_height));' 时出现以下消息:

“下级停止了,因为它收到了来自操作系统的信号。

信号名称:

SIGSEGV公司

信号含义:

分段故障”

和错误消息:

“16:44:43:启动 /home/guardiantech/Desktop/build-projeto_c-Desktop_Qt_6_4_2_GCC_64bit-Debug/projeto_c... [ WARN:0] 全局 ./modules/videoio/src/cap_gstreamer.cpp (1100) 打开 OpenCV |GStreamer 警告:无法查询视频位置:status=0,value=-1,duration=-1 16:44:46:/home/guardiantech/Desktop/build-projeto_c-Desktop_Qt_6_4_2_GCC_64bit-Debug/projeto_c崩溃。

.pro 文件:

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++17

# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

INCLUDEPATH += /usr/local/include/opencv4
LIBS += `pkg-config --cflags --libs opencv4`

SOURCES += \
    main.cpp \
    telaprincipal.cpp

HEADERS += \
    telaprincipal.h

FORMS += \
    telaprincipal.ui

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

.h 文件:

#ifndef TELAPRINCIPAL_H
#define TELAPRINCIPAL_H
#include <opencv2/core.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/opencv.hpp>

#include <QLabel>
#include <QMainWindow>

QT_BEGIN_NAMESPACE
namespace Ui { class TelaPrincipal; }
QT_END_NAMESPACE

class TelaPrincipal : public QMainWindow
{
    Q_OBJECT

public:
    TelaPrincipal(QWidget *parent = nullptr);
    ~TelaPrincipal();

private:
    Ui::TelaPrincipal *ui;
    QLabel *camera;
    cv::VideoCapture *videoCapture;
    cv::Mat frame;
    bool gravando = false;
    cv::VideoWriter videoWriter;

public slots:
    void atualizaFrame();
private slots:
    void on_botao_foto_clicked();
    void on_botao_gravar_clicked();
};
#endif // TELAPRINCIPAL_H

主.cpp文件:

#include "telaprincipal.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    TelaPrincipal w;
    w.show();
    return a.exec();
}

TelaPrincipal.cpp 文件:

#include "telaprincipal.h"
#include "ui_telaprincipal.h"

#include <opencv2/core.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/opencv.hpp>

#include <iostream>

#include <QTimer>

TelaPrincipal::TelaPrincipal(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::TelaPrincipal)
{
    ui->setupUi(this);
    camera = ui->frame;

    videoCapture = new cv::VideoCapture(0);
    //std::cout << cv::getBuildInformation() << std::endl;

    QTimer *cameraTimer = new QTimer(this);
    connect(cameraTimer, &QTimer::timeout, this, &TelaPrincipal::atualizaFrame);
    cameraTimer->start(0);
}

TelaPrincipal::~TelaPrincipal()
{
    delete videoCapture;
    delete ui;
}

void TelaPrincipal::atualizaFrame()
{
    if(videoCapture->isOpened())
    {
        *videoCapture >> frame;

        if(!frame.empty())
        {
            QImage img(frame.data, frame.cols, frame.rows, frame.step, QImage::Format_BGR888);

            camera->setPixmap(QPixmap::fromImage(img));
        }

        if(gravando)
        {
            videoWriter.write(frame);
        }
    }
}


void TelaPrincipal::on_botao_gravar_clicked()
{
    if(!gravando)
    {

        if (!videoCapture->isOpened()) {
            std::cerr << "Erro: a câmera não foi inicializada corretamente." << std::endl;
            return;
        }

        int frame_largura = videoCapture->get(cv::CAP_PROP_FRAME_WIDTH);
        int frame_altura = videoCapture->get(cv::CAP_PROP_FRAME_HEIGHT);

        double fps = videoCapture->get(cv::CAP_PROP_FPS);

        videoWriter.open("/path/to/my/file/video.mp4", cv::VideoWriter::fourcc('M', 'J', 'P', 'G'), fps, cv::Size(frame_largura, frame_altura)); //the aplication crashes on this line

        if (!videoWriter.isOpened()) {
            std::cerr << "Erro ao abrir o arquivo de vídeo para gravação." << std::endl;
        }

        gravando = true;
        ui->botoes->setPixmap(QPixmap("/path/to/my/img/backUI-2.png"));

    } else
    {
        gravando = false;
        ui->botoes->setPixmap(QPixmap("/path/to/my/img/backUI.png"));

        videoWriter.release();
    }
}

笔记:

分销商 ID:Ubuntu

描述: Ubuntu 22.04.3 LTS

发行:22.04

代号:jammy

Opencv4的

C++17

PTW公司

C++ opencv qt-creator

评论

0赞 wsys 11/10/2023
您是否打算使用 gstreamer 作为 opencv 视频 I/O 模块的 API?如果你这样做了,我认为你应该使用 gstreamer 的管道字符串,而不是文件路径,作为 的第一个参数。VideoWriter::open

答: 暂无答案