python+opencv3.4.0 实现HOG+SVM行人检测的示例代码
参照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官方例程保持一致,但省略了很多不是很关键的东西。训练一次大概需要十几分钟
importcv2
importnumpyasnp
importrandom
defload_images(dirname,amout=9999):
img_list=[]
file=open(dirname)
img_name=file.readline()
whileimg_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
ifamout<=0:#控制读取图片的数量
break
returnimg_list
#从每一张没有人的原始图片中随机裁出10张64*128的图片作为负样本
defsample_neg(full_neg_lst,neg_list,size):
random.seed(1)
width,height=size[1],size[0]
foriinrange(len(full_neg_lst)):
forjinrange(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])
returnneg_list
#wsize:处理图片大小,通常64*128;输入图片尺寸>=wsize
defcomputeHOGs(img_lst,gradient_lst,wsize=(128,64)):
hog=cv2.HOGDescriptor()
#hog.winSize=wsize
foriinrange(len(img_lst)):
ifimg_lst[i].shape[1]>=wsize[1]andimg_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))
#returngradient_lst
defget_svm_detector(svm):
sv=svm.getSupportVectors()
rho,_,_=svm.getDecisionFunction(0)
sv=np.transpose(sv)
returnnp.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_inrange(len(pos_list))]
computeHOGs(neg_list,gradient_lst)
[labels.append(-1)for_inrange(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)#forEPSILON_SVR,epsiloninlossfunction?
svm.setC(0.01)#Frompaper,softclassifier
svm.setType(cv2.ml.SVM_EPS_SVR)#C_SVC#EPSILON_SVR#maybealsoNU_SVR#doregressiontask
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))
foriinrange(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)inrects:
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_inrange(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')
以下是测试代码:
importcv2
importnumpyasnp
hog=cv2.HOGDescriptor()
hog.load('myHogDector.bin')
cap=cv2.VideoCapture(0)
whileTrue:
ok,img=cap.read()
rects,wei=hog.detectMultiScale(img,winStride=(4,4),padding=(8,8),scale=1.05)
for(x,y,w,h)inrects:
cv2.rectangle(img,(x,y),(x+w,y+h),(0,0,255),2)
cv2.imshow('a',img)
ifcv2.waitKey(1)&0xff==27:#esc键
break
cv2.destroyAllWindows()
到此这篇关于python+opencv3.4.0实现HOG+SVM行人检测的示例代码的文章就介绍到这了,更多相关opencvHOG+SVM行人检测内容请搜索毛票票以前的文章或继续浏览下面的相关文章希望大家以后多多支持毛票票!