1. 程式人生 > >opencv︱opencv中實現行人檢測:HOG+SVM(二)

opencv︱opencv中實現行人檢測:HOG+SVM(二)

零、行人檢測綜述

行人檢測,就是將一張圖片中的行人檢測出來,並輸出bounding
box級別的結果。而如果將各個行人之間的軌跡關聯起來,就變成了行人跟蹤。而行人檢索則是把一段視訊中的某個感興趣的人檢索出來。

行人檢測領域的工作大致可被歸為以下三類:

  • 第一類是將傳統的檢測方法Boosting trees 和 CNN 結合起來。張姍姍等人在CVPR 2016的工作是使用 ICF
    提取proposal,然後使用 CNN 進行重新打分來提高檢測的效能;在 ECCV 2016上,中山大學林倞教授課題組使用RPN 提取
    proposal,同時提取卷積特徵,然後使用 Boosting trees進行二次分類,效能得到了很大的提升。
  • 第二類是解決多尺度問題,例如在視訊資料中人的尺度變化問題。顏水成教授課題組提供了一種解決方法:訓練兩個網路,一個網路關注大尺度的人,另一個網路關注小尺度的人,在檢測時將兩個網路進行加權融合得到最終的結果,這樣能使效能得到很大的提升;UCSD
    在 ECCV
    2016上有一個類似的工作,提出在高層提取大尺度人的特徵,在低層提取小尺度人的特徵,這樣能保留儘量多的資訊量,使得對小尺度的行人也有較好的檢測效果。
  • 第三類是使用語義分割資訊來輔助行人檢測。首先對整個影象進行語義分割,然後將分割的結果作為先驗資訊輸入到檢測網路中(包括傳統的 ICF
    網路,以及現在常用的CNN),這樣可以通過對整體環境的感知來提高檢測的效果。

新提高檢測率的科研方式:

2016年張姍姍等人從分析的角度對各個工作進行總結和歸納。通過分析錯誤案例來找到錯誤來源,並提出相應的解決方案以進一步提高檢測率。研究發現,在高層級中主要有兩類錯誤,分別是定位錯誤和背景分類錯誤。可以嘗試兩個解決方案,其一是針對檢測框對齊性比較差這一現象,可以通過使用對齊性更好的訓練樣本標籤來解決;而針對模型判別能力比較差的問題,可以通過在傳統的 ICF 模型上使用 CNN 進行重新打分來提升檢測的效能。

資料集:

CVPR 2017上將會公佈一個新的行人檢測資料集:CityPersons。CityPersons資料集是脫胎於語義分割任務的Cityscapes資料集,對這個資料集中的所有行人提供 bounding box 級別的對齊性好的標籤。由於CityPersons資料集中的資料是在3個不同國家中的18個不同城市以及3個季節中採集的,其中單獨行人的數量明顯高於Caltech 和 KITTI 兩個資料集。實驗結果也表明,CityPersons 資料集上訓練的模型在 Caltech 和 KITTI 資料集上的測試漏檢率更低。也就是說,CityPersons資料集的多樣性更強,因而提高了模型的泛化能力。
文中提到所有論文的下載連結為:

http://pan.baidu.com/s/1eRO9xoY

一、基本理解

HOG屬於特徵提取,它統計梯度直方圖特徵。具體來說就是將梯度方向(0->360°)劃分為9個區間,將影象化為16x16的若干個block,每個block在化為4個cell(8x8)。對每一個cell,算出每一點的梯度方向和模,按梯度方向增加對應bin的值,最終綜合N個cell的梯度直方圖形成一個高維描述子向量。實際實現的時候會有各種插值。
選用的分類器是經典的SVM。
檢測框架為經典的滑動視窗法,即在位置空間和尺度空間遍歷搜尋檢測。

原始影象打完補丁後就直接用固定的視窗在影象中移動,計算檢測視窗下的梯度,形成描述子向量,然後就直接SVM了
這裡寫圖片描述

這裡寫圖片描述

二、opencv實現的code

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/gpu/gpu.hpp>
#include <stdio.h>

using namespace cv;

int main(int argc, char** argv)
{
    Mat img;
    vector<Rect> found;
     img = imread(argv[1]);
    if(argc != 2 || !img.data)
    {
        printf("沒有圖片\n");
        return -1;
    }
    HOGDescriptor defaultHog;
    defaultHog.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector());
    //進行檢測
    defaultHog.detectMultiScale(img, found);
    //畫長方形,框出行人
    for(int i = 0; i < found.size(); i++)
            {
        Rect r = found[i];
        rectangle(img, r.tl(), r.br(), Scalar(0, 0, 255), 3);
    }
    namedWindow("檢測行人", CV_WINDOW_AUTOSIZE);
    imshow("檢測行人", img);
    waitKey(0);

    return 0;
}

上述過程並沒有像人臉檢測Demo裡有Load訓練好的模型的步驟,這個getDefaultPeopleDetector是預設模型,這個模型資料在OpenCV原始碼中是一堆常量數字,這些數字是通過原作者提供的行人樣本INRIAPerson.tar訓練得到的。
這裡只是用到了HOG的識別模組,OpenCV把HOG包的內容比較多,既有HOG的特徵提取,也有結合SVM的識別,這裡的識別只有檢測部分,OpenCV提供預設模型,如果使用新的模型,需要重新訓練。

三、如何降低行人檢測誤識率

本節轉載於:機器視覺學習筆記(3)–如何降低行人檢測誤識率
現在的行人檢測演算法大多是應用HOG特徵識別整體,雖然這也能達到較高的識別率,但誤識別率也比較大,因此有必要進行優化識別。
通過大量樣本分析發現,人體的姿態除了四肢,其他大體固定,人體示意圖如圖1所示。
1478702315943084.png
圖1:人體示意圖
我們可以通過組合識別優化檢測演算法來實現。首先可以通過腿部識別,再在腿部的對應上區域對肩膀至頭部位識別,從而降低誤識率。
腿部由於走動原因姿態會有變化,所以很難用比較直觀的特徵去識別,可以用HOG+SVM識別腿部,如圖2所示。
這裡寫圖片描述
圖2:腿部識別
肩膀至頭部的邊緣輪廓類似形狀Ω,如圖3所示。

圖3:肩膀至頭部輪廓形狀
由此我們可以知道其形狀特徵大體固定,可將輪廓的Hu不變矩作為主要特徵,訓練識別器。識別可得,如圖4所示。
這裡寫圖片描述
圖4:肩膀至頭部識別
由此我可以得到最終的行人檢測,如圖5所示。
這裡寫圖片描述
圖5:行人檢測
在本人收集的訓練庫上,用該演算法與OPenCV自帶的行人檢測演算法相比,誤識率有顯著的降低。

四、行人檢測的資料庫與開源專案

1、
http://pascal.inrialpes.fr/soft/olt/行人檢測開源庫
簡介:
Dalal於2005年提出了基於HOG特徵的行人檢測方法, HOG特徵目前也被用在其他的目標檢測與識別、影象檢索和跟蹤等領域中。

2、行人檢測DataSets
參考於:NLP+VS︱深度學習資料集標註工具、影象語料資料庫、實驗室搜尋ing…
(1).基於背景建模:利用背景建模方法,提取出前景運動的目標,在目標區域內進行特徵提取,然後利用分類器進行分類,判斷是否包含行人;
(2).基於統計學習的方法:這也是目前行人檢測最常用的方法,根據大量的樣本構建行人檢測分類器。提取的特徵主要有目標的灰度、邊緣、紋理、顏色、梯度直方圖等資訊。分類器主要包括神經網路、SVM、adaboost以及現在被計算機視覺視為寵兒的深度學習。

該資料庫是目前規模較大的行人資料庫,採用車載攝像頭拍攝,約10個小時左右,視訊的解析度為640×480,30幀/秒。標註了約250,000幀(約137分鐘),350000個矩形框,2300個行人,另外還對矩形框之間的時間對應關係及其遮擋的情況進行標註。資料集分為set00~set10,其中set00~set05為訓練集,set06~set10為測試集(標註資訊尚未公開)。效能評估方法有以下三種:(1)用外部資料進行訓練,在set06~set10進行測試;(2)6-fold交叉驗證,選擇其中的5個做訓練,另外一個做測試,調整引數,最後給出訓練集上的效能;(3)用set00~set05訓練,set06~set10做測試。由於測試集的標註資訊沒有公開,需要提交給Pitor Dollar。結果提交方法為每30幀做一個測試,將結果儲存在txt文件中(檔案的命名方式為I00029.txt I00059.txt ……),每個txt檔案中的每行表示檢測到一個行人,格式為“[left, top,width, height, score]”。如果沒有檢測到任何行人,則txt文件為空。該資料庫還提供了相應的Matlab工具包,包括視訊標註資訊的讀取、畫ROC(Receiver Operatingcharacteristic Curve)曲線圖和非極大值抑制等工具。