当前位置: 首页 > article >正文

嵌入式学习-QT-Day10

嵌入式学习-QT-Day10

十、OpenCV

1、OpenCV介绍

2、环境搭建

3、验证环境

4、灰度处理

5、人脸检测

6、摄像头捕捉

6.1 摄像头单帧捕捉

6.2 摄像头连续捕捉

十、OpenCV

1、OpenCV介绍

OpenCV(Open Source Computer Visio n Library)是一个开源的计算机视觉库,它提供了丰富的图像处理和计算机视觉功能。该库由英特尔公司发起,并在 BSD 许可证下发布,因此它是免费的,且开放源代码。

OpenCV默认使用的色彩空间BGR(蓝、绿、红)而不是RGB(红、绿、蓝)。两种通道需要在代码之间相互转换。

应用非常广泛:

人机交互 物体识别 图像分割

人脸识别 自动驾驶

2、环境搭建

OpenCV支持不同的开发语言和开发环境,本次搭建的开发环境,基于Qt5.4

整个环境配置步骤如下:

把OpenCV的压缩包放到D盘根目录中。

解压(解压之后注意层级,只有一个opencv的目录层级)

再windows的环境变量Path中添加OpenCV的路径。

上面的路径为:

D:\opencv\opencv3.4-install\install\x86\mingw\bin

逐级点击确定

重启电脑

3、验证环境

创建一个简单的Qt项目尝试调用OpenCV的功能,操作步骤如下:

随便创建一个Qt的项目

项目创建完成后,在.pro文件中,添加以下配置项:

INCLUDEPATH += D:/opencv/opencv3.4-install/install/include
INCLUDEPATH += D:/opencv/opencv3.4-install/install/include/opencv
INCLUDEPATH += D:/opencv/opencv3.4-install/install/include/opencv2
LIBS += D:/opencv/opencv3.4-install/install/x86/mingw/lib/libopencv_*.a

点击项目的小锤子图标,重新构建,使项目构建出构建目录。随便找一张图片,放置到构建目录中,并命名为demo(名称随便,没有中文和特殊字符即可)

在主函数中编写一个简单的读取图片并展示的功能。

main.cpp

#include "dialog.h"
#include <QApplication>
#include <QDebug>
#include <opencv2/opencv.hpp>   // 头文件,.hpp也是C++的文件格式
using namespace cv; // 名字空间

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

    // 读取图片
    // 参数为读取的图片文件名称
    // Mat 矩阵,最原始的数学表示图像的方式
    Mat src = imread("demo.jpg");
    if(!src.data)   // 如果没有数据,表示读取失败
    {
        qDebug() << "读取图片失败";
    }

    // 给窗口设置标题,并设置图片显示模式为自动
    namedWindow("窗口",CV_WINDOW_AUTOSIZE);

    // 展示图片到窗口
    imshow("窗口",src);

    // 窗口长期保持(0表示无限等待)。
    waitKey(0);

    return 0;
}

实现效果:

4、灰度处理

图像灰度化是将一幅彩色的图像转换为灰度图像的过程。在灰度图像中,每个像素只包含一个灰度值,而不是彩色图像中的红、绿、蓝三个通道。灰度图像通常用于简化图像处理和分析,因为它们只包含亮度信息,而没有颜色信息。

图像灰度化的应用包括图像处理、机算机视觉、模式识别等领域。它有助于减少数据维度,简化图像处理算法,并提供更好的对比度和亮度信息,使图像特征更容易分析和识别。

main.cpp

#include "dialog.h"
#include <QApplication>
#include <QDebug>
#include <opencv2/opencv.hpp>   // 头文件,.hpp也是C++的文件格式
using namespace cv; // 名字空间

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

    // 读取图片
    // 参数为读取的图片文件名称
    // Mat 矩阵,最原始的数学表示图像的方式
    Mat src = imread("kk.jpg");
    if(!src.data)   // 如果没有数据,表示读取失败
    {
        qDebug() << "读取图片失败";
    }

    Mat gray;
    // cvtColor:转换颜色空间
    // 参数1:src原始图像数据
    // 参数2:转换后的图像数据
    // 参数3:转换方式
    cvtColor(src,gray,COLOR_BGR2GRAY);

    // 给窗口设置标题,并设置图片显示模式为自动
    namedWindow("窗口",CV_WINDOW_AUTOSIZE);

    // 展示图片到窗口
    imshow("窗口",src);
    imshow("gray",gray);
    // 窗口长期保持(0表示无限等待)。
    waitKey(0);

    return 0;
}

原图 灰度图

5、人脸检测

检测人脸是靠OpenCV的级联分类器来完成的,级联分类器本身并不仅仅能查找人脸,理论上可以查找任何的物体。级联分类器需要一个数据模型,我们可以直接使用Opencv已经训练好的一些模型。

模型目录在:

里面有很多xml文件。

这些包括眼睛、全身、车牌、猫、狗、人脸。根据自己的需要选择对应的模型即可。

需要通过CascadeClassifier类来加载分类器

CascadeClassifier classifier("xxx/install/etc/haarcascades/haarcascade_frontalface_alt2.xml");

通过CascadeClassifier的deterctMltiScale方法来检测是否存在人脸。

//  检测是否有目标(人脸、人眼等)
// 参数1:待检测的灰度图
// 参数2:查找到的目标矩形输出
void detectMultiScale(InputArray image,CV_OUT std::vector<Rect>& objects);
    // 识别到的区域结果会存储到这个向量中
    vector<Rect> faces;
    classifier.detectMultiScale(gray,faces);

通过vector.size方法可以获取到识别到的人脸。进行画框。可能会有多张人脸(用循环)

    // 循环遍历出所有的人脸
    for(int i = 0; i < faces.size(); i++)
    {
        // 在原图上画出选定框,标定人脸
        // 参数1:原始图像数据
        // 参数2:表示标定第几张人脸
        // 参数3:标定框的颜色【BGR】
        // 参数4:框的线条粗度
        rectangle(src,faces[i],Scalar(255,0,0),3);
    }

main.cpp

#include "dialog.h"
#include <QApplication>
#include <QDebug>
#include <vector>
#include <opencv2/opencv.hpp>   // 头文件,.hpp也是C++的文件格式
using namespace cv; // 名字空间
using namespace std;
int main(int argc, char *argv[])
{
//    QApplication a(argc, argv);
//    Dialog w;
//    w.show();

    // 加载人脸分类器(识别模型)
    CascadeClassifier classifier = CascadeClassifier("D:/opencv/opencv3.4-install/install/etc/haarcascades/haarcascade_frontalface_alt2.xml");

    // 读取图片
    // 参数为读取的图片文件名称
    // Mat 矩阵,最原始的数学表示图像的方式
    Mat src = imread("demo.jpg");
    if(!src.data)   // 如果没有数据,表示读取失败
    {
        qDebug() << "读取图片失败";
    }

    Mat gray;
    // cvtColor:转换颜色空间
    // 参数1:src原始图像数据
    // 参数2:转换后的图像数据
    // 参数3:转换方式
    cvtColor(src,gray,COLOR_BGR2GRAY);


    // 识别到的区域结果会存储到这个向量中
    vector<Rect> faces;
    classifier.detectMultiScale(gray,faces);

    // 循环遍历出所有的人脸
    for(int i = 0; i < faces.size(); i++)
    {
        // 在原图上画出选定框,标定人脸
        // 参数1:原始图像数据
        // 参数2:表示标定第几张人脸
        // 参数3:标定框的颜色【BGR】
        // 参数4:框的线条粗度
        rectangle(src,faces[i],Scalar(255,0,0),3);
    }


    // 给窗口设置标题,并设置图片显示模式为自动
    namedWindow("窗口",CV_WINDOW_AUTOSIZE);

    // 展示图片到窗口
    imshow("窗口",src);
    // 窗口长期保持(0表示无限等待)。
    waitKey(0);

    return 0;
}

6、摄像头捕捉

6.1 摄像头单帧捕捉

OpenCV提供了VideoCapture类来处理视频流,利用这个类可以很容易的调用本地摄像头获取摄像头图像帧。

打开摄像头

    // 打开摄像头
    // 参数0表示打开默认摄像头
    VideoCapture cap(0);

检查摄像头是否打开成功

    // 检查摄像头是否打开成功
    if(cap.isOpened() == false)
    {
        return -1;
    }

读取摄像头图像

    // 读取图片
    Mat src;
    // 读取一帧图像
    cap >> src;

释放摄像头

    // 释放摄像头
    cap.release();

main.cpp

#include "dialog.h"
#include <QApplication>
#include <QDebug>
#include <vector>
#include <opencv2/opencv.hpp>   // 头文件,.hpp也是C++的文件格式
using namespace cv; // 名字空间
using namespace std;
int main(int argc, char *argv[])
{
//    QApplication a(argc, argv);
//    Dialog w;
//    w.show();

    // 加载人脸分类器(识别模型)
    CascadeClassifier classifier = CascadeClassifier("D:/opencv/opencv3.4-install/install/etc/haarcascades/haarcascade_frontalface_alt2.xml");

    // 打开摄像头
    // 参数0表示打开默认摄像头
    VideoCapture cap(0);

    // 检查摄像头是否打开成功
    if(cap.isOpened() == false)
    {
        return -1;
    }

    // 读取图片
    Mat src;
    // 读取一帧图像
    cap >> src;
    if(!src.data)   // 如果没有数据,表示读取失败
    {
        qDebug() << "读取图片失败";
    }

    Mat gray;
    // cvtColor:转换颜色空间
    // 参数1:src原始图像数据
    // 参数2:转换后的图像数据
    // 参数3:转换方式
    cvtColor(src,gray,COLOR_BGR2GRAY);


    // 识别到的区域结果会存储到这个向量中
    vector<Rect> faces;
    classifier.detectMultiScale(gray,faces);

    // 循环遍历出所有的人脸
    for(int i = 0; i < faces.size(); i++)
    {
        // 在原图上画出选定框,标定人脸
        // 参数1:原始图像数据
        // 参数2:表示标定第几张人脸
        // 参数3:标定框的颜色【BGR】
        // 参数4:框的线条粗度
        rectangle(src,faces[i],Scalar(255,0,0),3);
    }

    // 给窗口设置标题,并设置图片显示模式为自动
    namedWindow("窗口",CV_WINDOW_AUTOSIZE);

    // 展示图片到窗口
    imshow("窗口",src);

    // 释放摄像头
    cap.release();

    // 窗口长期保持(0表示无限等待)。
    waitKey(0);

    return 0;
}

6.2 摄像头连续捕捉

dialog.h

#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
#include <QTimer>
#include <vector>
#include <QImage>
#include <QPixmap>
#include <QDebug>
#include <opencv2/opencv.hpp>   // 头文件,.hpp也是C++的文件格式
using namespace cv; // 名字空间
using namespace std;

namespace Ui {
class Dialog;
}

class Dialog : public QDialog
{
    Q_OBJECT

public:
    explicit Dialog(QWidget *parent = 0);
    ~Dialog();

private:
    Ui::Dialog *ui;

    // 定时器指针
    QTimer *timer;

    // 打开摄像头的载体对象
    VideoCapture cap;

    vector<Rect>faces;

    Mat src;

    CascadeClassifier classifier;

private slots:
    void timeoutSlot(); // 定时器槽函数
};

#endif // DIALOG_H

dialog.cpp

#include "dialog.h"
#include "ui_dialog.h"

Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);

    // 加载人脸分类器(识别模型)
    classifier = CascadeClassifier("D:/opencv/opencv3.4-install/install/etc/haarcascades/haarcascade_frontalface_alt2.xml");
    if(cap.open(0))
    {
        qDebug() << "摄像头打开成功";
        timer = new QTimer(this);
        timer->setInterval(50); // 50毫秒检测一次
        timer->setSingleShot(false);

        connect(timer,SIGNAL(timeout()),
                this,SLOT(timeoutSlot()));

        timer->start();
    }
    else
    {
        qDebug() << "摄像头打开失败";
    }
}

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

void Dialog::timeoutSlot()
{
    // 从cap中提取一帧图片
    cap >> src;
    if(!src.data)   // 如果没有数据,表示读取失败
    {
        qDebug() << "读取图片失败";
    }

    Mat gray;
    // cvtColor:转换颜色空间
    // 参数1:src原始图像数据
    // 参数2:转换后的图像数据
    // 参数3:转换方式
    cvtColor(src,gray,COLOR_BGR2GRAY);


    // 识别到的区域结果会存储到这个向量中
    vector<Rect> faces;
    classifier.detectMultiScale(gray,faces);

    // 循环遍历出所有的人脸
    for(int i = 0; i < faces.size(); i++)
    {
        // 在原图上画出选定框,标定人脸
        // 参数1:原始图像数据
        // 参数2:表示标定第几张人脸
        // 参数3:标定框的颜色【BGR】
        // 参数4:框的线条粗度
        rectangle(src,faces[i],Scalar(255,0,0),3);
    }
    // 展示图像
    // BGR -> RGB
    Mat rgb;
    cvtColor(src,rgb,CV_BGR2RGB);


    // Mat -> QImage
    // 参数1:原始数据
    // 参数2:宽度
    // 参数3:高度
    // 参数4:每一行的总通道数 = 宽度*3(rgb的通道数)
    // 参数5:转换格式
    QImage img(rgb.data,rgb.cols,rgb.rows,rgb.cols*3,QImage::Format_RGB888);

    // QImage -> QPixmap
    QPixmap p = QPixmap::fromImage(img);

    // 设置给QLabel
    ui->label->resize(p.width(),p.height());
    ui->label->setPixmap(p);
}

http://www.kler.cn/a/452589.html

相关文章:

  • PDF书籍《手写调用链监控APM系统-Java版》第12章 结束
  • 2024-12-25-sklearn学习(20)无监督学习-双聚类 料峭春风吹酒醒,微冷,山头斜照却相迎。
  • golang 并发--goroutine(四)
  • GIT与github的链接(同步本地与远程仓库)
  • 预览和下载 (pc和微信小程序)
  • 如何使用Windows快捷键在多显示器间移动窗口
  • 下载 AndroidStudio 旧版本方法
  • Max AI prompt1
  • RK356x bsp 5 - 海华AW-CM358SM Wi-Fi/Bt模组调试记录
  • 云手机群控能用来做什么?
  • 【HarmonyOS应用开发——ArkTS语言】购物商城的实现【合集】
  • 12-C语言单向链表
  • git 项目初始化
  • Linux运维常见命令
  • CE第三次作业
  • 挑战一个月基本掌握C++(第十一天)进阶文件,异常处理,动态内存
  • 在算力魔方上运行Genesis:一款颠覆性开源生成式物理引擎!
  • 云途领航:现代应用架构助力企业转型新篇
  • 【区块链】深入理解椭圆曲线密码学(ECC)
  • SVM分类-支持向量机(Support Vector Machine)
  • 飞牛 fnos 使用docker部署 OneNav 书签管理器
  • 12/21java基础
  • VSCode 插件开发实战(九): 不同插件之间如何通信
  • 在 Ubuntu 下通过 Docker 部署 MySQL 服务器
  • K8S 黑魔法之如何从 Pod 拿到节点的命令行
  • 记录下数仓相关的东西