91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Qt怎么實現實時人臉框

發布時間:2021-12-15 10:13:21 來源:億速云 閱讀:262 作者:iii 欄目:互聯網科技

這篇文章主要介紹“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. 每個模塊全部是獨立的一個類,代碼整潔、注釋完善。

三、效果圖

Qt怎么實現實時人臉框

四、核心代碼

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怎么實現實時人臉框”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

qt
AI

昭平县| 文安县| 万山特区| 淮滨县| 呼伦贝尔市| 石狮市| 安仁县| 云霄县| 察哈| 海林市| 康定县| 鄂托克前旗| 宜兰县| 满洲里市| 道孚县| 读书| 五台县| 永康市| 宁强县| 泾源县| 时尚| 大城县| 阜平县| 库伦旗| 乌兰浩特市| 武夷山市| 屏南县| 扶余县| 汤阴县| 南城县| 肥乡县| 白河县| 衡阳县| 石楼县| 宁明县| 宣城市| 伊宁县| 孟州市| 乌什县| 五河县| 宜城市|