欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

python+opencv3.4.0 实现HOG+SVM行人检测的示例代码

程序员文章站 2022-03-07 11:05:48
参照opencv官网例程写了一个基于python的行人检测程序,实现了和自带检测器基本一致的检测效果。网址 :https://docs.opencv.org/3.4.0/d5/d77/train_ho...

参照opencv官网例程写了一个基于python的行人检测程序,实现了和自带检测器基本一致的检测效果。

网址 :https://docs.opencv.org/3.4.0/d5/d77/train_hog_8cpp-example.html

opencv版本:3.4.0

训练集和opencv官方用了同一个,可以从下载,在网页的最下方“here(970mb处)”,用迅雷下载比较快(500kb/s)。训练集文件比较乱,需要仔细阅读下载首页的文字介绍。注意pos文件夹下的png图片属性,它们用opencv无法直接打开,linux系统下也无法显示,需要用matlab读取图片->保存才行,很奇怪的操作。

代码如下,尽可能与opencv官方例程保持一致,但省略了很多不是很关键的东西。训练一次大概需要十几分钟

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')

以下是测试代码:

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行人检测内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!