千家信息网

Qt怎么实现实时人脸框

发表于:2026-11-04 作者:千家信息网编辑
千家信息网最后更新 2026年11月04日,这篇文章主要介绍"Qt怎么实现实时人脸框",在日常操作中,相信很多人在Qt怎么实现实时人脸框问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"Qt怎么实现实时人脸框"的疑惑
千家信息网最后更新 2026年11月04日Qt怎么实现实时人脸框

这篇文章主要介绍"Qt怎么实现实时人脸框",在日常操作中,相信很多人在Qt怎么实现实时人脸框问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"Qt怎么实现实时人脸框"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

一、前言

在人脸识别到以后,需要在实时视频上将所有人脸框绘制出来,一把来说识别人脸会有多种选择,一个是识别最大人脸,这种场景主要用于刷脸门禁,还有一种是识别所有人脸,这种场景主要用于人脸识别摄像机,就是将画面中的所有人脸识别出来发给服务器,人脸框的数据主要是四个参数,左上角和右下角的位置,也可以说是x、y、width、height,可能有些做的比较好的还有倾斜角度,这个意义不是很大,人脸识别的速度一般都是飞快的,就算你用学习上用的opencv做识别也是非常快的,基本上都是毫秒级的响应,主要的耗时操作在特征值的提取,所以一般要求能够响应每个通道每秒钟25帧-30帧的画面绘制+人脸框的绘制,当然人脸框的数据可能会有多个。

用Qt来绘制人脸框,核心就是一个函数,调用QPainter的drawRect方法,传入区域即可,如果花哨点的话还可以设置边框的粗细和颜色、圆角角度等,注意圆角角度使用的是drawRoundedRect而不是drawRoundRect,很多人这里会搞错哦。近期接触的项目对人脸框的要求越来越多,之前是让用户自己拿到图片来绘制,近期索性直接将这个功能内置到视频控件中(视频控件封装了多种内核版本,有ffmpeg、vlc、mpv、海康sdk等),提供了可设置边框粗细、颜色,传入人脸框区域集合的接口,用户只要自己的算法分析拿到人脸的区域集合(用户是上帝,用户的需求就是我的需求),通过setFaceRects函数设置即可,如果要清空人脸,只要设置人脸框区域集合为空即可。总体测试下来速度非常快,可以忽略,采用的QOPenGLWidget绘制的实时图像,也支持人脸框的绘制。

二、功能特点

  1. 支持的功能包括人脸识别、人脸比对、人脸搜索、活体检测等。

  2. 在线版还支持身份证、驾驶证、行驶证、银行卡等识别。

  3. 在线版的协议支持百度、旷视,离线版的支持百度,可定制。

  4. 除了支持X86架构,还支持嵌入式linux比如contex-A9、树莓派等。

  5. 每个功能的执行除了返回结果还返回执行用时时间。

  6. 多线程处理,通过type控制当前处理类型。

  7. 支持单张图片检索相似度最高的图片。

  8. 支持指定目录图片用来生成人脸特征值文件。

  9. 可设置等待处理图片队列中的数量。

  10. 每次执行都有成功或者失败的信号返回。

  11. 人脸搜索的返回结果包含了原图+最大相似度图+相似度等。

  12. 人脸比对同时支持两张图片和两个特征值比对。

  13. 相关功能自定义一套协议用于客户端和服务端,可以通过TCP通信进行交互。

  14. 自定义人脸识别协议非常适用于中心一台服务器,现场若干设备请求的场景。

  15. 每个模块全部是独立的一个类,代码整洁、注释完善。

三、效果图

四、核心代码

bool FFmpegWidget::eventFilter(QObject *watched, QEvent *event){    if (watched == osdWidget && event->type() == QEvent::Paint) {        if (drawImage) {            QPainter painter;            painter.begin(osdWidget);            painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);            //绘制边框            drawBorder(&painter);            if (thread->getIsInit()) {                //绘制背景图片                drawImg(&painter, image);                //绘制人脸框                drawFace(&painter);                //绘制标签                drawOSD(&painter, osd1Visible, osd1FontSize, osd1Text, osd1Color, osd1Image, osd1Format, osd1Position);                drawOSD(&painter, osd2Visible, osd2FontSize, osd2Text, osd2Color, osd2Image, osd2Format, osd2Position);            } else {                //绘制背景                if (!isDrag) {                    drawBg(&painter);                }            }            painter.end();        }    }    return QWidget::eventFilter(watched, event);}void FFmpegWidget::drawBorder(QPainter *painter){    if (borderWidth == 0) {        return;    }    painter->save();    QPen pen;    pen.setWidth(borderWidth);    pen.setColor(hasFocus() ? focusColor : borderColor);    painter->setPen(pen);    painter->drawRect(rect());    painter->restore();}void FFmpegWidget::drawBg(QPainter *painter){    painter->save();    //背景图片为空则绘制文字,否则绘制背景图片    if (bgImage.isNull()) {        painter->setFont(this->font());        painter->setPen(palette().foreground().color());        painter->drawText(rect(), Qt::AlignCenter, bgText);    } else {        //居中绘制        int x = rect().center().x() - bgImage.width() / 2;        int y = rect().center().y() - bgImage.height() / 2;        QPoint point(x, y);        painter->drawImage(point, bgImage);    }    painter->restore();}void FFmpegWidget::drawImg(QPainter *painter, QImage img){    if (img.isNull()) {        return;    }    painter->save();    int offset = borderWidth * 1 + 0;    img = img.scaled(width() - offset, height() - offset, Qt::KeepAspectRatio, Qt::SmoothTransformation);    if (fillImage) {        QRect rect(offset / 2, offset / 2, width() - offset, height() - offset);        painter->drawImage(rect, img);    } else {        //按照比例自动居中绘制        int x = rect().center().x() - img.width() / 2;        int y = rect().center().y() - img.height() / 2;        QPoint point(x, y);        painter->drawImage(point, img);    }    painter->restore();}void FFmpegWidget::drawFace(QPainter *painter){    if (faceRects.count() == 0) {        return;    }    painter->save();    //人脸边框的颜色    QPen pen;    pen.setWidth(faceBorder);    pen.setColor(faceColor);    painter->setPen(pen);    //逐个取出人脸框区域进行绘制    foreach (QRect rect, faceRects) {        painter->drawRect(rect);    }    painter->restore();}void FFmpegWidget::drawOSD(QPainter *painter,                           bool osdVisible,                           int osdFontSize,                           const QString &osdText,                           const QColor &osdColor,                           const QImage &osdImage,                           const FFmpegWidget::OSDFormat &osdFormat,                           const FFmpegWidget::OSDPosition &osdPosition){    if (!osdVisible) {        return;    }    painter->save();    //标签位置尽量偏移多一点避免遮挡    QRect osdRect(rect().x() + (borderWidth * 2), rect().y() + (borderWidth * 2), width() - (borderWidth * 5), height() - (borderWidth * 5));    int flag = Qt::AlignLeft | Qt::AlignTop;    QPoint point = QPoint(osdRect.x(), osdRect.y());    if (osdPosition == OSDPosition_Left_Top) {        flag = Qt::AlignLeft | Qt::AlignTop;        point = QPoint(osdRect.x(), osdRect.y());    } else if (osdPosition == OSDPosition_Left_Bottom) {        flag = Qt::AlignLeft | Qt::AlignBottom;        point = QPoint(osdRect.x(), osdRect.height() - osdImage.height());    } else if (osdPosition == OSDPosition_Right_Top) {        flag = Qt::AlignRight | Qt::AlignTop;        point = QPoint(osdRect.width() - osdImage.width(), osdRect.y());    } else if (osdPosition == OSDPosition_Right_Bottom) {        flag = Qt::AlignRight | Qt::AlignBottom;        point = QPoint(osdRect.width() - osdImage.width(), osdRect.height() - osdImage.height());    }    if (osdFormat == OSDFormat_Image) {        painter->drawImage(point, osdImage);    } else {        QDateTime now = QDateTime::currentDateTime();        QString text = osdText;        if (osdFormat == OSDFormat_Date) {            text = now.toString("yyyy-MM-dd");        } else if (osdFormat == OSDFormat_Time) {            text = now.toString("HH:mm:ss");        } else if (osdFormat == OSDFormat_DateTime) {            text = now.toString("yyyy-MM-dd HH:mm:ss");        }        //设置颜色及字号        QFont font;        font.setPixelSize(osdFontSize);        painter->setPen(osdColor);        painter->setFont(font);        painter->drawText(osdRect, flag, text);    }    painter->restore();}

到此,关于"Qt怎么实现实时人脸框"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

人脸 支持 图片 实时 功能 区域 学习 用户 背景 边框 颜色 相似 场景 就是 特征 特征值 背景图片 视频 角度 处理 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网属科技 厦门中拓互联网络科技有限公司 万易互联网科技有限公司 北京互联网络科技有限公司 友谊互联网络科技 互联网 新科技 海南购全球互联网科技 青岛中康互联网医疗科技有限公司 恒生互联网科技指数跳水 广州市恰铎互联网科技有限公司 中国互联网公司排名锤子科技 东莞新华互联网科技学校 深圳市罗太互联网科技有限公司 南博望互联网科技有限公司 徐州市互联网科技有限公司 上海钢联属于互联网科技股吗 互联网科技实习生岗位 互联网安防科技感 陕西云淼互联网科技公司 青岛互联网科技园 喔噻互联网科技有限公司 互联网新科技 中国互联网科技工作委员会毛军 互联网科技产品 互联网教育科技公司vipkid 四川互联网展示科技馆设计 陕西九四连强互联网科技有限公司 北京天晋互联网科技有限公司 三亚科技创新互联网基地 科技互联网专业务虚会材料
0