简单的hog+svm行人检测

网上找的数据集,利用svm训练图片的HOG特征分类器,实现检测。

#python项目,使用opencv中的cv2.ml.svm
import cv2
import numpy as np
import os

def load_train(): #首先提取每个样本的hog特征,和标签
    train_data=[]
    label=[]
    test_data=[]
    file_positive='E:\\pedestrian_detect\\\Positive'
    file_negative='E:\\pedestrian_detect\\Negative'
    file_test='E:\\pedestrian_detect\\TestData'
    fp=os.listdir(file_positive)
    fn=os.listdir(file_negative)
    ft=os.listdir(file_test)
    
    for po in fp:
        path1=os.path.join(file_positive,po)
        print(path1)
        img=cv2.imread(path1)
        img=cv2.resize(img,(64,128))
        hog=cv2.HOGDescriptor((64,128),(16,16),(8,8),(8,8),9)
        descriptor1=hog.compute(img)
        #print(descriptor1.shape) #(3780, 1),需要对数据进行降维,否则后面的SVM的特征向量为3维的了
        descriptor1=np.concatenate((descriptor1),axis=0) #降维
        train_data.append(descriptor1)
        label.append(1)
        
    for ne in fn:
        path2=os.path.join(file_negative,ne)
        print(path2)
        img=cv2.imread(path2)
        img=cv2.resize(img,(64,128))
        descriptor2=hog.compute(img)
        descriptor2=np.concatenate((descriptor2),axis=0) #降维
        train_data.append(descriptor2)
        label.append(-1)
        
##    for te in ft:
##        path3=os.path.join(file_test,te)
##        img=cv2.imread(path3)
##        img=cv2.resize(img,(64,128))
##        descriptor3=hog.compute(img)
##        descriptor3=np.concatenate((descriptor3),axis=0) #降维
##        test_data.append(descriptor3)
    label=np.int32(label)   #类型转换
    train_data=np.float32(train_data)
##    test_data=np.float32(test_data)
##    return train_data,label,test_data
    return train_data,label
    ###使用sklearn.svm训练
##def train_svm_sklearn(sample,label,test):
##    model=svm.SVC()
##    #print(label.shape)
##    #print(sample.shape)
##    model.fit(X=sample,y=label)
##    #result=model.predict(test)
##    #print(result)
##    print(model)
##    vectors=model.support_vectors_ #返回支持向量
##    vectors=vectors[0,:]
##    print(vectors.shape)
##    return vectors

#使用opencv库中的SVM训练
def train_svm_opencv(sample,label):
    svm=cv2.ml.SVM_create()
    #下面的为SVM参数的设置,之前没有进行设置,得到的支持向量sv维度较高,导致合并部分维度不匹配,报错
    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) #使用线性分类器,因为后面的HogDescirptor检测函数只支持线性
    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)
    
    #对SVM进行训练
    svm.train(sample,cv2.ml.ROW_SAMPLE,label)
    pwd = os.getcwd()
    model_path = os.path.join(pwd, 'svm.xml')
    svm.save(model_path)
    #SVM训练完成后得到的XML文件里面,有一个数组,叫做support vector,还有一个数组,叫做alpha,有一个浮点数,叫做rho;
    #将alpha矩阵同support vector相乘,注意,alpha*supportVector,将得到一个行向量,将该向量前面乘以-1
    #即alpha*sv*another-rho ,对于HOG,式子中another=-1
#合并
    sv = svm.getSupportVectors()  #得到模型的支持向量
    print(sv.shape) #(1, 3780)
    rho, _, _ = svm.getDecisionFunction(0) #得到决策函数参数,为一个float型数据
    sv = np.transpose(sv)  #默认为转置,(3780,1)
    return np.append(sv, [[-rho]], 0) #axis=0
    #rho加负号:由于svm.predict中,公式为:alpha*sv*another-rho ,another=-1
def Rectangle(detector):
    file_test='E:\\pedestrian_detect\\TestData'
    ft=os.listdir(file_test)
    hog=cv2.HOGDescriptor()
    #hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())
    hog.setSVMDetector(detector) #设置线性分类器系数
    for i in ft:
        file_test_img=os.path.join(file_test,i)
        img=cv2.imread(file_test_img)
        rects,_=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('result',img)
        cv2.waitKey(0)
    cv2.destroyAllWindows()
train,label=load_train()
detector=train_svm_opencv(train,label)
Rectangle(detector)

样本不足,所以效果不是很好
结果如图:
简单的hog+svm行人检测_第1张图片

你可能感兴趣的:(学生)