1. 程式人生 > >Emgu.CV訓練自己的hog特徵,可實現任意物體的檢測

Emgu.CV訓練自己的hog特徵,可實現任意物體的檢測

本文由:姚磊嶽([email protected])於2017-5-28撰,轉載請保留作者資訊。

按照慣例,先吐槽:Emgu.CV的資料太少了,不知道是不是C#做圖形的太小眾。因為專案需要,需要對圖片中的車輛進行標定。於是想到了HOG+SVM的方式。在Emgu.CV中預設提供了已經訓練好的行人檢測的特徵,但是如果要檢測其他物體,必須自己進行訓練。於是在網上一通尋找,居然沒有完整的程式碼,沒辦法,只有苦逼的自己動手。弄了整整一天,終於實現。應該是目前網路上比較詳細的一篇EMGU.CV自行訓練的文章了,大家如要轉載請保留作者資訊。效果如圖:


方便自己,也方便他人,把今天所實現的程式碼上傳,並詳細說明。時間有限,沒有做封裝,湊合著看。

需要具備:

1、HOG的基本概念;

2、用於檢測目標的正負樣本。如:需要檢測的是車輛,則需要有車輛的各種樣本。本文車輛正樣本只有500個,所以最終的檢測效果並不好(如上圖所示),如果樣本足夠,可以檢測到圖片中的全部車輛。

思路流程:

1、根據訓練樣本,設計HOG描述子;

2、獲取正負樣本HOG值;

3、訓練SVM;

4、從訓練好的SVM提取出hog描述值(一個一維的float陣列,這是實現過程中最難的)

5、檢測

檢測

詳解:

1、根據訓練樣本,設計HOG描述子(有的也叫HOG運算元);

這裡需要有HOG的基本概念,什麼是視窗大小,什麼是block,什麼是cell等等,網上資料很多,這裡不做過多屆時。

在我的實現中,正負訓練樣本是36*36畫素的圖片,於是,我的HOG運算元設計如下:


第一個引數:winsize:視窗大小,我取樣本大小;

第二個引數:block,我的是12*12;當然,也可以設定為18*18或者6*6,切記:BLOCK大小不能是技術值,至於為什麼,看一下cell和block的關係即可。同時:設計的過程中,BLOCK要可被winsize整除。網上的資料都是16*16,也沒有說清楚為什麼,其實這個看懂了HOG後可以自行設定

第三個引數:stride,我的設定是6*6,當然也可以設定為12*12或者4*4,不同的設定,將得到不同的緯度數量;

第四個引數:cell,4個cell構成1個block,這也就是block一定要是偶數的原因。

第五個引數:需要得到幾個channel的值,預設是9個,具體原因請參見HOG原論文

當我們設定完畢後,緯度資訊就可以計算出來了

a = (winsize寬-block寬) / stride寬 +1

b = (winsize高-block高) / stride高 +1

c = block寬 / cell寬 

d = block高/block高

緯度 = a*b*c*d*channel數,在本例中為:5*5*2*2*9 = 900

這個值,在通過hog.compute(圖片)時也可以得到,當然,自己算一下也未嘗不可,至少不用像網上資料那樣進行判斷。

2、獲取正負樣本HOG值

這一步相對來說很簡單,即:將正負樣本圖片一一讀入,然後逐一計算,並新增到matrix中即可。直接上程式碼:



有必要說明的是:

(1)Image<Gray, byte> im = new Emgu.CV.Image<Gray, byte>(filePath);

hog支援的是灰度圖片,不能用彩色圖片進行訓練。

(2)

Matrix<float> HogFeatureData = new Matrix<float>(967, 900);

//500樣本+467負樣本,HOG緯度=(36-12)/6 + 1) *(36-12)/6 + 1) * 4 *9
        Matrix<int> featureClasses = new Matrix<int>(967, 1);

這是SVM訓練所需要的兩個引數,HogFeatureData是全部樣本(正負樣本都在)的hog矩陣,其中967是樣本數量,900是HOG的緯度,怎麼來的,前面已經說明了計算方法。

featureClasses是每一個樣本對應的類別,正樣本對應1,負樣本對應-1

3、訓練SVM


這步比較簡單,沒有什麼複雜的地方,直接看程式碼即可。

4、從訓練好的SVM提取出hog描述值

這是實現過程中最難的,也是我本人在實現過程中花時間最多的。當然首先是自己沒有用LibSVM等其他的技術輔助(我也不會,汗……)。我實現的方法很笨,如果各位有LibSVM基礎的,可以忽略我的這個步驟。

首先,得感謝:http://www.cnblogs.com/KC-Mei/p/4553024.html部落格的作者,雖然還有很多方法可以得到項對應的值,但是我也懶得動腦筋,直接拿來主義了。


這裡一共要獲得4個變數。詳細程式碼請下載本文最終所提供的全部原始碼。至於怎麼計算,老樣子,先上程式碼:


(1)首先,如果已經訓練過樣本,並儲存了(本例在第三步所做的事),則可以通過直接讀取XML避免再次訓練。

resultMat = -1 * alphaMat * svmMat;

這個是計算hog detector的關鍵步驟,原理可尋找相關網上資料,這裡就不詳敘了。

(2)float[] mydetector = new float[DescriptorDim + 1];
            for (int i = 0; i < DescriptorDim; i++)
            {
                mydetector[i] = resultMat[0, i];
            }
            mydetector[DescriptorDim] = rhoValue;

這裡一定要說明一下,hog的緯度在本例中是900,但是detector要加上一緯偏移,也就是901緯。組後一緯度的值是rho的節點值。第三步訓練完畢後,我們可以開啟儲存的XML,找到這個節點。

這個步驟牽涉到較多的HOG原理,很奇怪為什麼EmguCv不能直接提供一個封裝的方法。要使用者大費周章去自己計算。也許這就是開源的不足之處吧,有時間了,自己要封裝一個方法,每次這樣寫程式碼得累死,也毫無意義。

接下來第五步:預測 就簡單多了。


(1)為了自己程式設計方便,定義了一個類:myRect,其中:rct用來存放檢測出來的矩形框類性;score是這個矩形框的得分(得分越高,檢測越準,在程式設計過程當中,我們可以通過對score進行閾值設定,以遮蔽一些不靠譜的檢測)

(2)在Using這塊,網上全部的資料都是:HOGDescriptor hog = new HOGDescriptor();

這是不對的,如果僅用來檢測行人,或者預設的hog運算元即可的話(預設hog運算元為:winsize:64*128,block:16*16,stride:8*8,cell:8*8),那沒有問題,但如果我們定義了我們自己的HOG運算元,則必須保持和我們自己hog運算元的一致。故在本例中必須:

using (HOGDescriptor hog = new HOGDescriptor(new Size(36, 36), new Size(12, 12), new Size(6, 6), new Size(6, 6), 9))

然後:

hog.SetSVMDetector(mydetector);

代表,將HOG的SVM的detector設定為我們之前計算出來的值。

設定完畢後,就可以通過我們自行訓練的SVM來進行檢測了。程式碼比較簡單,就不再詳述了。

全部原始碼下載地址:http://download.csdn.net/detail/u011616825/9855112

相關推薦

Emgu.CV訓練自己hog特徵實現任意物體檢測

本文由:姚磊嶽([email protected])於2017-5-28撰,轉載請保留作者資訊。 按照慣例,先吐槽:Emgu.CV的資料太少了,不知道是不是C#做圖形的太小眾。因為專案需要,需要對圖片中的車輛進行標定。於是想到了HOG+SVM的方式。在Emgu.

C#.NET 程序員的福利自己寫的一個XML操作類實現像jquery一樣方便的xml操作且不用專門去處理命名空間。

console region ignorecas node 處理 命名空間 void clone 一個 此工具是進入一家新公司之後實現的,主要是工作當中操作 xml 的時間太多,因為公司按任務計“工作量”,領導給我安排的時間遠遠不夠完善此工具【悲哀的

影象特徵提取三大法寶:HOG特徵LBP特徵Haar特徵

(一)HOG特徵 1、HOG特徵: 方向梯度直方圖(Histogram of Oriented Gradient, HOG)特徵是一種在計算機視覺和影象處理中用來進行物體檢測的特徵描述子。它通過計算和統計影象區域性區域的梯度方向直方圖來構成特徵。Hog特徵結合SVM分

OpenCV學習筆記——用haar特徵訓練自己的分類器(再做手勢檢測

資料還是得看啊,又讀了經典文獻《Robust Real-Time Face Detection》,不願意讀原文的朋友可以看看http://blog.csdn.net/hqw7286/article/details/5556767,作者把文中的要點基本也都總結出來了。Ope

OpenCV學習筆記(三十三)——用haar特徵訓練自己的分類器(再做手勢檢測

資料還是得看啊,又讀了經典文獻《Robust Real-Time Face Detection》,不願意讀原文的朋友可以看看http://blog.csdn.net/hqw7286/article/details/5556767,作者把文中的要點基本也都總結出來了。Ope

用DPM訓練自己的模型並用於視訊檢測

DPM(Deformable PartModel)總結 剛參加完一個機器人比賽,其中要用到雙目進行目標定位,做法是從左右場景圖中找到目標區域,並用目標區域中的特徵點進行雙目匹配定位,定位效果非常好。考慮到實時性和簡單性,尋找目標區域我用的是DPM演算法,匹配效果非常好。DP

自開發自動拉群微信雲控系統實現全自動一鍵拉群

tco key return cati 劃線 除了 com off shm 微信自動拉群雲控系統源碼,全自動一鍵拉群。自動統計新加的好友,自動將所有新加好友一鍵拉群。服務器端下發群二維碼,手機端一鍵拉群。全自動大批量,同時拉群。 在系統的開發實現過程中,除了服務器端推送指

Android BroadcastReceiver使用實現程序間通訊

1、建立廣播接收器: /** * 作者:created by meixi * 郵箱:[email protected] * 日期:2018/11/1 09 */ public class MyBroadcastReceiver extends BroadcastReceiver

java生成mysql資料庫建表語句、欄位、欄位型別、欄位註釋實現不用mysqldump備份資料庫

使用 mysqldump 備份資料庫也是可行的,因為每次備份的時候都需要mysqldump這個檔案, 我在windows備份時沒問題,但是放到linux上面時,centos系統死活不認這個檔案,但又不想裝mysql,一氣之下自己研究了個不需要mysqldump就可以備份的程式, 如果看了以下程式

android自定義星級評分控制元件實現只顯示實心星星

話不多說,上圖 近日app需求弄一個等級展示,看了下UI圖,只顯示實星(點亮的星星).如圖 但是網上關於星級評分的例子大多這樣 也展示虛心星星 通過自定義View package com.starsbar; import android.content.C

卜若的程式碼筆記系列-mysql系列-第三章:通過cmd登入mysql實現遠端登入以及退出切換賬號

1.通過cmd進入到各個硬碟 舉個例子:比如我現在要進入到c盤 直接: C:\Users\Skady_cat>cd/ 或者: C:\Users\Skady_cat>d: 然後cd到mysql的根目錄,如果預設安裝的話應該是這個目錄 C:\Progra

怎麼防止員工私下飛單讓企業受損學會這個工作手機實現微信監控

在業務型公司當中,銷售的重要性毋庸置疑。特別是在市場競爭日趨白熱化的當下,一支戰鬥力強悍、執行能力卓越的銷售團隊,能讓公司在競爭當中脫穎而出。從這個層面而言,好銷售是公司最珍貴的資源。 但在傳統的管理模式下,“飛單”“私下交易”“辱罵客戶”等不規範行為時有發生。更

Tensorflow訓練自己的Object Detection模型並進行目標檢測

0.準備工作 1.專案目錄概覽 圖1 object detection專案目錄 2.準備資料集和相關檔案 下載VOC2007資料集,解壓放到dataset目錄下,如圖1。

angularjs 實現 三級省市區聯動實現無限級聯動

一個select標籤實現省市區三級聯動 html 程式碼: # 頁面呼叫元件 <select-component ng-repeat="field in data.fieldsList trac

使用z-index和position:absolute實現DIV覆蓋和重疊實現半透明背景上邊漂浮一層不透明的div層。

Div的重疊和覆蓋可以使用z-index和position:absolute決定定位來實現,具體實現程式碼如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3

掃雷(C語言實現)(第一步不炸死實現展開)

掃雷遊戲大家應該都有玩過,今天的我們用C語言實現一下掃雷遊戲。點開時第一步不炸死,而且沒有雷的周圍會展開。 實現思路 1.棋盤設計: 必須要設計倆個棋盤,一個設計者棋盤,一個玩家棋盤。 2.棋盤列印:     列印棋盤 3.雷的佈置 我的程式碼中採用9

python應用例項:座標轉換——基於布林莎模型實現BJ54座標系/GSC2000座標系/WGS84等各種地心直角座標系的轉換

博主準研究僧一枚,假期在老師指導下接觸專案。本博文可作為座標轉換,特別是布林莎七引數法的學習資料。其python原始碼註釋充分,也可作為python的學習專案。程式UI介面如下,由於是自用程式,博主對美化UI不感興趣,ui部分原始碼註釋充分,顏控可自行修改調整。PS:克總信徒

redis+sentinel+keepalived 高可用實現多臺並單點訪問

       之前有寫過redis+sentinel的哨兵機制主從的切換,這一次多了一個keepalived,是為了能夠方便專案只支援一臺訪問,可是又要高可用的情況下,就可以執行此方案。 本次主要講的就是keepalived的配置,如何才能做到單臺訪問而實現高可用,從而實

修改UIPageControl的點點替換任意圖片image。

把點替換成自己的圖片,只要重整這兩個屬性即可 [pageControl setValue:[UIImage imageWithName:@"selected"] forKeyPath:@"_cur