Ubuntu 使用opencv

新建项目
新建项目后将pro改为

#-------------------------------------------------
#
# Project created by QtCreator 2024-12-01T23:34:34
#
#-------------------------------------------------

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = FaceDetectPrecision
TEMPLATE = app

# The following define makes your compiler emit warnings if you use
# any feature of Qt which has been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0


SOURCES += \
        main.cpp \
        mainwindow.cpp

HEADERS += \
        mainwindow.h

FORMS += \
        mainwindow.ui

# 包含路径
INCLUDEPATH += /usr/include/opencv4
# 查找并链接所有必要的 OpenCV 库
CONFIG += link_pkgconfig
PKGCONFIG += opencv4


# 定义资源文件夹路径
RESOURCES_DIR = $$PWD/resources

# 定义目标复制目录路径
DEST_DIR = $$OUT_PWD/resources

# 仅在 Linux 系统下应用
unix {
    # 添加构建后命令,复制 resources 文件夹到输出目录
    QMAKE_POST_LINK += mkdir -p $$DEST_DIR && cp -r $$RESOURCES_DIR/* $$DEST_DIR/
}

RESOURCES += \
    res.qrc

MainWindow头文件

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTimer>
#include <QImage>
#include <QPixmap>
#include <QMessageBox>
#include <QFileDialog>
#include <opencv2/opencv.hpp>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
private slots:
    void updateFrame();
    void on_processImageButton_clicked();
private:
    Ui::MainWindow *ui;
    cv::VideoCapture cap;
    cv::CascadeClassifier faceCascade;
    QTimer *timer;

    QImage Mat2QImage(const cv::Mat &mat);
};

#endif // MAINWINDOW_H

MainWindow源文件

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    // 加载人脸检测器
       QString cascadePath = "resources/haarcascade_frontalface_alt.xml";
       if (!faceCascade.load(cascadePath.toStdString())) {
           QMessageBox::critical(this, "错误", "无法加载分类器文件:haarcascade_frontalface_alt.xml");
           exit(-1);
       }

       // 打开摄像头(通常索引为0)
       cap.open(0);
       if (!cap.isOpened()) {
           QMessageBox::critical(this, "错误", "无法打开摄像头。请检查摄像头连接。");
           exit(-1);
       }

       // 创建定时器,每30ms更新一次视频帧
       timer = new QTimer(this);
       connect(timer, &QTimer::timeout, this, &MainWindow::updateFrame);
       timer->start(30);
}

MainWindow::~MainWindow()
{
    cap.release();
    delete ui;
}

void MainWindow::updateFrame()
{
    cv::Mat frame;
    cap >> frame;
    if (frame.empty()) {
        return;
    }

    double t1 = cv::getTickCount();

    // 转换为灰度
    cv::Mat gray;
    cv::cvtColor(frame, gray, cv::COLOR_BGR2GRAY);

    // 进行人脸检测
    std::vector<cv::Rect> faces;
    faceCascade.detectMultiScale(gray, faces, 1.1, 5, cv::CASCADE_SCALE_IMAGE, cv::Size(50, 50));

    if (!faces.empty()) {
        qDebug("检测到人脸...");
    }

    // 画框
    for (const auto &face : faces) {
        cv::rectangle(frame, face, cv::Scalar(255, 0, 0), 3);
    }

    double t2 = cv::getTickCount();
    double freq = cv::getTickFrequency();
    double fps = freq / (t2 - t1);

    // 显示FPS
    std::string fpsText = "FPS: " + std::to_string(fps);
    cv::putText(frame, fpsText, cv::Point(10, 30), cv::FONT_HERSHEY_SIMPLEX, 1.0, cv::Scalar(0,0,255), 2);

    // 将BGR转换为RGB
    cv::cvtColor(frame, frame, cv::COLOR_BGR2RGB);
    QImage img = Mat2QImage(frame);
    ui->videoLabel->setPixmap(QPixmap::fromImage(img));
}

QImage MainWindow::Mat2QImage(const cv::Mat &mat)
{
    // 8-bits unsigned, NO. OF CHANNELS = 1
     if(mat.type() == CV_8UC1)
     {
         QVector<QRgb> colorTable;
         for(int i=0; i<256; i++)
             colorTable.push_back(qRgb(i,i,i));
         const uchar *qImageBuffer = mat.data;
         QImage img(qImageBuffer, mat.cols, mat.rows, mat.step, QImage::Format_Indexed8);
         img.setColorTable(colorTable);
         return img.copy();
     }
     // 8-bit, 3 channel
     else if(mat.type() == CV_8UC3)
     {
         const uchar *qImageBuffer = mat.data;
         QImage img(qImageBuffer, mat.cols, mat.rows, mat.step, QImage::Format_RGB888);
         return img.copy();
     }
     // 8-bit, 4 channel
     else if(mat.type() == CV_8UC4)
     {
         const uchar *qImageBuffer = mat.data;
         QImage img(qImageBuffer, mat.cols, mat.rows, mat.step, QImage::Format_ARGB32);
         return img.copy();
     }
     else
     {
         return QImage();
     }
}

void MainWindow::on_processImageButton_clicked()
{
    // 打开文件对话框选择图像
    QString filename = QFileDialog::getOpenFileName(this, tr("选择图像文件"), "", tr("图像文件 (*.bmp *.jpg *.jpeg *.png);;所有文件 (*)"));
    if (filename.isEmpty()) {
        return; // 用户取消选择
    }

    // 加载图像
    cv::Mat img = cv::imread(filename.toStdString());
    if (img.empty()) {
        QMessageBox::warning(this, "警告", "无法加载图像。");
        return;
    }

    // 转换为灰度
    cv::Mat gray;
    cv::cvtColor(img, gray, cv::COLOR_BGR2GRAY);

    // 进行人脸检测
    std::vector<cv::Rect> faces;
    faceCascade.detectMultiScale(gray, faces, 1.1, 5, cv::CASCADE_SCALE_IMAGE, cv::Size(50, 50));

    // 打印检测出的人脸数目
    qDebug() << faces.size() << "个脸部被检测到。";

    // 画框和标签
    for (const auto &face : faces) {
        cv::rectangle(img, face, cv::Scalar(255, 0, 0), 3);
        cv::putText(img, "Face", cv::Point(face.x, face.y - 10), cv::FONT_HERSHEY_SIMPLEX, 0.9, cv::Scalar(255,0,0), 2);
    }

    // 保存结果
    QString saveFilename = "face_detected.jpg";
    cv::imwrite(saveFilename.toStdString(), img);
    QMessageBox::information(this, "保存成功", "检测结果已保存为 " + saveFilename);
}

主函数

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

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

    return a.exec();
}

资源文件

resources目录下放着haarcascade_frontalface_alt.xml文件

运行

运行代码后可看到摄像头采集人脸信息。

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐