【Ubuntu】QT调用OpenCV摄像头视频拍照功能(带水印和时间戳显示功能)

目录

1、结果展示

2、界面设计

3、代码展示


1、结果展示

        简单的拍照录像摄像头功能开发,实现了照片和录像水印功能和显示时间戳,以及照片和录像可以保存到本地文件夹,可以使用外界摄像头,这里我使用的是笔记本自带的摄像头。

拍照和录像后可以保存在指定目录文件夹中,并且可以查看图片和视频。

2、界面设计

主要构成很简单,一个Qlabel,三个按钮,注意命名。

Qlabel界面:capArea_lb

开始按钮:capture_bt

拍照:takephoto_bt

录制:takevideo_bt

3、代码展示

pro文件依赖:

#-------------------------------------------------
#
# Project created by QtCreator 2024-07-11T18:43:25
#
#-------------------------------------------------

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = camCapture
TEMPLATE = app


SOURCES += main.cpp\
        menu.cpp

HEADERS  += menu.h

FORMS    += menu.ui

INCLUDEPATH += /usr/local/include

LIBS += -L/usr/local/lib/libopencv_highgui.so \
          /usr/local/lib/libopencv_core.so \
          /usr/local/lib/libopencv_imgproc.so \
          /usr/local/lib/libopencv_imgcodecs.so \
          /usr/local/lib/libopencv_face.so \
          /usr/local/lib/libopencv_objdetect.so \
          /usr/local/lib/libopencv_videoio.so

DISTFILES +=

RESOURCES += \
    qimage.qrc

menu.h

#ifndef MENU_H
#define MENU_H

#include <QWidget>
#include<QTimer>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/core/core.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/objdetect.hpp>
#include<opencv2/videoio.hpp>
#include<opencv2/face.hpp>

#include <QElapsedTimer>
using namespace std;
using namespace cv;

namespace Ui {
class menu;
}

class menu : public QWidget
{
    Q_OBJECT

public:
    explicit menu(QWidget *parent = 0);
    // 声明 QImageToCvMat 函数
    cv::Mat QImageToCvMat(const QImage &image);

    ~menu();
private slots:
    void CaptureOpen();

    void on_capture_bt_clicked();

    void on_takephoto_bt_clicked();

    void on_takevideo_bt_clicked();



private:
    Ui::menu *ui;
    QTimer * capTimer;
    VideoCapture cap;
    Mat frame;

    bool recording; // 新增:跟踪是否正在录制
    VideoWriter videoWriter; // 新增:用于视频保存
    QElapsedTimer elapsedTimer; // 添加QElapsedTimer

    Mat watermark;
    void addWatermark(Mat &frame, const Mat &watermark);

};

#endif // MENU_H

menu.cpp

#include "menu.h"
#include "ui_menu.h"
#include<QDateTime>
#include<QDebug>

menu::menu(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::menu),
    recording(false) // 初始化为未录制状态


{
    ui->setupUi(this);
    capTimer = new QTimer(this);
    connect(capTimer,SIGNAL(timeout()),this,SLOT(CaptureOpen()));
    cap.open(0);
    // 加载水印图片
    watermark = imread("/opt/aicTrain/camCapture/button/start.png", IMREAD_UNCHANGED);
    if (watermark.empty()) {
        qDebug() << "水印图片加载失败";
    }
    else
    {
        // 调整水印图片大小
        int newWidth = 50;  // 设置新的宽度
        int newHeight = 50; // 设置新的高度
        cv::resize(watermark, watermark, cv::Size(newWidth, newHeight));
    }


}

menu::~menu()
{
    delete ui;
}



void menu::CaptureOpen()
{

        cap >> frame;

        if (!watermark.empty())
        {
            addWatermark(frame, watermark);
        }

        Mat frame1;
        cvtColor(frame,frame1,CV_BGR2RGB);
        // 添加水印到实时显示的帧

    // 如果正在录制,获取经过的时间并在帧上绘制时间戳
        if (recording)
        {
            qint64 elapsedTime = elapsedTimer.elapsed(); // 获取经过的时间,单位为毫秒
            int seconds = (elapsedTime / 1000) % 60;
            int minutes = (elapsedTime / (1000 * 60)) % 60;
            int hours = (elapsedTime / (1000 * 60 * 60)) % 24;
            QString timeString = QString("%1:%2:%3")
                    .arg(hours, 2, 10, QChar('0'))
                    .arg(minutes, 2, 10, QChar('0'))
                    .arg(seconds, 2, 10, QChar('0'));
            std::string timeText = timeString.toStdString();

            // 在显示的帧上绘制时间戳
            cv::putText(frame1, timeText, cv::Point(frame1.cols - 150, 30), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(255, 255, 255), 2);
        }
            // 右上角时间水印,获取当前日期和时间
            QString currentDateTime = QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss");
            std::string dateTimeText = currentDateTime.toStdString();

            // 在帧的左上角绘制当前日期和时间
            cv::putText(frame1, dateTimeText, cv::Point(10, 30), cv::FONT_HERSHEY_SIMPLEX, 0.8, cv::Scalar(255, 255, 255), 2);
            // 文件水印
            cv::putText(frame, dateTimeText, cv::Point(10, 30), cv::FONT_HERSHEY_SIMPLEX, 0.8, cv::Scalar(255, 255, 255), 2);


    QImage Qimage1 = QImage((const unsigned char *)(frame1.data),
                            frame1.cols,frame1.rows,
                            frame1.step,QImage::Format_RGB888);
    ui->capArea_lb->setPixmap(QPixmap::fromImage(Qimage1));
    ui->capArea_lb->resize(Qimage1.size());
    ui->capArea_lb->show();



    // 如果正在录制,将帧写入视频文件
    if (recording && videoWriter.isOpened())
       {

          videoWriter.write(frame);
       }

}



void menu::on_capture_bt_clicked()
{
    ui->capture_bt->setText("捕获中");
    capTimer->start(30);
}

void menu::on_takephoto_bt_clicked()
{

        if (!frame.empty())
        {

            // 将当前帧转换为适合保存的格式
            Mat frameBGR;
            cvtColor(frame, frameBGR, CV_RGB2BGR);

            // 获取当前时间戳作为文件名
            QString timestamp = QDateTime::currentDateTime().toString("yyyyMMdd_HHmmss");
            QString filePath = QCoreApplication::applicationDirPath() + "/" + timestamp + ".jpg";

            // 将 Mat 对象转换为 QImage
            QImage Qimage1 = QImage((const unsigned char *)(frameBGR.data),
                                    frameBGR.cols, frameBGR.rows,
                                    frameBGR.step, QImage::Format_RGB888);

            // 保存图像到文件
            if (Qimage1.save(filePath))
            {
                qDebug() << "照片保存成功:" << filePath;
            }
            else
            {
                qDebug() << "照片保存失败";
            }
        }

}

void menu::on_takevideo_bt_clicked()
{
    if (recording)
        {
            // 停止录制
            recording = false;
            videoWriter.release();
            ui->takevideo_bt->setText("开始录制");

            qDebug() << "视频录制已停止";
        }
        else
        {

            // 开始录制
            QString timestamp = QDateTime::currentDateTime().toString("yyyyMMdd_HHmmss");
            QString filePath = QCoreApplication::applicationDirPath() + "/" + timestamp + ".avi";

            int codec = VideoWriter::fourcc('M', 'J', 'P', 'G'); // 选择合适的编码器
            double fps = 15.0; // 帧率
            Size frameSize(frame.cols, frame.rows);

            videoWriter.open(filePath.toStdString(), codec, fps, frameSize, true);


            if (videoWriter.isOpened())
            {
                recording = true;
                elapsedTimer.start(); // 启动计时器
                ui->takevideo_bt->setText("停止录制");
                qDebug() << "视频录制已开始,保存路径:" << filePath;
            }
            else
            {
                qDebug() << "无法打开视频文件进行录制";
            }
        }
}

void menu::addWatermark(Mat &frame, const Mat &watermark)
{
    // 确保水印图片尺寸小于视频帧
    int wmRows = watermark.rows;
    int wmCols = watermark.cols;


    // 获取水印图像ROI区域
    Mat roi = frame(Rect(frame.cols - wmCols - 10, frame.rows - wmRows - 10, wmCols, wmRows));

    // 将水印图像叠加到ROI上
    for (int r = 0; r < wmRows; ++r)
    {
        for (int c = 0; c < wmCols; ++c)
        {
            Vec4b wmPixel = watermark.at<Vec4b>(r, c);
            if (wmPixel[3] > 0) // 仅在水印像素不透明时进行叠加
            {
                Vec3b &roiPixel = roi.at<Vec3b>(r, c);
                roiPixel[0] = wmPixel[0];
                roiPixel[1] = wmPixel[1];
                roiPixel[2] = wmPixel[2];
            }
        }
    }
}

main.cpp

#include "menu.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    menu w;
    w.show();

    return a.exec();
}

如果你觉得这篇文章有用,请点赞收藏!后续会有一些拓展功能发出!

  • 15
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在Qt调用OpenCV库,可以实现高效的图像处理和显示功能。通过使用Qt的QWidget,可以创建一个GUI窗口,并在其中添加一个QLabel控件,用于显示OpenCV捕获的摄像头图像。 具体步骤如下: 1. 首先,需要在Qt项目中添加OpenCV库。 2. 然后,在Qt窗口中创建一个QLabel控件用于显示摄像头图像。 3. 其次,使用OpenCV打开摄像头,读取图像数据。 4. 然后,将OpenCV读取的图像数据转换为QPixmap格式,以便显示在QLabel控件上。 5. 最后,在GUI窗口中循环调用OpenCV读取摄像头图像,并将转换后的图像数据显示在QLabel上。 以下是示例代码: //首先,需要在Qt项目中添加OpenCV库 #include "opencv2/opencv.hpp" #include "opencv2/highgui.hpp" #include "opencv2/imgproc.hpp" //在Qt窗口中创建一个QLabel控件用于显示摄像头图像 QLabel *label = new QLabel(); //使用OpenCV打开摄像头,读取图像数据 cv::VideoCapture cap(0); cv::Mat frame; while(1) { //循环调用OpenCV读取摄像头图像 cap.read(frame); //将OpenCV读取的图像数据转换为QPixmap格式 QPixmap img = QPixmap::fromImage(QImage(frame.data, frame.cols, frame.rows, QImage::Format_RGB888)); //将转换后的图像数据显示在QLabel上 label->setPixmap(img); } ### 回答2: Qt是一种流行的跨平台应用程序开发框架,而OpenCV是一种广泛应用于计算机视觉领域的开放源代码计算机视觉库。使用QtOpenCV可以轻松实现对摄像头调用显示。 首先,需要使用Qt中的QWidget类创建一个窗口,然后添加一个QLabel类对象。这个QLabel类对象将用于显示摄像头捕捉到的图像。在程序中创建一个新的OpenCV摄像头对象,并使用OpenCV中提供的实时捕捉数据的方法从摄像头读取数据。 要在Qt显示摄像头读取的数据,需要使用OpenCV提供的cv::cvtColor()函数将数据从BGR格式转换为RGB格式。然后,使用Qt提供的QImage类将OpenCV图像转换为Qt图像格式,并在QLabel类对象中显示图像。 最后,通过Qt的窗口控制方式可以实现对摄像头进行各种控制操作,例如调节曝光时间、对焦等等。在完成以上步骤后,便可通过QtOpenCV实现对摄像头调用显示操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值