您好,登錄后才能下訂單哦!
這篇文章主要介紹“Qt怎么實(shí)現(xiàn)實(shí)時(shí)人臉框”,在日常操作中,相信很多人在Qt怎么實(shí)現(xiàn)實(shí)時(shí)人臉框問(wèn)題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”Qt怎么實(shí)現(xiàn)實(shí)時(shí)人臉框”的疑惑有所幫助!接下來(lái),請(qǐng)跟著小編一起來(lái)學(xué)習(xí)吧!
在人臉識(shí)別到以后,需要在實(shí)時(shí)視頻上將所有人臉框繪制出來(lái),一把來(lái)說(shuō)識(shí)別人臉會(huì)有多種選擇,一個(gè)是識(shí)別最大人臉,這種場(chǎng)景主要用于刷臉門禁,還有一種是識(shí)別所有人臉,這種場(chǎng)景主要用于人臉識(shí)別攝像機(jī),就是將畫面中的所有人臉識(shí)別出來(lái)發(fā)給服務(wù)器,人臉框的數(shù)據(jù)主要是四個(gè)參數(shù),左上角和右下角的位置,也可以說(shuō)是x、y、width、height,可能有些做的比較好的還有傾斜角度,這個(gè)意義不是很大,人臉識(shí)別的速度一般都是飛快的,就算你用學(xué)習(xí)上用的opencv做識(shí)別也是非常快的,基本上都是毫秒級(jí)的響應(yīng),主要的耗時(shí)操作在特征值的提取,所以一般要求能夠響應(yīng)每個(gè)通道每秒鐘25幀-30幀的畫面繪制+人臉框的繪制,當(dāng)然人臉框的數(shù)據(jù)可能會(huì)有多個(gè)。
用Qt來(lái)繪制人臉框,核心就是一個(gè)函數(shù),調(diào)用QPainter的drawRect方法,傳入?yún)^(qū)域即可,如果花哨點(diǎn)的話還可以設(shè)置邊框的粗細(xì)和顏色、圓角角度等,注意圓角角度使用的是drawRoundedRect而不是drawRoundRect,很多人這里會(huì)搞錯(cuò)哦。近期接觸的項(xiàng)目對(duì)人臉框的要求越來(lái)越多,之前是讓用戶自己拿到圖片來(lái)繪制,近期索性直接將這個(gè)功能內(nèi)置到視頻控件中(視頻控件封裝了多種內(nèi)核版本,有ffmpeg、vlc、mpv、海康sdk等),提供了可設(shè)置邊框粗細(xì)、顏色,傳入人臉框區(qū)域集合的接口,用戶只要自己的算法分析拿到人臉的區(qū)域集合(用戶是上帝,用戶的需求就是我的需求),通過(guò)setFaceRects函數(shù)設(shè)置即可,如果要清空人臉,只要設(shè)置人臉框區(qū)域集合為空即可??傮w測(cè)試下來(lái)速度非??欤梢院雎?,采用的QOPenGLWidget繪制的實(shí)時(shí)圖像,也支持人臉框的繪制。
支持的功能包括人臉識(shí)別、人臉比對(duì)、人臉?biāo)阉?、活體檢測(cè)等。
在線版還支持身份證、駕駛證、行駛證、銀行卡等識(shí)別。
在線版的協(xié)議支持百度、曠視,離線版的支持百度,可定制。
除了支持X86架構(gòu),還支持嵌入式linux比如contex-A9、樹(shù)莓派等。
每個(gè)功能的執(zhí)行除了返回結(jié)果還返回執(zhí)行用時(shí)時(shí)間。
多線程處理,通過(guò)type控制當(dāng)前處理類型。
支持單張圖片檢索相似度最高的圖片。
支持指定目錄圖片用來(lái)生成人臉特征值文件。
可設(shè)置等待處理圖片隊(duì)列中的數(shù)量。
每次執(zhí)行都有成功或者失敗的信號(hào)返回。
人臉?biāo)阉鞯姆祷亟Y(jié)果包含了原圖+最大相似度圖+相似度等。
人臉比對(duì)同時(shí)支持兩張圖片和兩個(gè)特征值比對(duì)。
相關(guān)功能自定義一套協(xié)議用于客戶端和服務(wù)端,可以通過(guò)TCP通信進(jìn)行交互。
自定義人臉識(shí)別協(xié)議非常適用于中心一臺(tái)服務(wù)器,現(xiàn)場(chǎng)若干設(shè)備請(qǐng)求的場(chǎng)景。
每個(gè)模塊全部是獨(dú)立的一個(gè)類,代碼整潔、注釋完善。
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 { //按照比例自動(dòng)居中繪制 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); //逐個(gè)取出人臉框區(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)簽位置盡量偏移多一點(diǎn)避免遮擋 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è)置顏色及字號(hào) QFont font; font.setPixelSize(osdFontSize); painter->setPen(osdColor); painter->setFont(font); painter->drawText(osdRect, flag, text); } painter->restore(); }
到此,關(guān)于“Qt怎么實(shí)現(xiàn)實(shí)時(shí)人臉框”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注億速云網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)?lái)更多實(shí)用的文章!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。