import cv2
import numpy as np
from skimage.feature import hog
import glob
import matplotlib.pyplot as plt
#读取car data
def load_car_data():
vehicles = glob.glob('./vehicles/*/*.png')
return vehicles
#读取non car data
def load_non_car_data():
non_vehicles = glob.glob('./non-vehicles/*/*.png')
return non_vehicles
#提取HOG特征
def extract_feature(img,orient,pix_per_cell,cell_per_block,vis=False,feature_vec = True):
if vis == True:
features,hog_image = hog(img,orientations = orient,pixels_per_cell=(pix_per_cell,pix_per_cell),
cells_per_block = (cell_per_block,cell_per_block),transform_sqrt=False,visualise=vis,feature_vector=feature_vec)
return features,hog_image
else :
features = hog(img,orientations = orient,pixels_per_cell=(pix_per_cell,pix_per_cell),
cells_per_block = (cell_per_block,cell_per_block),transform_sqrt=False,visualise=vis,feature_vector=feature_vec)
return feature
#显示对比
def show_hog():
vehicles = load_car_data()
non_vehicles = load_non_car_data()
vehicle_img = plt.imread(vehicles[5])
non_vehicle_img = plt.imread(non_vehicles[5])
_,vehicle_hog_image = extract_feature(vehicle_img[:,:,2],9,8,8,vis=True,feature_vec=True)
_,non_vehicle_hog_image = extract_feature(non_vehicle_img[:,:,2],9,8,8,vis=True,feature_vec=True)
f,((ax1,ax2),(ax3,ax4)) = plt.subplots(2,2,figsize=(7,7))
ax1.imshow(vehicle_img)
ax1.set_title('car')
ax2.imshow(vehicle_hog_image)
ax2.set_title('car hog feature')
ax3.imshow(non_vehicle_img)
ax3.set_title('non car')
ax4.imshow(non_vehicle_hog_image)
ax4.set_title('non car hog feature')
plt.show()
# svm模型训练 我们刚刚获取了车辆和非车辆的hog特征,接下来用这些特征去训练svm模型。
def split_data():
car_data = load_car_data()
car_features = extract_features(car_data)
non_car_data = load_non_car_data()
non_car_features = extract_features(non_car_data)
x = np.vstack((car_features,non_car_features)).astype(np.float64)
y = np.hstack((np.ones(len(car_features)),np.zeros(len(non_car_features))))
rand_state = np.random.randint(0,100)
X_train,X_test,y_train,y_test = train_test_split(x,y,test_size = 0.2,random_state=rand_state)
return X_train,X_test,y_train,y_test
def train_model(X_train,y_train):
svc = LinearSVC()
svc.fit(X_train,y_train)
return svc
# 图像搜索 接下来进行车辆搜索,其原理是使用滑动窗口截取图像部分区域,然后用刚刚训练好的svm模型判断是否是车辆,如果是就保存该区域坐标。 ##定义滑动窗口 首先定义滑动窗口,其中有这样几个概念cell、block、window,step。cell是抽取hog特征时的最小单位,这里定义为16个像素。block由cell组成,这里定义为2*2个cell。window是滑动窗口大小,定义为64个像素。step是步长,即每次滑动的长度,定义为2个cell。
#x方向上block个数
nxblock = (ch1.shape[1]//pix_per_cell) + 1
#y方向上block个数
nyblock = (ch1.shape[0]//pix_per_cell) + 1
#定义window大小
window = 64
#每个window的cell个数,为了后续计算,剪掉1
nblocks_per_window = (window//pix_per_cell) - 1
#步长
cells_per_step = 2
#x方向上需要移动的次数
nxstep = (nxblock - nblocks_per_window)//cells_per_step
#y方向上需要移动的次数
nystep = (nyblock - nblocks_per_window)//cells_per_step
滑动窗口滑动过程如下
#获取特征
hog1 = get_hog_feature(ch1,orient,pix_per_cell,cell_per_block, feature_vec = False)
if hog_channel == 'ALL':
hog2 = get_hog_feature(ch2,orient,pix_per_cell,cell_per_block, feature_vec = False)
hog3 = get_hog_feature(ch3,orient,pix_per_cell,cell_per_block, feature_vec = False)
#滑动抽取每个窗口特征
for xb in range(nxstep):
for yb in range(nystep):
ypos = yb * cells_per_step
xpos = xb * cells_per_step
hog_feat1 = hog1[ypos:ypos+nblocks_per_window,xpos:xpos+nblocks_per_window].ravel()
if hog_channel == 'ALL':
hog_feat2 = hog2[ypos:ypos+nblocks_per_window,xpos:xpos+nblocks_per_window].ravel()
hog_feat3 = hog3[ypos:ypos+nblocks_per_window,xpos:xpos+nblocks_per_window].ravel()
hog_features = np.hstack((hog_feat1, hog_feat2, hog_feat3))
else : hog_features = hog_feat1
xleft = xpos * pix_per_cell
ytop = ypos * pix_per_cell
hog_features = hog_features.reshape(1,-1)
test_prediction = svc.predict(hog_features)
#若是车辆
if test_prediction == 1 or show_all_rectangle:
xbox_left = np.int(xleft * scale)
ytop = np.int(ytop * scale)
win = np.int(window * scale)
#保存窗口坐标
rectangles.append(((xbox_left,ytop + ystart),(xbox_left + window,ytop+win+ystart)))
检测效果
效果见p5-vehicle-detection
本节课程主要使用传统计算机视觉方法进行目标检测,其中使用到的技术与常见滑动窗口、图像金字塔和非最大抑制很相似。除了传统计算机视觉方法,还可以使用深度学习进行目标检测,后续再单独开文章进行介绍。这部分代码详见p5-vehicle-detection