參照opencv官網例程寫了一個基于python的行人檢測程序,實現了和自帶檢測器基本一致的檢測效果。
網址 :https://docs.opencv.org/3.4.0/d5/d77/train_HOG_8cpp-example.html
opencv版本:3.4.0
訓練集和opencv官方用了同一個,可以從http://pascal.inrialpes.fr/data/human/下載,在網頁的最下方“here(970MB處)”,用迅雷下載比較快(500kB/s)。訓練集文件比較亂,需要仔細閱讀下載首頁的文字介紹。注意pos文件夾下的png圖片屬性,它們用opencv無法直接打開,linux系統下也無法顯示,需要用matlab讀取圖片->保存才行,很奇怪的操作。
代碼如下,盡可能與opencv官方例程保持一致,但省略了很多不是很關鍵的東西。訓練一次大概需要十幾分鐘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
import cv2 import numpy as np import random def load_images(dirname, amout = 9999 ): img_list = [] file = open (dirname) img_name = file .readline() while img_name ! = '': # 文件尾 img_name = dirname.rsplit(r '/' , 1 )[ 0 ] + r '/' + img_name.split( '/' , 1 )[ 1 ].strip( '\n' ) img_list.append(cv2.imread(img_name)) img_name = file .readline() amout - = 1 if amout < = 0 : # 控制讀取圖片的數量 break return img_list # 從每一張沒有人的原始圖片中隨機裁出10張64*128的圖片作為負樣本 def sample_neg(full_neg_lst, neg_list, size): random.seed( 1 ) width, height = size[ 1 ], size[ 0 ] for i in range ( len (full_neg_lst)): for j in range ( 10 ): y = int (random.random() * ( len (full_neg_lst[i]) - height)) x = int (random.random() * ( len (full_neg_lst[i][ 0 ]) - width)) neg_list.append(full_neg_lst[i][y:y + height, x:x + width]) return neg_list # wsize: 處理圖片大小,通常64*128; 輸入圖片尺寸>= wsize def computeHOGs(img_lst, gradient_lst, wsize = ( 128 , 64 )): hog = cv2.HOGDescriptor() # hog.winSize = wsize for i in range ( len (img_lst)): if img_lst[i].shape[ 1 ] > = wsize[ 1 ] and img_lst[i].shape[ 0 ] > = wsize[ 0 ]: roi = img_lst[i][(img_lst[i].shape[ 0 ] - wsize[ 0 ]) / / 2 : (img_lst[i].shape[ 0 ] - wsize[ 0 ]) / / 2 + wsize[ 0 ], \ (img_lst[i].shape[ 1 ] - wsize[ 1 ]) / / 2 : (img_lst[i].shape[ 1 ] - wsize[ 1 ]) / / 2 + wsize[ 1 ]] gray = cv2.cvtColor(roi, cv2.COLOR_BGR2GRAY) gradient_lst.append(hog.compute(gray)) # return gradient_lst def get_svm_detector(svm): sv = svm.getSupportVectors() rho, _, _ = svm.getDecisionFunction( 0 ) sv = np.transpose(sv) return np.append(sv, [[ - rho]], 0 ) # 主程序 # 第一步:計算HOG特征 neg_list = [] pos_list = [] gradient_lst = [] labels = [] hard_neg_list = [] svm = cv2.ml.SVM_create() pos_list = load_images(r 'G:/python_project/INRIAPerson/96X160H96/Train/pos.lst' ) full_neg_lst = load_images(r 'G:/python_project/INRIAPerson/train_64x128_H96/neg.lst' ) sample_neg(full_neg_lst, neg_list, [ 128 , 64 ]) print ( len (neg_list)) computeHOGs(pos_list, gradient_lst) [labels.append( + 1 ) for _ in range ( len (pos_list))] computeHOGs(neg_list, gradient_lst) [labels.append( - 1 ) for _ in range ( len (neg_list))] # 第二步:訓練SVM svm.setCoef0( 0 ) svm.setCoef0( 0.0 ) svm.setDegree( 3 ) criteria = (cv2.TERM_CRITERIA_MAX_ITER + cv2.TERM_CRITERIA_EPS, 1000 , 1e - 3 ) svm.setTermCriteria(criteria) svm.setGamma( 0 ) svm.setKernel(cv2.ml.SVM_LINEAR) svm.setNu( 0.5 ) svm.setP( 0.1 ) # for EPSILON_SVR, epsilon in loss function? svm.setC( 0.01 ) # From paper, soft classifier svm.setType(cv2.ml.SVM_EPS_SVR) # C_SVC # EPSILON_SVR # may be also NU_SVR # do regression task svm.train(np.array(gradient_lst), cv2.ml.ROW_SAMPLE, np.array(labels)) # 第三步:加入識別錯誤的樣本,進行第二輪訓練 # 參考 http://masikkk.com/article/SVM-HOG-HardExample/ hog = cv2.HOGDescriptor() hard_neg_list.clear() hog.setSVMDetector(get_svm_detector(svm)) for i in range ( len (full_neg_lst)): rects, wei = hog.detectMultiScale(full_neg_lst[i], winStride = ( 4 , 4 ),padding = ( 8 , 8 ), scale = 1.05 ) for (x,y,w,h) in rects: hardExample = full_neg_lst[i][y:y + h, x:x + w] hard_neg_list.append(cv2.resize(hardExample,( 64 , 128 ))) computeHOGs(hard_neg_list, gradient_lst) [labels.append( - 1 ) for _ in range ( len (hard_neg_list))] svm.train(np.array(gradient_lst), cv2.ml.ROW_SAMPLE, np.array(labels)) # 第四步:保存訓練結果 hog.setSVMDetector(get_svm_detector(svm)) hog.save( 'myHogDector.bin' ) |
以下是測試代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
import cv2 import numpy as np hog = cv2.HOGDescriptor() hog.load( 'myHogDector.bin' ) cap = cv2.VideoCapture( 0 ) while True : ok, img = cap.read() rects, wei = hog.detectMultiScale(img, winStride = ( 4 , 4 ),padding = ( 8 , 8 ), scale = 1.05 ) for (x, y, w, h) in rects: cv2.rectangle(img, (x, y), (x + w, y + h), ( 0 , 0 , 255 ), 2 ) cv2.imshow( 'a' , img) if cv2.waitKey( 1 )& 0xff = = 27 : # esc鍵 break cv2.destroyAllWindows() |
到此這篇關于python+opencv3.4.0 實現HOG+SVM行人檢測的示例代碼的文章就介紹到這了,更多相關opencv HOG+SVM行人檢測內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!
原文鏈接:https://blog.csdn.net/qq_33662995/article/details/79356939