ubuntu下openCV-Haar特徵分類器訓練

ubuntu下openCV-Haar特徵分類器訓練


  • 這段時間在學openCV,準備作一個頭部檢測,可是openCV自帶的分類器只有人臉檢測的,並且準確度不高,就準備本身訓練一個分類器。在網上看了不少的博客,都講得不是很清楚,並且全是在windows上訓練的,對與用習慣linux的我來講,用cmd實在是太痛苦了,而我沒有在網上找到這方面的博客,甚至連opencv_createsamplesopencv_traincascade在哪都沒說只說在openCV目錄下,可是直接安裝的openCV下不少是沒有的,對於新手來說會很是迷茫,徹底搞不懂。html

  • 而後我就到github上看openCV的倉庫,發現倉庫的apps目錄下有分類器源碼,以爲能夠本身在linux下編譯一個訓練器python

  • 進過幾回嘗試,我發現openCV4以上版本源碼編譯出來是沒有我須要的這兩個訓練器的,3一下版本的會報錯,具體什麼緣由我不清楚,openCV-3.4.9版本的徹底沒有問題linux

1、安裝Cmake

一、安裝方法一

sudo apt install cmake 

2、安裝方法二

2.1 CMake 下載地址

2.2 安裝配置

  • 解壓:tar zxvf cmake-3.16.5-Linux-x86_64.tar.gz 緩存

  • 移到opt目錄下:mv cmake-3.16.5-Linux-x86_64 /optapp

  • 創建軟鏈接:ln -s /opt/cmake-3.16.5-Linux-x86_64/bin/* /usr/binide

  • 檢測安裝是否成功:

    • cmake --version

      cmake version 3.16.5
      CMake suite maintained and supported by Kitware (kitware.com/cmake).

2、編譯openCV

1、下載

二、安裝依賴

  • 下面的步驟已經在Ubuntu10.04上測試過了,可是也能夠在其餘發行版上使用。

  • 必需的包

    • GCC 4.4.x 或更新

    • CMake 2.8.7 或更高版本

    • Git

    • GTK+2.x 或更高版本, including 頭 (libgtk2.0-dev)

    • pkg-config

    • Python 2.6或更高版本以及帶有開發人員包的Numpy 1.5或更高版本(Python -dev, Python - Numpy)

    • ffmpeg或libav開發包:libavcodec-dev,libavformat-dev,libswscale-dev

    • [可選] libtbb2 libtbb-dev

    • [可選] libdc1394 2.x

    • [可選] libjpeg-dev, libpng-dev, libtiff-dev, libjasper-dev, libdc1394-22-dev

    • [可選] CUDA Toolkit 6.5 or higher

  • sudo add-apt-repository "deb http://security.ubuntu.com/ubuntu xenial-security main"
    sudo apt-get install build-essential
    # 若是安裝了cmake 和git 的能夠刪下面的選項
    sudo apt-get install cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev
    sudo apt-get install python-dev python-numpy libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-dev libjasper-dev libdc1394-22-dev

三、編譯

  • 解壓:unzip mirrors-opencv-3.4.9.zip

  • cd opencv
    mkdir build    # 編譯會生成不少文件,最好建一個文件夾來保存
    cd build    
    cmake ../         # 生成makefile
    make                 # 使用makefile編譯     時間會很長,二十分鐘的樣子
  • 編譯好後就能夠找咱們須要的訓練器了

    cd build/bin          # 這樣就能夠看見了

3、訓練分類器

1、教程:

2、準備樣本

  • 建立pos目錄裝正樣本

    • 正負樣本都要轉化成灰度圖,並且對於正樣本用haar特徵訓練是規格化成20×20或其餘大小,最好不要太大,過多的haar特徵會影響分類器的訓練時間;對於LBP特徵正樣本要規格化爲24×24大小,而對於HOG要規格化成64×64. 負樣本對尺寸沒有統一要求,在訓練對應的分類器時,選擇的負樣本尺寸必定要大於等於正樣本規定的尺寸。

  • 建立neg目錄裝負樣本

    • 負樣本有兩點要求:1)不能包含正樣本且儘量多的提供場景的背景圖;2)負樣本儘量的多,並且要多樣化,和正樣本有必定的差距可是差異也不要太大,不然容易在第一級就所有被分類器reject,訓練時不能顯示負樣本的個數,從而致使卡死。

  • 建立xml目錄裝訓練數據

  • 將訓練器opencv_createsamples opencv_traincascade拷貝到當前路徑下

  • ls -rt pos > pos.txt    # pos.txt 正樣本相對路徑表
    ls -rt neg > neg.txt # neg.txt 負樣本相對路徑表
  • 修改pos.txt和neg.txt

  • gedit pos.txt
  • Ctrl + A 全選 ,而後按Tab 鍵

  • 選一個空格

  • 選擇查找替換

  • 所有替換,neg.txt的這一步替換長neg/

  • pos.txt還須要多一步,不然會報錯,1 表明個數 0 0 表明照片的起點座標,50 50 爲個人照片的大小

3、生成描述文件

  • ./opencv_createsamples -info pos.txt -vec pos.vec -bg neg.txt -num 2874 -w 50 -h 50

  • 以上參數的含義以下: vec <vec_file_name>:訓練好的正樣本的輸出文件名。 img<image_file_name>:源目標圖片 bg<background_file_name>:背景描述文件。 num<number_of_samples>:要產生的正樣本的數量,和正樣本圖片數目相同。 bgcolor<background_color>:背景色。背景色制定了透明色。對於壓縮圖片,顏色方差量由bgthresh參數來指定。則在bgcolor-bgthresh 和bgcolor+bgthresh 中間的像素被認爲是透明的。 bgthresh<background_color_threshold>

    inv:若是指定,顏色會反色 randinv:若是指定,顏色會任意反色 maxidev<max_intensity_deviation>:背景色最大的偏離度。 maxangel<max_x_rotation_angle>, maxangle<max_y_rotation_angle>, maxzangle<max_x_rotation_angle>:最大旋轉角度,以弧度爲單位。 show:若是指定,每一個樣本會被顯示出來,按下"esc"會關閉這一開關,即不顯示樣本圖片,而建立過程 繼續。這是個有用的debug 選項。 w<sample_width>:輸出樣本的寬度(以像素爲單位) h<sample_height>:輸出樣本的高度(以像素爲單位)

    只須要對正樣本進行以上操做,負樣本不須要生成vec文件。。。

4、訓練

  • 注意:這裏要找一臺好一點的電腦訓練,我訓練一萬的樣本,從最開始一天訓練一級,而後每級的時間增長半天,到第五級已經差很少須要三天了,預計到20級沒一兩月搞不定

  • ./opencv_traincascade -data xml -vec pos.vec -bg neg.txt -numPos 2000 -numNeg 7370  -numStages 20 -featureType HAAR -w 50 -h 50   
    # 注意大小寫,寫錯可能不會報錯,可是識別不了,就會使用默認值,這裏我就被坑過
    # 訓練時間會很是很是長,我第一次用了198正樣本、368負樣本就訓練了一個晚上,第二次用兩千多的正樣本,三千多的負樣本就更長了,可是訓練中途斷了再執行命令時會繼續上一次訓練
    # 注意 :這裏的-numPos *** 必定要比 準備.vec文件時的 -num *** 小,不然在訓練時可能會報錯,顯示找不到更多正樣本
  • 像我這裏輸入-numPos 2000 ,在訓練到第三級時就須要2018個正樣本,若是.vec裏只有2000個就會找不到新的正樣本,從而報錯

  • 以上參數的含義以下:

    -data <cascade_dir_name>:目錄用於保存訓練產生的分類器xml文件和中間文件,如不存在訓練程序會建立它;

    -vec <vec_file_name>:由 opencv_createsamples 程序生成的包含正樣本的vec文件名;

    -bg <background_file_name>:背景描述文件,也就是包含負樣本文件名的那個描述文件

    -numPos <number_of_positive_samples>:每級分類器訓練時所用的正樣本數目(默認值爲2000); -numNeg <number_of_negative_samples>:每級分類器訓練時所用的負樣本數目,能夠大於 -bg 指定的圖片數目(默認值爲1000);

    -numStages <number_of_stages>:訓練的分類器的級數(默認值爲20級);

    -precalcValBufSize <precalculated_vals_buffer_size_in_Mb>:緩存大小,用於存儲預先計算的特徵值(feature values),單位爲MB(默認值爲256); -precalcIdxBufSize <precalculated_idxs_buffer_size_in_Mb>:緩存大小,用於存儲預先計算的特徵索引(feature indices),單位爲MB(默認值爲256);

    內存越大,訓練時間越短。 -baseFormatSave:這個參數僅在使用Haar特徵時有效。若是指定這個參數,那麼級聯分類器將以老的格式存儲(默認不指定該參數項,此時其值爲false;一旦指定則其值默認爲true);

    級聯參數:CvCascadeParams類,定義於cascadeclassifier.h -stageType <BOOST(default)>:級別(stage)參數。目前只支持將BOOST分類器做爲級聯的類型; -featureType<{HAAR(default), LBP}>:特徵的類型: HAAR - 類Haar特徵; LBP - 局部紋理模式特徵(默認Harr); -w <sampleWidth>:訓練樣本的寬(單位爲像素,默認24); -h <sampleHeight>:訓練樣本的高(單位爲像素,默認24); 訓練樣本的尺寸必須跟訓練樣本建立(使用 opencv_createsamples 程序建立)時的尺寸保持一致。

    Boosted分類器參數:CvCascadeBoostParams類,定義於boost.h -bt <{DAB, RAB, LB, GAB(default)}>:Boosted分類器的類型(DAB - Discrete AdaBoost, RAB - Real AdaBoost, LB - LogitBoost, GAB - Gentle AdaBoost爲默認); -minHitRate <min_hit_rate>:分類器的每一級但願獲得的最小檢測率(默認值爲0.995),總的檢測率大約爲 min_hit_rate^number_of_stages; -maxFalseAlarmRate <max_false_alarm_rate>:分類器的每一級但願獲得的最大誤檢率(默認值爲0.5),總的誤檢率大約爲 max_false_alarm_rate^number_of_stages; -weightTrimRate <weight_trim_rate>:Specifies whether trimming should be used and its weight,一個還不錯的數值是0.95; -maxDepth <max_depth_of_weak_tree>:弱分類器樹最大的深度。一個還不錯的數值是1,是二叉樹(stumps);

    -maxWeakCount <max_weak_tree_count>:每一級中的弱分類器的最大數目(默認值爲100)。The boosted classifier (stage) will have so many weak trees (<=maxWeakCount), as needed to achieve the given -maxFalseAlarmRate;

  • 最後等一夜就能夠獲得訓練的分類器了,cascade.xml就是咱們的分類器

  • image-20200313023532502

4、分類器

5、測試程序

import  cv2

face = cv2.CascadeClassifier("./data/cascade.xml")  #人臉識別
cap = cv2.VideoCapture(2)

while True:
   ret, img = cap.read()
   roi_color = 0
   gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)    #轉換爲灰度圖片,haar特徵都是在灰度上檢測
   faces = face.detectMultiScale(gray,1.3,5)       #參數1:灰度圖片數據   2:縮放比例 3:人臉大小不能小於5個像素

   # 獲取寬高信息,我的臉畫方框
   for (x,y,w,h) in faces:
       # img:要畫的圖片,(x,y):起始座標 ,(x+w,y+h):寬高,顏色,線條寬度
       cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
   
   cv2.imshow('10',img)
   if cv2.waitKey(5) & 0xff == ord("q"):
       break

cap.release()
cv2.destroyAllWindows()
相關文章
相關標籤/搜索