QT--day6(人脸识别、图像处理)

news2024/12/29 10:45:38

 人脸识别:



/***********************************************************************************头文件****************************************************************************************/



#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QWidget>
#include <QWidget>
#include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h>
#include<opencv2/face.hpp>
#include <vector>
#include <map>
#include <QMessageBox>
#include <QDebug>
#include <QFile>
#include <QTextStream>
#include <QDateTime>
#include <QTimerEvent>
#include<QtSerialPort/QtSerialPort>
#include<QtSerialPort/QSerialPortInfo>
using namespace  cv;
using namespace cv::face;
using namespace std;

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

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

private slots:
    void on_opencameraBtn_clicked();

    void on_closecameraBtn_clicked();

    void on_faceStudyBtn_clicked();

private:
    Ui::Widget *ui;

    /***********************第一模块:摄像头展示相关成员**************************/

    //定义视频流对象
    VideoCapture v;

    //定义图像容器
    Mat src;       //存储原色图

    Mat gray;     //存储灰度图

    Mat dst;     //存储均衡化图像

    Mat rgb;     //存储转化成的rgb图

    //定义级联分类器类
    CascadeClassifier c;    //该类用于使用模型进行相关区域分类工作

    //定义存储人脸矩形框的数组
    vector<Rect>faces;

    //定义展示摄像头的定时器
    int camera_timer_id;

    //重写定时器事件处理函数
    void timerEvent(QTimerEvent *e);

    /***********************第二模块:人脸录入相关成员****************************/

    Ptr<LBPHFaceRecognizer> recognizer;   //人脸识别的指针

    vector<Mat>study_faces;        //训练人脸的人脸容器

    vector<int>study_lab;         //记录要存储人脸的id标签

    int count;                  //记录机器学习的次数

    int flag;                    //记录是否正在录入人脸

    int study_timer_id;          //人脸录入的定时器

    /**********************第三模块:人脸检测*************************************/
    int check_timer_id;

};

#endif // WIDGET_H






/*******************************************************************源文件***************************************************************************************************************************/



#include "widget.h"
#include "ui_widget.h"

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

    //打开摄像头
    if(!v.open(0))
    {
       QMessageBox::information(this,"","摄像头打开失败");
       return;
    }

    //加栽级联分类器
    if(!c.load("D:\\opencv\\resource\\haarcascade_frontalface_alt2.xml"))
    {
        QMessageBox::information(NULL,"","级联分类器加载失败");
        return ;
    }

    //给人脸识别区空间
    QFile file("D:\\opencv\\resource\\myface.xml");

    //判断人脸模型是否存在
    if(file.exists())
    {
        //判断人脸模型是否存在
        recognizer=FaceRecognizer::load<LBPHFaceRecognizer>("D:\\opencv\\resource\\myface.xml");

    }else
    {
        //此时表明人脸模型不存在,需要创建出一个人脸模型
        recognizer=LBPHFaceRecognizer::create();  //调用静态成员函数,创建出一个人脸模型
    }
    //初始时将登录按钮设置成不可用状态,当人脸识别成功后,该按钮设置层可用状态
    ui->loginBtn->setEnabled(false);

    //启动人脸预测的定时器
    check_timer_id=startTimer(3000);

    //程序运行时应处于检测过程而不是学习过程
    flag=1;

    //设置可信度
    recognizer->setThreshold(100);   //后期识别后,如果可信度低于100,则说明识别成功

}

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

//定时器事件处理函数
void Widget::timerEvent(QTimerEvent *e)
{
    if(e->timerId()==camera_timer_id)   //说明展示摄像头的定时器到位,处理摄像头的功能
    {
        //从视频流中读取一张图像放入src中
        v.read (src);

        //镜像处理
        flip(src, src, 1);

        //色彩空间转化,将bgr图转化为rgb图
        cvtColor(src,rgb,CV_BGR2RGB);

        //将图像重新设置大小
        cv::resize(rgb,rgb,Size(300,300));

        //灰度处理
        cvtColor(rgb,gray,CV_BGR2GRAY);

        //均衡化处理
        equalizeHist(gray,dst);

        //获得人脸矩形框
        c.detectMultiScale(dst,faces);

        //将人脸矩形区域绘制到rgb图上
        for(int i=0;i<faces.size();i++)
        {
            rectangle(rgb,faces[i],Scalar(255,0,0),2);
        }

        //使用rgb图构造出一个qt能够识别的图像
        //QImage (const uchar *data,int width,int height,int bytesPerLine,Format format;
        //功能:构造一个QImage图
        //参数1:其他图像的数据域
        //参数2:其他图像的宽度
        //参数3:其他图像的高度
        //参数4:一行内的字节数
        //参数5:图像格式
        QImage img(rgb.data,rgb.cols,rgb.rows,rgb.cols*rgb.channels(),QImage::Format_RGB888);

        //在ui界面中展示构造出来的图像
        ui->cameraLab->setPixmap(QPixmap::fromImage(img));
    }

    //判断是否是人脸录入定时器到位
    if(e->timerId()==study_timer_id)
    {
        qDebug()<<"正在录入,请稍后...";

        //获取ui界面中的矩形框框起来的人脸区域
        Mat face;            //要存储的人脸

        //判断人脸矩形框是否存在
        if(faces.empty())
            return ;            //如果ui界面上人脸矩形框不存在,则直接结束

        //从摄像头原图中截取一个矩形框大小的图像放到face变量中
        face=src(faces[0]);

        //将该脸进行重新设置大小
        cv::resize(face,face,Size(50,50));

        //色彩空间转换
        cvtColor(face,face,CV_BGR2GRAY);

        //均衡化处理
        equalizeHist(face,face);

        //此时,要存储的脸已经准备好了,需要使用人脸识别器进行更新模型操作

        //将刚学习的这张脸放入学习容器中
        study_faces.push_back(face);
        study_lab.push_back(1);

        count++;         //表明己经学习了一张人脸
        if(count==50)    //需要学习50次,完成人脸模型的配置
        {
            recognizer->update(study_faces,study_lab);//完成人脸模型的更新,将图像模型转化为数据模型
            //将刚刚生成的人脸数据模型,保存到本地磁盘文件中
            recognizer->save("D:\\opencv\\resource\\myface.xml");

            //殿后工作
            QMessageBox::information(this,"","录入成功");
            flag=1;                 //表明可以进行人脸检测工作
            ui->faceStudyBtn->setEnabled(true);//按钮设置成可用状态
            study_faces.clear();
            study_lab.clear();   //清空两个容器
            count=0;             //清空计数器,以便下次使用
            killTimer(study_timer_id);//关闭人脸录入的定时器

        }
    }

    //判断是否是人脸识别定时器到位
    if(e->timerId()==check_timer_id)
    {
        //判断是否可以进行检测
        if(flag==1)
        {
             qDebug()<<"正在寻找...";

             //找到人脸模型
             QFile file("D:\\opencv\\resource\\myface.xml");
             if(file.exists())    //在人脸模型存在的基础上进行识别
             {
                 //继续判断当前摄像头中是否有人脸存在
                 if(faces.empty()||recognizer.empty())
                     return;           //表明没有人脸或人脸识别器不存在

                 //开始进行人脸识别工作
                 //1、获取摄像头中的人脸区域
                 Mat face=src(faces[0]);

                 //2.重新设置大小,为存储时的大小
                 cv::resize(face,face,Size(50,50));

                 //3.灰度处理和均衡化处理
                 cvtColor(face,face,CV_BGR2GRAY);
                 equalizeHist(face,face);

                 //定义变量存储人脸预测后的结果
                 int lab=-1;      //预测后的人脸编号
                 double conf=0.0;  //预测后的人脸可信度

                 //5、进行人脸预测工作
                 //函数原型: void predict (InputArray src,cv_our int &label,cv_our double &confidence) const;
                 //功能:对给定的图像进行预测工作
                 //参数1:要预测的图像
                 //参数2:预测后的该图像的编号,如果识别失败,则编号保持之前的不变,如果预测成功,则将该图像对应的编号返回
                 //参数3:人脸识别后的可信度
                 recognizer->predict(face,lab,conf);

                 qDebug()<<"lab="<<lab<<"  conf="<<conf;
                 //对人脸识别后的数据进行判断
                 if(lab!=-1)
                 {
                     //说明人脸识别成功
                     ui->loginBtn->setEnabled(true);
                 }
             }


        }
    }


}

//打开摄像头按钮对应的槽函数
void Widget::on_opencameraBtn_clicked()
{
    //启动打开摄像头的定时器
    camera_timer_id=startTimer(20);
}

//关闭摄像头按钮对应的槽函数
void Widget::on_closecameraBtn_clicked()
{
    //关闭摄像头的定时器
    killTimer(camera_timer_id);
}

//录入人脸按钮对应的槽函数
void Widget::on_faceStudyBtn_clicked()
{
    qDebug()<<"开始录入人脸,请正视摄像头...";
    flag=0;                         //0表示正在录入人脸,不要进行检测工作
    count=0;                        //将学习次数清零
    //启动录入人脸的定时器
    study_timer_id=startTimer(50);    //每隔50毫秒学习一次

    //将录入按钮设置成不可用状态
    ui->faceStudyBtn->setEnabled(false);


}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/817079.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

HCIP期中实验

考试需求 1 、该拓扑为公司网络&#xff0c;其中包括公司总部、公司分部以及公司骨干网&#xff0c;不包含运营商公网部分。 2 、设备名称均使用拓扑上名称改名&#xff0c;并且区分大小写。 3 、整张拓扑均使用私网地址进行配置。 4 、整张网络中&#xff0c;运行 OSPF 协议…

汽车销售企业消费税,增值税高怎么合理解决?

《税筹顾问》专注于园区招商、企业税务筹划&#xff0c;合理合规助力企业节税&#xff01; 汽车行业一直处于炙手可热的阶段&#xff0c;这是因为个人或者家庭用车的需求在不断攀升&#xff0c;同时随着新能源的技术进一步应用到汽车领域&#xff0c;一度实现了汽车销量的翻倍。…

JavaSE类和对象(2)(重点:封装、包、static静态变量和方法)

目录 一、封装 1.封装&#xff1a;从语法来看&#xff0c;就是被private修饰的成员变量或者成员方法。只能在当前类当中使用。 2.快捷键&#xff0c;自动生成set或者get方法 3.限定访问修饰符&#xff08;private、 protected、public&#xff09; public&#xff1a;可以理…

python数学建模_2:灰色预测模型(GM(1,1))使用文档

灰色预测模型(GM(1,1))使用文档简介使用时机处理数据类型函数说明使用示例注意事项具体项目 灰色预测模型(GM(1,1))使用文档 简介 灰色预测模型(GM(1,1))是灰色系统理论的重要部分&#xff0c;常用于对包含不确定性的系统进行建模和预测。 使用时机 当数据量较小&#xff0…

树莓派通过天线+gps获取经纬度并调用高德地图api在地图上标点

完整项目为《基于机器视觉的行人和路面缺陷检测及其边缘设备部署》 完整功能视频演示地址&#xff1a;本科最后的课设&#xff1a;“车载系统的辅助系统——基于机器视觉的行人和路面缺陷检测”完结撒花*罒▽罒*_哔哩哔哩_bilibili 该博客介绍的功能为&#xff1a; 1&#xff1…

VS下开发Qt应用环境搭建

VS下开发Qt应用环境搭建 版本说明环境搭建步骤QT新增组件重新安装QTVS中的配置 版本说明 vs2019 QT5.14 我之前是按照QT基础组件的安装&#xff0c;但是这个安装只是最基础的组件&#xff0c;如果想要在VS中使用QT&#xff0c;还得安装其他组件&#xff0c;下面的安装流程、 …

轻松解决宝塔面板设置了授权IP访问,但是IP变动导致访问不了面板

为了宝塔面板的安全与隐蔽性&#xff0c;我们很多站长会设置授权IP&#xff0c;授权IP的作用是&#xff1a;设置访问授权IP,多个请使用逗号(,)隔开;注意&#xff1a;一旦设置授权IP,只有指定IP的电脑能访问面板! 但是很多站长不是通过专用的虚拟通道访问&#xff0c;用的都是宽…

【Python系列】Python基础语法轻松入门—从变量到循环

目录 写在前面 语法介绍 变量 数据类型 整数 浮点数 字符串 列表 元组 字典 运算符 算术运算符 比较运算符 逻辑运算符 条件语句 循环语句 图书推荐 图书介绍 参与方式 中奖名单 写在前面 Python 是一种高级、解释型的编程语言&#xff0c;具有简单易学…

恒心工程PMO运作实践︱恒丰银行苏州分行行长(拟)姜兆华

恒丰银行股份有限公司苏州分行党委书记、行长&#xff08;拟&#xff09;&#xff0c;原总行金融科技部副总经理、恒心工程PMO办公室主任姜兆华先生受邀为由PMO评论主办的2023第十二届中国PMO大会演讲嘉宾&#xff0c;演讲议题&#xff1a;恒心工程PMO运作实践——以商业银行核…

京东的成功秘诀:找到自己独特而有效的商业模式

你知道京东为什么能够从一个卖电器的小网站发展成为中国最大的电商平台吗&#xff1f;如果京东一开始靠卖电器赚钱&#xff0c;不可能有今天&#xff0c;在十几年刘强东刚创业的时候&#xff0c;如果京东靠卖电器赚钱&#xff0c;你知道想当年的国美黄光裕和想当年的苏宁的张近…

磁盘均衡器:HDFS Disk Balancer

HDFS Disk Balancer 背景产生的问题以及解决方法 hdfs disk balancer简介HDFS Disk Balancer功能数据传播报告 HDFS Disk Balancer开启相关命令 背景 相比较于个人PC&#xff0c;服务器一般可以通过挂载多块磁盘来扩大单机的存储能力在Hadoop HDFS中&#xff0c;DataNode负责最…

F5 LTM 知识点和实验 7-使用SNATs处理流量

第七章:使用SNATs处理流量 SNATs: 传统的vs都是对目的地址和端口进行改变,而源地址没有改变,如果你需要对源地址和源端口进行更改,则需要使用SNAT能力,好处在于: 1、允许不可路由地址(网络内部)的设备获得可路由地址以进入网络外部。2、确保目标服务器通过BIG-IP系统返…

[Docker实现测试部署CI/CD----相关服务器的安装配置(1)]

目录 0、CI/CD系统最终架构图规划IP地址 1、git配置Git下载pycharm配置gitidea配置git 2、GitLab安装与配置主机要求拉取镜像定义 compose.yml启动gitlab浏览器访问并修改密码查看登录密码修改密码 3、SonarQube 安装与配置拉取镜像修改虚拟内存的大小启动SonarQube登录 SonarQ…

5.2.16.静态映射操作LED3

5.2.16.静态映射操作LED3 5.2.16.1、添加驱动中的写函数 (1)先定义好应用和驱动之间的控制接口&#xff0c;这个是由自己来定义的。譬如定义为&#xff1a;应用向驱动写"on"则驱动让LED亮&#xff0c;应用向驱动写"off"&#xff0c;驱动就让LED灭 1. 驱动文…

自定义Controller接口参数的值不能为空的校验

需求&#xff1a;在进入到相应Controller控制器前&#xff0c;需要先校验参数是否符合规范要求&#xff0c;如是否为空等等。 有人说&#xff0c;可以使用PathVariable里面的required属性控制&#xff0c;然而该属性只是代表参数是否必填&#xff0c;并不能校验参数的值是否满…

python_在K线找出波段_01_找出所有转折点

目录 写在前面&#xff1a; 需要考虑的几种K线图情况&#xff1a; 寻找所有转折点逻辑&#xff1a; 代码&#xff1a; 寻找转折点方法&#xff1a;找到第一个转折点就返回 循环寻找峰谷方法 主方法 调用计算&#xff1a; 返回&#xff1a; 在【PyQt5开发验证K线视觉想…

C++继承特性(1)——含义与继承方式的讲解

目录 1.继承的含义 2.继承的定义&#xff1a; 3.继承方式 例子1&#xff1a;基类的访问限定符为public&#xff0c;两个派生类的继承方式分别为public、protected时&#xff1a; 例子2&#xff1a; 基类的访问限定符为protected&#xff0c;两个派生类的继承方式分别为pub…

软件测试工程师的职业规划,你都做好了吗?

第一阶段&#xff1a;初级测试工程师 一般刚刚入门&#xff0c;熟悉基本的测试流程&#xff0c;此时已打基础为主。入门薪资一般在6000-8000元之间。 具体工作是&#xff1a; &#xff08;1&#xff09; 按照测试方案和流程对产品进行功能测试&#xff0c;检查产品是否有缺陷…

Java读取及生成pb文件并转换jsonString

Java读取及生成pb文件并转换jsonString 1. 效果图2. 原理2.1 Protocol Buffers是什么2.2 支持的语言2.3 根据.proto生成.java2.4 初始化及构建pb&#xff0c;读取&#xff0c;转jsonString 3. 源码3.1 address.proto3.2 PbParseUtil.java 参考 读取pb及生成pb文件pb文件转换jso…

vue-cli4升级到vue-cli5的踩坑记录

前言 最近对部分项目升级了vue-cli脚手架&#xff0c;记录一下 问题一&#xff1a; scss/less/css中无法引入public下的静态资源 问题描述 在样式文件中使用静态资源路径导致编译无法通过 错误信息如下&#xff1a; Module not found: Error: Cant resolve /img/login/lo…