内射老阿姨1区2区3区4区_久久精品人人做人人爽电影蜜月_久久国产精品亚洲77777_99精品又大又爽又粗少妇毛片

Qt怎么實現(xiàn)實時人臉框

這篇文章主要介紹“Qt怎么實現(xiàn)實時人臉框”,在日常操作中,相信很多人在Qt怎么實現(xiàn)實時人臉框問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Qt怎么實現(xiàn)實時人臉框”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!

成都創(chuàng)新互聯(lián)是一家以重慶網(wǎng)站建設(shè)公司、網(wǎng)頁設(shè)計、品牌設(shè)計、軟件運(yùn)維、營銷推廣、小程序App開發(fā)等移動開發(fā)為一體互聯(lián)網(wǎng)公司。已累計為宴會酒店設(shè)計等眾行業(yè)中小客戶提供優(yōu)質(zhì)的互聯(lián)網(wǎng)建站和軟件開發(fā)服務(wù)。

一、前言

在人臉識別到以后,需要在實時視頻上將所有人臉框繪制出來,一把來說識別人臉會有多種選擇,一個是識別最大人臉,這種場景主要用于刷臉門禁,還有一種是識別所有人臉,這種場景主要用于人臉識別攝像機(jī),就是將畫面中的所有人臉識別出來發(fā)給服務(wù)器,人臉框的數(shù)據(jù)主要是四個參數(shù),左上角和右下角的位置,也可以說是x、y、width、height,可能有些做的比較好的還有傾斜角度,這個意義不是很大,人臉識別的速度一般都是飛快的,就算你用學(xué)習(xí)上用的opencv做識別也是非常快的,基本上都是毫秒級的響應(yīng),主要的耗時操作在特征值的提取,所以一般要求能夠響應(yīng)每個通道每秒鐘25幀-30幀的畫面繪制+人臉框的繪制,當(dāng)然人臉框的數(shù)據(jù)可能會有多個。

用Qt來繪制人臉框,核心就是一個函數(shù),調(diào)用QPainter的drawRect方法,傳入?yún)^(qū)域即可,如果花哨點的話還可以設(shè)置邊框的粗細(xì)和顏色、圓角角度等,注意圓角角度使用的是drawRoundedRect而不是drawRoundRect,很多人這里會搞錯哦。近期接觸的項目對人臉框的要求越來越多,之前是讓用戶自己拿到圖片來繪制,近期索性直接將這個功能內(nèi)置到視頻控件中(視頻控件封裝了多種內(nèi)核版本,有ffmpeg、vlc、mpv、??祍dk等),提供了可設(shè)置邊框粗細(xì)、顏色,傳入人臉框區(qū)域集合的接口,用戶只要自己的算法分析拿到人臉的區(qū)域集合(用戶是上帝,用戶的需求就是我的需求),通過setFaceRects函數(shù)設(shè)置即可,如果要清空人臉,只要設(shè)置人臉框區(qū)域集合為空即可??傮w測試下來速度非???,可以忽略,采用的QOPenGLWidget繪制的實時圖像,也支持人臉框的繪制。

二、功能特點

  1. 支持的功能包括人臉識別、人臉比對、人臉?biāo)阉?、活體檢測等。

  2. 在線版還支持身份證、駕駛證、行駛證、銀行卡等識別。

  3. 在線版的協(xié)議支持百度、曠視,離線版的支持百度,可定制。

  4. 除了支持X86架構(gòu),還支持嵌入式linux比如contex-A9、樹莓派等。

  5. 每個功能的執(zhí)行除了返回結(jié)果還返回執(zhí)行用時時間。

  6. 多線程處理,通過type控制當(dāng)前處理類型。

  7. 支持單張圖片檢索相似度最高的圖片。

  8. 支持指定目錄圖片用來生成人臉特征值文件。

  9. 可設(shè)置等待處理圖片隊列中的數(shù)量。

  10. 每次執(zhí)行都有成功或者失敗的信號返回。

  11. 人臉?biāo)阉鞯姆祷亟Y(jié)果包含了原圖+最大相似度圖+相似度等。

  12. 人臉比對同時支持兩張圖片和兩個特征值比對。

  13. 相關(guān)功能自定義一套協(xié)議用于客戶端和服務(wù)端,可以通過TCP通信進(jìn)行交互。

  14. 自定義人臉識別協(xié)議非常適用于中心一臺服務(wù)器,現(xiàn)場若干設(shè)備請求的場景。

  15. 每個模塊全部是獨(dú)立的一個類,代碼整潔、注釋完善。

三、效果圖

Qt怎么實現(xiàn)實時人臉框

四、核心代碼

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);
                //繪制標(biāo)簽
                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);

    //逐個取出人臉框區(qū)域進(jìn)行繪制
    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();

    //標(biāo)簽位置盡量偏移多一點避免遮擋
    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");
        }

        //設(shè)置顏色及字號
        QFont font;
        font.setPixelSize(osdFontSize);
        painter->setPen(osdColor);
        painter->setFont(font);

        painter->drawText(osdRect, flag, text);
    }

    painter->restore();
}

到此,關(guān)于“Qt怎么實現(xiàn)實時人臉框”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>

文章標(biāo)題:Qt怎么實現(xiàn)實時人臉框
文章路徑:http://www.rwnh.cn/article32/gjhppc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供企業(yè)建站、App開發(fā)、標(biāo)簽優(yōu)化、微信小程序、用戶體驗網(wǎng)站排名

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都網(wǎng)頁設(shè)計公司
洛南县| 南川市| 天台县| 甘洛县| 桂平市| 宜昌市| 大埔区| 肇州县| 临西县| 绩溪县| 扶沟县| 布尔津县| 石城县| 张掖市| 永兴县| 泗水县| 淮北市| 金沙县| 容城县| 定边县| 安多县| 揭西县| 芜湖市| 浦北县| 神池县| 安福县| 富宁县| 延长县| 灵台县| 宝鸡市| 梁河县| 和田县| 黔南| 吉首市| 蓬莱市| 白沙| 疏勒县| 琼中| 武定县| 睢宁县| 静宁县|