OpenCV拾趣(六)——視頻流人臉跟蹤

本篇簡介

從本小節(jié)開始刁憋,我們將嘗試使用基礎(chǔ)框架搭建篇完成的各類工具滥嘴,實(shí)現(xiàn)一些實(shí)戰(zhàn)向的應(yīng)用場景。
本篇作為實(shí)戰(zhàn)篇的第一個案例职祷,首先來看看如何實(shí)現(xiàn)視頻流人臉跟蹤這個較為常見的功能氏涩。

原理簡介

實(shí)現(xiàn)對人臉時別/跟蹤,需要解決的主要問題就是將人臉的部分與場景中其他的部分區(qū)分開來有梆。這就涉及到兩方面的問題:

  1. 如何提取人臉的特征
  2. 如何使用提取的特征對場景中的對象進(jìn)行分類

對此是尖,一種常見的實(shí)現(xiàn)方式為Haar特征檢測提取特征 + 級聯(lián)分類器(Cascading Classifier)進(jìn)行分類的組合。而OpenCV中也提供了相應(yīng)的分類器訓(xùn)練及分類工具泥耀。關(guān)于Haar特征提取和級聯(lián)分類器的原理饺汹,在這里就不詳細(xì)說明了,有興趣的話可以參考文末參考連接中的相關(guān)資料[1][2]痰催。

此外兜辞,簡明起見迎瞧,接下來的實(shí)現(xiàn)將只關(guān)注如何使用已訓(xùn)練好的分類器進(jìn)行人臉檢測,如何對分類器進(jìn)行訓(xùn)練不在本文的討論范圍內(nèi)逸吵。

那么接下來我們就來看一看如何使用我們實(shí)現(xiàn)好的QCvCamView控件和OpenCV提供的分類器工具實(shí)現(xiàn)視頻流人臉跟蹤凶硅。

實(shí)現(xiàn)人臉檢測濾波器

首先,秉承QCvCamView中通過濾波鏈來實(shí)現(xiàn)視頻流處理的思路(參考:擴(kuò)展視頻流控件)扫皱,我們需要實(shí)現(xiàn)一個人臉檢測濾波器足绅,聲明如下:

class QCvFaceDetectFilter : public QCvMatFilter
{
  public:
    QCvFaceDetectFilter(QString name) : QCvMatFilter(name) {}

  public:
    bool load(QString fileName);
    bool isClassifierValid();

  protected:
    virtual void execFilter(const cv::Mat& inMat, cv::Mat& outMat);

  protected:
    cv::CascadeClassifier m_classifier;
};

這個濾波器除了實(shí)現(xiàn)了濾波器通用的execFilter方法外,還提供了讀取分類器配置和判斷分類器是否有效的公共方法韩脑。OpenCV提供的級聯(lián)分類器作為組件以成員變量的形式在這里聲明氢妈。
注:要使用這個分類器,需要引用opencv2/objdetect.hpp頭文件

讀取分類器配置的具體實(shí)現(xiàn)如下:

bool QCvFaceDetectFilter::load(QString fileName)
{
    return m_classifier.load(fileName.toStdString().c_str());
}

也就是直接使用了OpenCV提供的讀取方法段多。

濾波處理的具體實(shí)現(xiàn)如下:

void QCvFaceDetectFilter::execFilter(const cv::Mat& inMat, cv::Mat &outMat)
{
    outMat = inMat.clone();
    if (m_classifier.empty())
    {
        return;
    }

    std::vector<cv::Rect> faces;
    cv::Mat frameGray;
    cv::cvtColor(outMat, frameGray, cv::COLOR_BGR2GRAY);
    cv::equalizeHist(frameGray, frameGray);
    //-- Detect faces
    m_classifier.detectMultiScale(frameGray, faces, 1.1, 2, 0 | cv::CASCADE_SCALE_IMAGE,
                                  cv::Size(30, 30));
    for (size_t i = 0; i < faces.size(); i++)
    {
        cv::Point center(faces[i].x + faces[i].width / 2, faces[i].y + faces[i].height / 2);
        cv::ellipse(outMat, center,
                    cv::Size(faces[i].width / 2, faces[i].height / 2), 0, 0, 360,
                    cv::Scalar(255, 0, 255), 4, 8, 0);
    }
}

上面的實(shí)現(xiàn)中首量,首先借助cvtColor方法將RGB圖像轉(zhuǎn)化為灰度圖像,并通過直方圖匹配(eualizeHist)對灰度圖像進(jìn)行了預(yù)處理进苍,以提升光線較暗時識別的準(zhǔn)確率加缘。
之后,將預(yù)處理后的灰度圖像傳入級聯(lián)分類器的多級檢測方法(detectMultiScale)進(jìn)行分類琅捏,并將結(jié)果矩形保存到faces數(shù)據(jù)中生百。
最后,在RGB圖像上將檢測到的人臉結(jié)果繪制為橢圓形柄延。這樣基于級聯(lián)分類器的人臉檢測濾波器就實(shí)現(xiàn)完成了。

注:這里的實(shí)現(xiàn)參考了OpenCV官方級聯(lián)分類器教程中的實(shí)現(xiàn)缀程,并進(jìn)行了一定簡化搜吧。

界面實(shí)現(xiàn)

整體界面設(shè)計(jì)如下:


face_detect_gui.png

灰色部分即為嵌入的QCvCamView控件,下方兩個按鈕分別為加載分類器的按鈕和開始人臉檢測的按鈕杨凑。其中開始檢測的按鈕在沒有完成分類器加載前處于不可用狀態(tài)滤奈。

基于上述界面設(shè)計(jì),我們初始化QCvCamView控件撩满,并將上面實(shí)現(xiàn)好的人臉檢測濾波器添加到濾波鏈中:

    m_camView = new QCvCamView(ui->frame);
    m_faceFilter = new QCvFaceDetectFilter("face");
    m_camView->appendFilter(m_faceFilter);

然后將配置好的視頻流控件添加到布局中即可蜒程。這里限于篇幅就不貼布局相關(guān)的代碼了。
接下來我們來實(shí)現(xiàn)兩個功能按鈕伺帘。首先是加載分類器的按鈕昭躺,比較關(guān)鍵的實(shí)現(xiàn)步驟如下:

void FaceVideoDlg::onBtnLoad()
{
    // 省略界面布局及控件相關(guān)的操作
    ...

    QString dataDir = QDir::currentPath() + "/../../../../sdk/opencv_release/share/OpenCV/haarcascades";
    if (!QDir(dataDir).exists())
    {
        dataDir = ".";
    }
    QString classifierName = QFileDialog::getOpenFileName(this,
                                                          "Please Select a Cascade Classifier",
                                                          dataDir,
                                                          "XML Files (*.xml)");
    if (!classifierName.isEmpty())
    {
        bool isValid = m_faceFilter->load(classifierName);
        // 省略界面布局及控件相關(guān)的操作
        ...
    }
    else
    {
        // 省略界面布局及控件相關(guān)的操作
        ...
    }
}

上面的實(shí)現(xiàn)分為三個步驟:

  • 讀取分類器。在上面的實(shí)現(xiàn)中伪嫁,默認(rèn)路徑指向了OpenCV官方提供的訓(xùn)練結(jié)果樣例路徑(參考第一節(jié)有關(guān)SDK目錄的說明)领炫,方便后續(xù)測試。
  • 加載分類器张咳。這個步驟委托給了人臉檢測濾波器處理帝洪。
  • 根據(jù)加載結(jié)果似舵,執(zhí)行各控件的啟用/禁用操作。

另一方面葱峡,開始人臉檢測的按鈕實(shí)現(xiàn)就相對比較簡單了砚哗,只需要啟動視頻流控件即可:

void FaceVideoDlg::onBtnDetect(bool clicked)
{
    m_camView->onStreamSwitch(clicked);
}

測試檢測效果

整個界面實(shí)現(xiàn)完成后,我們來測試下檢測的效果砰奕。首先點(diǎn)擊加載分類器按鈕频祝,選擇官方樣例中的haarcascade_frontalface_alt2.xml訓(xùn)練器,然后點(diǎn)擊開始檢測按鈕脆淹,效果如下:


face_detect2.png

有關(guān)視頻流人臉檢測的實(shí)現(xiàn)就說明到這里常空。
>>本篇參考代碼
>>返回系列索引

參考鏈接

[1] Haar-like Feature Wikipedia
[2] Cascading Classfier Wikipedia
[3] OpenCV官方級聯(lián)分類器教程

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市盖溺,隨后出現(xiàn)的幾起案子漓糙,更是在濱河造成了極大的恐慌,老刑警劉巖烘嘱,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件昆禽,死亡現(xiàn)場離奇詭異,居然都是意外死亡蝇庭,警方通過查閱死者的電腦和手機(jī)醉鳖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來哮内,“玉大人盗棵,你說我怎么就攤上這事”狈ⅲ” “怎么了纹因?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長琳拨。 經(jīng)常有香客問我瞭恰,道長,這世上最難降的妖魔是什么狱庇? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任惊畏,我火速辦了婚禮,結(jié)果婚禮上密任,老公的妹妹穿的比我還像新娘颜启。我一直安慰自己,他們只是感情好批什,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布农曲。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪乳规。 梳的紋絲不亂的頭發(fā)上形葬,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天,我揣著相機(jī)與錄音暮的,去河邊找鬼笙以。 笑死,一個胖子當(dāng)著我的面吹牛冻辩,可吹牛的內(nèi)容都是我干的猖腕。 我是一名探鬼主播,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼恨闪,長吁一口氣:“原來是場噩夢啊……” “哼倘感!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起咙咽,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤老玛,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后钧敞,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蜡豹,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年溉苛,在試婚紗的時候發(fā)現(xiàn)自己被綠了镜廉。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡愚战,死狀恐怖娇唯,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情凤巨,我是刑警寧澤视乐,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站敢茁,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏留美。R本人自食惡果不足惜彰檬,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望谎砾。 院中可真熱鬧逢倍,春花似錦、人聲如沸景图。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至亮蒋,卻和暖如春扣典,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背慎玖。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工贮尖, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人趁怔。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓湿硝,卻偏偏與公主長得像,于是被迫代替她去往敵國和親润努。 傳聞我的和親對象是個殘疾皇子关斜,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件铺浇、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,024評論 4 62
  • 一點(diǎn)背景知識 OpenCV 是一個開源的計(jì)算機(jī)視覺和機(jī)器學(xué)習(xí)庫痢畜。它包含成千上萬優(yōu)化過的算法,為各種計(jì)算機(jī)視覺應(yīng)用提...
    沬日十七閱讀 1,000評論 0 4
  • 1 實(shí)驗(yàn)?zāi)康?目前計(jì)算機(jī)視覺技術(shù)已經(jīng)比較成熟随抠,相關(guān)的開源項(xiàng)目與算法很多裁着,可以將這些開源算法進(jìn)行整合,進(jìn)而做成一個小...
    YOUNG_FAN閱讀 6,677評論 0 50
  • ②尼瑪劇情也太快了吧 想著想著拱她,突然眼前一片漆黑二驰,我拿出手機(jī)來照亮,可是我一點(diǎn)也動不了秉沼,一道光閃過桶雀,我到了一片平原...
    視姬哥閱讀 246評論 0 0
  • 白駒過隙敞咧,時光荏苒棘捣,一轉(zhuǎn)眼,整整兩個月過去了休建,兩個月的時間乍恐,快的讓我猝不及防,快的讓我心中感慨测砂,我依稀記得3月5號...
    麥浪下的花香閱讀 736評論 0 1