import cv2
import os
import numpy as np
import hog_discriptor
def get_path():
print('loading data...')
# 正样本文件夹路径
PosImgPath = "D:\A\python\opencv\tests\hog_pedestran_detect_python\Positive"
# 负样本
NegImgPath = "D:\A\python\opencv\tests\hog_pedestran_detect_python\Negative"
# 文件夹所有图片文件名
PosImgList = os.listdir(PosImgPath)
NegImgList = os.listdir(NegImgPath)
print('Number of positive samples:', len(PosImgList))
print('Number of negative samples:', len(NegImgList))
# 合并数据路径 添加对应标签
samplePath = []
labels = []
for f in PosImgList:
samplePath.append('Positive\' + f)
labels.append(1)
for f in NegImgList:
samplePath.append('Negative\' + f)
labels.append(-1)
labels = np.array(labels)
return samplePath, labels
def extract_hog(samplePath):
print('extracting hog...')
# hog参数
winSize = (64, 128) # 窗口大小
blockSize = (16, 16) # 块大小
blockStride = (8, 8) # 块滑动增量
cellSize = (8, 8) # 胞元大小
Bin = 9 # 梯度方向数
# 创建hog
hogDescriptor = cv2.HOGDescriptor(winSize, blockSize, blockStride, cellSize, Bin)
# 获取正负样本hog特征
hogFeature = []
for f in samplePath:
img = cv2.imread(f, cv2.IMREAD_GRAYSCALE)
img = cv2.resize(img, (64, 128))
discriptor = hogDescriptor.compute(img)
hogFeature.append(discriptor)
# 转为numpy数组
hogFeature = np.array(hogFeature)
return hogFeature
def train_svm(hogFeature, labels):
# 创建svm
svm = cv2.ml.SVM_create()
svm.setKernel(cv2.ml.SVM_LINEAR) # 使用线性核
svm.setP(0.01) # 练习集中的特征向量和拟合出来的超平面的间隔须要小于p
svm.setC(0.01) # 异常值处罚因子 一般取10的n次幂 default=1.0 越接近0惩罚越大
svm.setType(cv2.ml.SVM_EPS_SVR) # SVM类型 SVR支持向量回归机
# 训练
print('training...')
svm.train(hogFeature, cv2.ml.ROW_SAMPLE, labels)
print('done.')
return svm
def get_svm_detecter(svm):
# 获取支持向量
SupportVector = svm.getSupportVectors()
SupportVector = np.transpose(SupportVector)
# rho-决策函数常数项b的相反数
rho, alpha, _ = svm.getDecisionFunction(0)
# 返回分类器
return np.append(alpha * SupportVector, [[-rho]], 0)
def detect(MyDecter):
imageSrc = cv2.imread('TestData\000001.jpg', cv2.IMREAD_COLOR)
myHog = cv2.HOGDescriptor()
myHog.setSVMDetector(MyDecter)
# 设置步长和padding、每次的缩放比例
objects, _ = myHog.detectMultiScale(imageSrc, winStride=(8, 8), padding=(16, 16), scale=1.04)
for (x, y, w, h) in objects:
cv2.rectangle(imageSrc, (x, y), (x+w, y+h), (255, 0, 0), 2)
cv2.imshow('img', imageSrc)
cv2.waitKey(0)
if __name__ == '__main__':
samplePath, labels = get_path()
hogFeature = extract_hog(samplePath)
svm = train_svm(hogFeature, labels)
MyDecter = get_svm_detecter(svm)
detect(MyDecter)