python+opencv实现hog+svm的训练

    python实现hog+svm训练的网上很多,但是资源svm训练这一块都是通过skimage这个库来实现的,本文从hog特征提取到svm的训练,以及后面的测试都是通过调用opencv来实现的,这样对于基于opencv来做开发的话较为方便,python+opencv通常是在建模的时候会用到,这主要是python脚本语言的高效性。话不多少,下面直接上代码:
"""
Created on Tue Apr  3 10:16:07 2018

@author: kuangyongjian

get_data.py
"""
import cv2 as cv
import random
import glob
import os

#加载负样本
def get_neg_samples(foldername,savePath):
    count = 0
    imgs = []
    labels = []
    f = open('neg.txt')
    filenames = glob.iglob(os.path.join(foldername,'*'))
    for filename in filenames:
        print('filename = ',filename)
        src = cv.imread(filename,1)
        
        if((src.cols >= 64) & (src.rows >= 128)):
            x = random.uniform(0,src.cols - 64)
            y = random.uniform(0,src.rows - 128)
            
            imgRoi = src(cv.Rect(x,y,64,128))
            imgs.append(imgRoi)
            saveName = savePath + 'neg' + str(count) + '.jpg'
            cv.imwrite(saveName,imgRoi)
            
            label = 'neg' + str(count) + '.jpg'
            labels.append(label)
            label = label + '\n'
            f.write(label)
            count += 1
    return imgs,labels


#读取负样本
def read_neg_samples(foldername):
    imgs = []
    labels = []
    neg_count = 0;
    filenames = glob.iglob(os.path.join(foldername,'*'))
    for filename in filenames:
       # print('filename = ',filename)
        src = cv.imread(filename,1)
       # cv.imshow("src",src)
       # cv.waitKey(5)
        imgs.append(src)
        labels.append(-1)
        neg_count += 1
   
    #print ('neg_count = ',neg_count)     
    return imgs,labels
        
        

#加载正样本
def get_pos_samples(foldername,savePath):
    count = 0
    imgs = []
    labels = []
    f = open('pos.txt')
    filenames = glob.iglob(os.path.join(foldername,'*'))
    for filename in filenames:
        print('filename = ',filename)
        src = cv.imread(filename)
        imgRoi = src(cv.Rect(16,16,64,128))
        imgs.append(imgRoi)
        saveName = savePath + 'neg' + str(count) + '.jpg'
        cv.imwrite(saveName,imgRoi)
        
        label = 'neg' + str(count) + '.jpg'
        labels.append(label)
        f.write(label)
        count += 1
        
    return imgs,labels


#读取正样本
def read_pos_samples(foldername):
    imgs = []
    labels = []
    pos_count = 0
    filenames = glob.iglob(os.path.join(foldername,'*'))
    
    for filename in filenames:
        src = cv.imread(filename)
        imgs.append(src)
        labels.append(1)
        pos_count += 1
     
    return imgs,labels
# -*- coding: utf-8 -*-
"""
Created on Tue Apr  3 11:47:53 2018

@author: kuangyongjian

svm_train.py
"""
import numpy as np
import cv2 as cv

#svm参数配置
def svm_config():
    svm = cv.ml.SVM_create()
    svm.setCoef0(0)
    svm.setCoef0(0.0)
    svm.setDegree(3)
    criteria = (cv.TERM_CRITERIA_MAX_ITER + cv.TERM_CRITERIA_EPS, 1000, 1e-3)
    svm.setTermCriteria(criteria)
    svm.setGamma(0)
    svm.setKernel(cv.ml.SVM_LINEAR)
    svm.setNu(0.5)
    svm.setP(0.1)
    svm.setC(0.01)
    svm.setType(cv.ml.SVM_EPS_SVR)

    return svm

#svm训练
def svm_train(svm,features,labels):
    svm.train(np.array(features),cv.ml.ROW_SAMPLE,np.array(labels))
    
#svm参数保存
def svm_save(svm,name):
    svm.save(name)
        
#svm加载参数 
def svm_load(name):
    svm = cv.ml.SVM_load(name)
    
    return svm
# -*- coding: utf-8 -*-
"""
Created on Tue Apr  3 14:06:43 2018

@author: kuangyongjian

hog_feature.py
"""
import numpy as np
import cv2 as cv

from get_data import get_pos_samples,get_neg_samples,read_pos_samples,read_neg_samples
from svm_train import svm_config,svm_train,svm_save,svm_load

#计算hog特征
def computeHog(imgs,features,wsize = (128,64)):
    hog = cv.HOGDescriptor()
    count = 0
    
    for i in range(len(imgs)):
        if imgs[i].shape[1] >= wsize[1] and imgs[i].shape[0] >= wsize[0]:
            y = imgs[i].shape[0] - wsize[0]
            x = imgs[i].shape[1] - wsize[1]
            h = imgs[i].shape[0]
            w = imgs[i].shape[1]
            roi = imgs[i][y : y + h, x : x + w]
            features.append(hog.compute(roi))
            count += 1
    
    print ('count = ',count)
    return features

#获取svm参数
def get_svm_detector(svm):
    sv = svm.getSupportVectors()
    rho, _, _ = svm.getDecisionFunction(0)
    sv = np.transpose(sv)
    return np.append(sv,[[-rho]],0)        

#加载hardexample
def get_hard_samples(svm,hog_features,labels):
    hog = cv.HOGDescriptor()
    hard_examples = []
    hog.setSVMDetector(get_svm_detector(svm))
    negs,hardlabel= read_neg_samples('F:/za/Model/pedestrain/INRIAPerson/Train/neg')
    
    for i in range(len(negs)):
        rects,wei = hog.detectMultiScale(negs[i],0,winStride = (8,8),padding = (0,0),scale = 1.05)
        for (x,y,w,h) in rects:
            hardexample = negs[i][y : y + h, x : x + w]
            hard_examples.append(cv.resize(hardexample,(64,128)))
            
    computeHog(hard_examples,hog_features)
    [labels.append(-1) for _ in range(len(hard_examples))]
    svm_train(svm,hog_features,labels)
    hog.setSVMDetector(get_svm_detector(svm))
    hog.save('myHogDector1.bin')
    #svm.train(np.array(hog_features),cv.ml.ROW_SAMPLE,np.array(labels))
 
#获取所有的hog特征
def get_features(features,labels):
    pos_imgs,pos_labels = read_pos_samples('F:/za/Model/pedestrain/INRIAPerson/pos_64x128')
    computeHog(pos_imgs,features)
    
    [labels.append(1) for _ in range(len(pos_imgs))]
    
    neg_imgs,neg_labels = read_neg_samples('F:/za/Model/pedestrain/INRIAPerson/neg_64x128')
    computeHog(neg_imgs,features)
    
    [labels.append(-1) for _ in range(len(neg_imgs))]

    #print('feature_shape = ',np.shape(features))

    return features,labels

#hog训练
def hog_train(svm):
    features = []
    labels = []
    
    hog = cv.HOGDescriptor()
    
    #get hog features
    get_features(features,labels)
    
    #svm training
    print ('svm training...')
    svm_train(svm,features,labels)
    print ('svm training complete...')
    
    hog.setSVMDetector(get_svm_detector(svm))
    hog.save('myHogDector.bin')
    
    print('hard samples training...')
    get_hard_samples(svm,features,labels)
    print('hard samples complete...')
    
    
if __name__ == '__main__':
    #svm config
    svm = svm_config()
    
    #hog training
    hog_train(svm)
    
# -*- coding: utf-8 -*-
"""
Created on Tue Apr  3 19:26:28 2018

@author: kuangyongjian

nms.py
"""
import numpy as np


def py_cpu_nms(dets,scores,thresh):    
    """Pure Python NMS baseline."""    
    x1 = dets[:, 0]    
    y1 = dets[:, 1]    
    x2 = dets[:, 2]    
    y2 = dets[:, 3]    
    #scores = dets[:, 4]  #bbox打分  
    
    areas = (x2 - x1 + 1) * (y2 - y1 + 1)    
#打分从大到小排列,取index    
    order = scores.argsort()[::-1]    
#keep为最后保留的边框    
    keep = []  
    boxs = []
    while order.size > 0:    
#order[0]是当前分数最大的窗口,肯定保留    
        i = order[0]    
        keep.append(i)    
#计算窗口i与其他所有窗口的交叠部分的面积  
        xx1 = np.maximum(x1[i], x1[order[1:]])    
        yy1 = np.maximum(y1[i], y1[order[1:]])    
        xx2 = np.minimum(x2[i], x2[order[1:]])    
        yy2 = np.minimum(y2[i], y2[order[1:]])    
    
        w = np.maximum(0.0, xx2 - xx1 + 1)    
        h = np.maximum(0.0, yy2 - yy1 + 1)    
        inter = w * h    
#交/并得到iou值    
        ovr = inter / (areas[i] + areas[order[1:]] - inter)    
#inds为所有与窗口i的iou值小于threshold值的窗口的index,其他窗口此次都被窗口i吸收    
        inds = np.where(ovr <= thresh)[0]    
#order里面只保留与窗口i交叠面积小于threshold的那些窗口,由于ovr长度比order长度少1(不包含i),所以inds+1对应到保留的窗口  
        order = order[inds + 1]    
    
    [boxs.append(dets[i]) for i in keep]
    
    return boxs
# -*- coding: utf-8 -*-
"""
Created on Tue Apr  3 14:47:20 2018

@author: kuangyongjian

test.py
"""
import numpy as np
import cv2 as cv
from nms import py_cpu_nms 
from imutils.object_detection import non_max_suppression


hog = cv.HOGDescriptor()
hog.load('myHogDector1.bin')


img = cv.imread('person_236.png')

cv.imshow('src',img)
cv.waitKey(10)

rects,scores = hog.detectMultiScale(img,winStride = (8,8),padding = (0,0),scale = 1.05)

sc = [score[0] for score in scores]
sc = np.array(sc)

#转换下输出格式(x,y,w,h) -> (x1,y1,x2,y2)
for i in range(len(rects)):
    r = rects[i]
    rects[i][2] = r[0] + r[2]
    rects[i][3] = r[1] + r[3]


pick = []
#非极大值移植  
print('rects_len',len(rects))
pick = non_max_suppression(rects, probs = sc, overlapThresh = 0.3)
print('pick_len = ',len(pick))

#画出矩形框
for (x,y,xx,yy) in pick:
    cv.rectangle(img, (x, y), (xx, yy), (0, 0, 255), 2)    

cv.imshow('a', img)  
cv.waitKey(10)

由于python语言平时用的不多,而且自己python应该也还算是刚刚入门吧,若有不当之处,请指教!

代码下载:点击打开链接

  • 41
    点赞
  • 323
    收藏
    觉得还不错? 一键收藏
  • 84
    评论
Python OpenCV HOG SVM 行人检测是使用Python编程语言和OpenCV库来实现行人检测的一种方法。该方法主要利用了HOG(Histogram of Oriented Gradients)特征和SVM(Support Vector Machine)分类器来检测行人。 以下是 Python OpenCV HOG SVM 行人检测的步骤: 1. 收集行人图像数据集并标注。 2. 提取图像中的HOG特征。 3. 利用提取的特征训练SVM分类器。 4. 在测试图像中使用训练好的SVM分类器来检测行人。 具体实现细节如下: 1. 数据集收集和标注 要进行行人检测,首先需要收集行人图像数据集并进行标注。可以使用现有的数据集,例如INRIA行人数据集,或者自己创建数据集。 对于数据集的标注,可以使用图像标注工具来手动标注,例如LabelImg或VGG Image Annotator(VIA)。对于每个行人图像,需要标注行人的位置和大小。 2. 提取HOG特征 OpenCV提供了HOGDescriptor函数来提取图像中的HOG特征。HOG特征是由图像中不同方向的梯度组成的向量,可以有效地表示图像的纹理和形状特征。 代码示例: ``` import cv2 # 创建HOG描述符对象 hog = cv2.HOGDescriptor() # 提取HOG特征 features = hog.compute(image) ``` 其中,image是输入图像,features是提取的HOG特征向量。 3. 训练SVM分类器 在提取HOG特征后,需要使用训练数据集来训练SVM分类器。可以使用OpenCV提供的SVM函数来实现训练。 代码示例: ``` import cv2 # 加载训练数据集和标签 train_data = cv2.imread('train_data.png') train_labels = cv2.imread('train_labels.png') # 创建SVM分类器对象 svm = cv2.ml.SVM_create() # 设置SVM参数 svm.setType(cv2.ml.SVM_C_SVC) svm.setKernel(cv2.ml.SVM_LINEAR) svm.setTermCriteria((cv2.TERM_CRITERIA_MAX_ITER, 100, 1e-6)) # 训练SVM分类器 svm.train(train_data, cv2.ml.ROW_SAMPLE, train_labels) ``` 其中,train_data是训练数据集,train_labels是对应的标签。SVM参数可以根据实际情况进行调整。 4. 行人检测 在训练SVM分类器后,可以在测试图像中使用它来检测行人。可以使用OpenCV提供的detectMultiScale函数来实现检测。 代码示例: ``` import cv2 # 加载测试图像 test_image = cv2.imread('test_image.png') # 创建HOG描述符对象 hog = cv2.HOGDescriptor() # 设置SVM分类器 hog.setSVMDetector(svm.getSupportVectors()) # 行人检测 rects, weights = hog.detectMultiScale(test_image, winStride=(8, 8)) # 绘制检测结果 for (x, y, w, h) in rects: cv2.rectangle(test_image, (x, y), (x + w, y + h), (0, 255, 0), 2) # 显示检测结果 cv2.imshow('result', test_image) cv2.waitKey(0) ``` 其中,test_image是要检测的测试图像。通过设置SVM分类器,可以使用HOG描述符对象的detectMultiScale函数来检测行人。检测结果是一组矩形框,可以使用OpenCV提供的rectangle函数来绘制。最后使用imshow函数显示检测结果。 总结: Python OpenCV HOG SVM 行人检测是一种简单有效的行人检测方法。通过收集数据集,提取HOG特征,训练SVM分类器,可以实现高效的行人检测。可以应用于视频监控、自动驾驶等领域。
评论 84
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值