import os
import glob
import numpy as np
import cv2
from skimage.feature import hog
import matplotlib.pyplot as plt
import numpy as np
import time
from sklearn.svm import LinearSVC
from sklearn.preprocessing import StandardScaler
from skimage.feature import hog
from sklearn.model_selection import train_test_split
from sklearn.neural_network import MLPClassifier
import pickle
car_list = [name for index,name in enumerate(os.listdir('../vehicles/vehicles')) if index != 0]
noncar_list = [name for index,name in enumerate(os.listdir('../non-vehicles/non-vehicles')) if index != 0]
cars=[]
for carfile in car_list:
carpath='../vehicles/vehicles/'
imgpath=os.path.join(carpath+carfile+'/*.png')
images = glob.glob(imgpath)
for image in images:
cars.append(image)
print('车辆图片总数为:{}'.format(len(cars)))
noncars=[]
for carfile in noncar_list:
carpath='../non-vehicles/non-vehicles/'
imgpath=os.path.join(carpath+carfile+'/*.png')
images=glob.glob(imgpath)
for image in images:
noncars.append(image)
print(len(noncars))
def show_images():
car_ind = np.random.randint(0, len(cars))
noncar_ind = np.random.randint(0, len(noncars))
car_image = cv2.imread(cars[car_ind])
noncar_image = cv2.imread(noncars[noncar_ind])
print('car_image min Values is:', car_image.min(), 'Car_image Max values is :', car_image.max())
print('notcar_image min Values is:', noncar_image.min(), 'notCar_image Max values is :', noncar_image.max())
plt.figure(figsize=(1, 1))
fig = plt.figure()
a = fig.add_subplot(121)
plt.imshow(car_image)
plt.title('Example Car Image')
a = fig.add_subplot(122)
plt.imshow(noncar_image)
plt.title('Example Not-car Image')
plt.show()
def color_hist(img, nbins=32, bins_range=(0, 256)):
fhist = np.histogram(img[:, :, 0], bins=nbins, range=bins_range)
shist = np.histogram(img[:, :, 1], bins=nbins, range=bins_range)
thist = np.histogram(img[:, :, 2], bins=nbins, range=bins_range)
hist_features = np.concatenate((fhist[0], shist[0], thist[0]))
return hist_features
def bin_spatial(img, size=(32, 32)):
features = cv2.resize(img, size).ravel()
return features
def get_hog_features(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=True,
visualize=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=True,
visualize=vis,
feature_vector=feature_vec)
return features
def extract_features(imgs, color_space='HSV', spatial_size=(16, 16), hist_bins=32,
orient=11, pix_per_cell=16, cell_per_block=2, hog_channel='ALL',
spatial_feat=True, hist_feat=True, hog_feat=True):
"""
输入:一个图片的列表,调用bin_spatial() 和 color_hist() get_hog_features()提取特征向量
:param imgs:
:param color_space:
:param spatial_size:
:param hist_bins:
:param orient:
:param pix_per_cell:
:param cell_per_block:
:param hog_channel:
:param spatial_feat:
:param hist_feat:
:param hog_feat:
:return:
"""
features = []
for file in imgs:
file_features = []
image = cv2.imread(file)
if color_space != 'BGR':
if color_space == 'HSV':
feature_image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
elif color_space == 'LUV':
feature_image = cv2.cvtColor(image, cv2.COLOR_BGR2LUV)
elif color_space == 'HLS':
feature_image = cv2.cvtColor(image, cv2.COLOR_BGR2HLS)
elif color_space == 'YUV':
feature_image = cv2.cvtColor(image, cv2.COLOR_BGR2YUV)
elif color_space == 'YCrCb':
feature_image = cv2.cvtColor(image, cv2.COLOR_BGR2YCrCb)
else:
feature_image = np.copy(image)
if spatial_feat == True:
spatial_features = bin_spatial(feature_image, size=spatial_size)
file_features.append(spatial_features)
if hist_feat == True:
hist_features = color_hist(feature_image, nbins=hist_bins)
file_features.append(hist_features)
if hog_feat == True:
if hog_channel == 'ALL':
hog_features = []
for channel in range(feature_image.shape[2]):
hog_feature = get_hog_features(feature_image[:, :, channel],
orient, pix_per_cell, cell_per_block,
vis=False, feature_vec=True)
hog_features.append(hog_feature)
hog_features = np.ravel(hog_features)
else:
hog_features = get_hog_features(feature_image[:, :, hog_channel], orient,
pix_per_cell, cell_per_block, vis=False, feature_vec=True)
file_features.append(hog_features)
features.append(np.concatenate(file_features))
return features
def show_hog():
pix_per_cell = [8, 16, 8, 16]
cell_per_block = [1, 1, 2, 2]
orient = [9, 9, 11, 11]
for i in range(len(pix_per_cell)):
car_ind = 1167
car_image = cv2.imread(cars[car_ind])
gray = cv2.cvtColor(car_image, cv2.COLOR_BGR2GRAY)
features, hog_image = get_hog_features(
gray, orient[i], pix_per_cell[i], cell_per_block[i], vis=True, feature_vec=True
)
plt.figure(figsize=(1, 1))
fig = plt.figure()
a = fig.add_subplot(121)
plt.imshow(car_image, cmap='gray')
plt.title('Example Car Image')
a = fig.add_subplot(122)
plt.imshow(hog_image, cmap='gray')
plt.title('HOG Visualization')
print(" No. of features for pix_per_cell- ", pix_per_cell[i], "cell_per_block -", cell_per_block[i],
'orient -', orient[i], "is", len(features))
plt.show()
def train_svm_model():
color_space = 'YUV'
orient = 11
pix_per_cell = 16
cell_per_block = 2
hog_channel = 'ALL'
car_features = extract_features(
cars, color_space=color_space, spatial_size=(16, 16), hist_bins=32, orient=11,
pix_per_cell=16, cell_per_block=2, hog_channel=hog_channel)
print('car_features length is:{},第一个feature shape is:{}'.format(len(car_features), car_features[0].shape))
notcar_features = extract_features(
noncars, color_space=color_space, spatial_size=(16, 16), hist_bins=32, orient=11,
pix_per_cell=16, cell_per_block=2, hog_channel=hog_channel)
print('not_car_features length is:{},第一个feature shape is:{}'.format(len(notcar_features), notcar_features[0].shape))
X = np.vstack((car_features, notcar_features)).astype(np.float64)
print('X shape is:{},X min is {},X max is {}'.format(X.shape, X.min(), X.max()))
y = np.hstack((np.ones(len(car_features)), np.zeros(len(notcar_features))))
rand_state = np.random.randint(0, 100)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.20, random_state=rand_state)
print('X_train min value is {},X_train max value is {}'.format(X_train.min(), X_train.max()))
print('X_test min value is {},X_test max value is {}'.format(X_test.min(), X_test.max()))
X_scaler = StandardScaler().fit(X_train)
X_train = X_scaler.transform(X_train)
X_test = X_scaler.transform(X_test)
print('---After StandardScaler--- X_train min value is {},X_train max value is {},Mean is {}'.
format(X_train.min(), X_train.max(), X_train.mean()))
print('---After StandardScaler--- X_test min value is {},X_test max value is {},Mean is {}'.
format(X_test.min(), X_test.max(), X_train.mean()))
print('Using:', orient, 'orientations', pix_per_cell,
'pixels per cell and', cell_per_block, 'cells per block')
print('Feature vector length:', len(X_train[0]))
svc = LinearSVC()
t = time.time()
svc.fit(X_train, y_train)
t2 = time.time()
print(round(t2 - t, 2), 'Seconds to train SVC...')
print('Test Accuracy of SVC = ', round(svc.score(X_test, y_test), 4))
dist_pickle = {}
dist_pickle["svc"] = svc
dist_pickle["X_scaler"] = X_scaler
pickle.dump(dist_pickle, open("../svc_pickle1.p", "wb"))
print('模型成功保存!!')
def convert_color(img, conv='BGR2YCrCb'):
if conv == 'BGR2YCrCb':
return cv2.cvtColor(img, cv2.COLOR_BGR2YCrCb)
elif conv == 'BGR2LUV':
return cv2.cvtColor(img, cv2.COLOR_BGR2LUV)
elif conv == 'BGR2HSV':
return cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
elif conv == 'BGR2HLS':
return cv2.cvtColor(img, cv2.COLOR_BGR2HLS)
elif conv == 'BGR2YUV':
return cv2.cvtColor(img, cv2.COLOR_BGR2YUV)
def find_cars(img, ystart, ystop, scale, svc, X_scaler, spatial_size, hist_bins, orient, pix_per_cell,
cell_per_block, conv='BGR2YUV'):
draw_img = np.copy(img)
heatmap = np.zeros_like(img[:, :, 0])
img_tosearch = img[ystart:ystop, :, :]
ctrans_tosearch = convert_color(img_tosearch, conv=conv)
if scale != 1:
imshape = ctrans_tosearch.shape
ctrans_tosearch = cv2.resize(
ctrans_tosearch, (np.int(imshape[1] / scale), np.int(imshape[0] / scale)))
ch1 = ctrans_tosearch[:, :, 0]
ch2 = ctrans_tosearch[:, :, 1]
ch3 = ctrans_tosearch[:, :, 2]
nxblocks = (ch1.shape[1] // pix_per_cell) - 1
nyblocks = (ch1.shape[0] // pix_per_cell) - 1
nfeat_per_block = orient * cell_per_block ** 2
window = 64
nblocks_per_window = (window // pix_per_cell) - 1
cells_per_step = 2
nxsteps = (nxblocks - nblocks_per_window) // cells_per_step
nysteps = (nyblocks - nblocks_per_window) // cells_per_step
hog1 = get_hog_features(ch1, orient, pix_per_cell, cell_per_block, feature_vec=False)
hog2 = get_hog_features(ch2, orient, pix_per_cell, cell_per_block, feature_vec=False)
hog3 = get_hog_features(ch3, orient, pix_per_cell, cell_per_block, feature_vec=False)
bbox_list = []
for xb in range(nxsteps):
for yb in range(nysteps):
ypos = yb * cells_per_step
xpos = xb * cells_per_step
hog_feat1 = hog1[ypos:ypos + nblocks_per_window, xpos:xpos + nblocks_per_window].ravel()
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))
xleft = xpos * pix_per_cell
ytop = ypos * pix_per_cell
subimg = cv2.resize(ctrans_tosearch[ytop:ytop + window, xleft:xleft + window], (64, 64))
spatial_features = bin_spatial(subimg, size=spatial_size)
hist_features = color_hist(subimg, nbins=hist_bins)
test_features = X_scaler.transform(
np.hstack((spatial_features, hist_features, hog_features)).reshape(1, -1))
test_prediction = svc.predict(test_features)
if test_prediction == 1:
xbox_left = np.int(xleft * scale)
ytop_draw = np.int(ytop * scale)
win_draw = np.int(window * scale)
bbox_list.append(((xbox_left, ytop_draw + ystart),
(xbox_left + win_draw, ytop_draw + win_draw + ystart)))
cv2.rectangle(draw_img, (xbox_left, ytop_draw + ystart),
(xbox_left + win_draw, ytop_draw + win_draw + ystart), (0, 0, 255), 6)
heatmap[ytop_draw + ystart:ytop_draw + win_draw + ystart, xbox_left:xbox_left + win_draw] += 1
return draw_img, heatmap, bbox_list
def test_images():
spatial_size = (16, 16)
hist_bins = 32
ystart = 400
ystop = 660
orient = 11
pix_per_cell = 16
cell_per_block = 2
scale = 1.5
images = glob.glob('../test_images/test*.jpg')
f = open("../svc_pickle.p", "rb")
dist_pickle = pickle.load(f)
svc = dist_pickle['svc']
X_scaler = dist_pickle["X_scaler"]
for fname in images:
img = cv2.imread(fname)
draw_img, heatmap, bbox_list = find_cars(
img, ystart, ystop, scale, svc, X_scaler, spatial_size, hist_bins, orient,
pix_per_cell, cell_per_block, conv='BGR2YUV')
fig = plt.figure(figsize=(10, 10))
plt.subplot(121)
plt.imshow(draw_img)
plt.title('Draw box image')
plt.subplot(122)
plt.imshow(heatmap, cmap='hot')
plt.title('Hotimage')
fig.tight_layout()
plt.show()
from scipy.ndimage.measurements import label
def add_heat(heatmap, bbox_list):
for box in bbox_list:
heatmap[box[0][1]:box[1][1], box[0][0]:box[1][0]] += 1
return heatmap
def apply_threshold(heatmap, threshold):
heatmap[heatmap <= threshold] = 0
return heatmap
def draw_labeled_bboxes(img, labels):
for car_number in range(1, labels[1] + 1):
nonzero = (labels[0] == car_number).nonzero()
nonzeroy = np.array(nonzero[0])
nonzerox = np.array(nonzero[1])
bbox = ((np.min(nonzerox), np.min(nonzeroy)), (np.max(nonzerox), np.max(nonzeroy)))
cv2.rectangle(img, bbox[0], bbox[1], (0, 0, 255), 6)
return img
def detect_false_and_applyto_origin(img, box_list, threshold=1, draw_pic=False):
heat = np.zeros_like(img[:, :, 0]).astype(np.float)
heat = add_heat(heat, box_list)
heat = apply_threshold(heat, threshold)
heatmap = np.clip(heat, 0, 255)
labels = label(heatmap)
draw_img = draw_labeled_bboxes(np.copy(img), labels)
if draw_pic == True:
plt.figure(figsize=(10, 10))
fig = plt.figure()
plt.imshow(draw_img)
plt.show()
return draw_img
def test1():
spatial_size = (16, 16)
hist_bins = 32
ystart = 400
ystop = 660
orient = 11
pix_per_cell = 16
cell_per_block = 2
scale = 1.5
images = glob.glob('../test_images/test*.jpg')
f = open("../svc_pickle.p", "rb")
dist_pickle = pickle.load(f)
svc = dist_pickle['svc']
X_scaler = dist_pickle["X_scaler"]
for fname in images:
img = cv2.imread(fname)
draw_img, heatmap, bbox_list = find_cars(
img, ystart, ystop, scale, svc, X_scaler, spatial_size, hist_bins, orient,
pix_per_cell, cell_per_block, conv='BGR2YUV')
result = detect_false_and_applyto_origin(img, bbox_list, threshold=0.8, draw_pic=True)
plt.show()
def process_image(img, n_frames=20, thresholding=18):
spatial_size = (16, 16)
hist_bins = 32
ystart = 400
ystop = 660
orient = 11
pix_per_cell = 16
cell_per_block = 2
scale = 1.5
f = open("../svc_pickle.p", "rb")
dist_pickle = pickle.load(f)
svc = dist_pickle['svc']
X_scaler = dist_pickle["X_scaler"]
bbox_list_temp = []
global hot_windows_list
global bbox_list
global bbox_list_final
draw_img, heatmap, bbox_list = find_cars(img, ystart, ystop, scale, svc, X_scaler, spatial_size, hist_bins, orient,
pix_per_cell, cell_per_block, conv='BGR2YUV')
hot_windows_list.append(bbox_list)
if len(hot_windows_list) <= n_frames:
bbox_list_final = sum(hot_windows_list, [])
else:
for val in hot_windows_list[(len(hot_windows_list) - n_frames - 1): (len(hot_windows_list) - 1)]:
bbox_list_temp.append(val)
bbox_list_final = sum(bbox_list_temp, [])
result = detect_false_and_applyto_origin(
img, bbox_list_final, threshold=thresholding, draw_pic=False)
return result
hot_windows_list = []
from moviepy.editor import VideoFileClip
import pickle
print('开始对视频进行预测!')
video = VideoFileClip("../project_video.mp4")
project_clip = video.fl_image(process_image)
output = "../vehicle_detection_bei1.mp4"
project_clip.write_videofile(output, audio=False)
print('对视频预测结束!')
"""
传统视觉问题:
1、slide windows 太慢了,而且窗口太难设置了;
2、Hog提取特征能力有限,不断尝试超参数;
3、预测也非常慢。
"""