Windows 10 基于Tensorflow 利用Faster RCNN实现街头行人检测
课程报告下载
https://download.csdn.net/download/Darius_Tanz/18399562
GPU配置
CUDA各版本下载链接
cuDNN各版本下载链接
配置教程
辅助配置教程
Faster RCNN
程序
配置好Tensorflow GPU
安装slim Image Detect Library
方法一 用Git
git clone https://github.com/tensorflow/models
方法二 点击链接直接下载
https://github.com/tensorflow/models
安装python依赖库
pip3 install pillow lxml matplotlib contextlib2 jupyter cython
下载COCO API
git clone https://github.com/philferriere/cocoapi.git
进入刚刚下载的文件夹找到子文件夹PythonAPI,用cmd进入到该文件夹
cd x:/x/PythonAPI
python3 setup.py build_ext –inplace
下载protoc
https://github.com/protocolbuffers/protobuf/releases/download/v3.4.0/protoc-3.4.0-win32.zip
把cocoapi中的pycocotools文件夹拷贝到models/research目录下
使用protoc编译接口
在models\research目录下,cmd运行:
protoc.exe .\object_detection\protos\*.proto --python_out=.
测试
新建一个环境变量:PYTHONPATH,
它的值是models\research 和models\research\slim所在的目录
进入到.\models\research文件夹下,cmd运行
python ./object_detection\builders\model_builder_test.py
出现OK ,就好了
所有文件的文件结构,有些还未提到,请按照此种方式建立相应文件夹
------------------------------------------------------------------
——————————————————————
———————————————————————
——————————————————————
-------------------------------------------------------------
下载预训练模型:
在~/models/research 目录下新建pedestrain_detection目录
http://download.tensorflow.org/models/object_detection/faster_rcnn_inception_v2_coco_2018_01_28.tar.gz
数据集
http://www.robots.ox.ac.uk/ActiveVision/Research/Projects/2009bbenfold_headpose/project.html#datasets
对应下载存放至相应文件夹
安装opencv解析视频
pip install opencv-python
数据预处理
__author__ = 'you'
#将视频的每一帧提取出来,前4500做训练集
import cv2
def capture_from_video(video,train,test):
frame = 0
cap = cv2.VideoCapture(video)
length = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
factor = 2
while True:
check ,img = cap.read()
if check:
if frame < 4500:
path = train
else:
path = test
img = cv2.resize(img,(1920//factor,1080//factor))
cv2.imwrite(path+"//"+str(frame)+".jpg",img)
frame+=1
else:
break
cap.release()
if __name__ == '__main__':
#注意修改文件路径
capture_from_video("TownCentreXVID.avi",train='./images',test='./test_images')
从标注数据中提取所需数据
把4500张图片中的95%划分为训练集,5%的划分为验证集。
__author__ = 'you'
#将top文件中的核心数据提取出来
import json
import random
import copy
json_template={
'size':{'width':"960",'depth':"3","height":"540"},
'filename':'0.jpg',
"object":[]
}
object_template={
"bndbox":
{
"xmin":"",#左上角
"ymin":"",#左上角
"xmax":"",#右下角
"ymax":""
},
"name":"pedestrain",
"id" :"1"
}
#name : 表示需要检测的目标的名字
#id : 给这个目标编号一个id
#name 和 id 后面需要和 label_map.pbtxt保持一致
def read_top(file):
with open(file,'r') as fp:
infos=[]
info = copy.deepcopy(json_template)
lines = fp.readlines()
lastframe=0
for line in lines:
line = line.strip().split(",")
frameNumber = int(line[1])
xmin=abs(float(line[-4])-2)/2
ymin=abs(float(line[-3])-2)/2
xmax=abs(float(line[-2])-2)/2
ymax=abs(float(line[-1])-2)/2
if lastframe!=frameNumber:
#新的帧
if len(info['object']) > 0:
infos.append(copy.deepcopy(info))
print(info['filename'])
#保存每一帧的文件名
info = copy.deepcopy(json_template)
lastframe = frameNumber
info['filename']="%s.jpg"% frameNumber
object_ = copy.deepcopy(object_template)
object_['bndbox']['xmin']=copy.deepcopy(xmin)
object_['bndbox']['xmax']=copy.deepcopy(xmax)
object_['bndbox']['ymin']=copy.deepcopy(ymin)
object_['bndbox']['ymax']=copy.deepcopy(ymax)
info['object'].append(copy.deepcopy(object_))
#parse over.
#with open('json','w') as fp2:
# #保存为json为文件
# json.dump(infos,fp2)
return infos
if __name__ == '__main__':
infos=read_top(r"TownCentre-groundtruth.top")
train_fp=open('pedestrain_train.csv','w')
valid_fp=open('pedestrain_valid.csv','w')
train_fp.writelines("class,filename,height,width,xmax,xmin,ymax,ymin\n")
valid_fp.writelines("class,filename,height,width,xmax,xmin,ymax,ymin\n")
for info in infos:
filename = info['filename']
height = int(info['size']['height'])
width = int(info['size']['width'])
print(filename)
if random.random()<0.05:
#划分数据集
fp = valid_fp
else:
fp = train_fp
for object_ in info['object']:
xmin=object_['bndbox']['xmin']
xmax=object_['bndbox']['xmax']
ymin=object_['bndbox']['ymin']
ymax=object_['bndbox']['ymax']
name=object_['name']
fp.writelines("%s,%s,%d,%d,%s,%s,%s,%s\n"%(name,filename,height,width,xmax,xmin,ymax,ymin))
train_fp.close()
valid_fp.close()
将图片转换为TF_RECORD格式
# Create train data:
#在cmd进入相应文件夹输入
python generate_tfrecord.py --csv_input=./pedestrain_train.csv --output_path=train.record --image_dir=./images
# Create test data:
#在cmd进入相应文件夹输入
python generate_tfrecord.py --csv_input=./pedestrain_valid.csv --output_path=valid.record --image_dir=./images
"""
Usage:
# Create train data:
#在cmd进入相应文件夹输入
python generate_tfrecord.py --csv_input=./pedestrain_train.csv --output_path=train.record --image_dir=./images
# Create test data:
#在cmd进入相应文件夹输入
python generate_tfrecord.py --csv_input=./pedestrain_valid.csv --output_path=valid.record --image_dir=./images
"""
from __future__ import division
from __future__ import print_function
from __future__ import absolute_import
import os
import io
import pandas as pd
import tensorflow as tf
from PIL import Image
from object_detection.utils import dataset_util
from collections import namedtuple, OrderedDict
flags = tf.app.flags
flags.DEFINE_string('csv_input', '', 'Path to the CSV input')
flags.DEFINE_string('output_path', '', 'Path to output TFRecord')
flags.DEFINE_string('image_dir', '', 'Path to images')
FLAGS = flags.FLAGS
# TO-DO replace this with label map
def class_text_to_int(row_label):
if row_label == 'pedestrain':
return 1
else:
None
def split(df, group):
data = namedtuple('data', ['filename', 'object'])
gb = df.groupby(group)
return [data(filename, gb.get_group(x)) for filename, x in zip(gb.groups.keys(), gb.groups)]
def create_tf_example(group, path):
with tf.gfile.GFile(os.path.join(path, '{}'.format(group.filename)), 'rb') as fid:
encoded_jpg = fid.read()
encoded_jpg_io = io.BytesIO(encoded_jpg)
image = Image.open(encoded_jpg_io)
width, height = image.size
filename = group.filename.encode('utf8')
image_format = b'jpg'
xmins = []
xmaxs = []
ymins = []
ymaxs = []
classes_text = []
classes = []
for index, row in group.object.iterrows():
xmins.append(row['xmin'] / width)
xmaxs.append(min(row['xmax'] / width,1.10)) #提供的数据集有的边框会超出实际的图片大小
ymins.append(row['ymin'] / height)
ymaxs.append(min(row['ymax'] / height,1.10)) #
classes_text.append(row['class'].encode('utf8'))
classes.append(class_text_to_int(row['class']))
tf_example = tf.train.Example(features=tf.train.Features(feature={
'image/height': dataset_util.int64_feature(height),
'image/width': dataset_util.int64_feature(width),
'image/filename': dataset_util.bytes_feature(filename),
'image/source_id': dataset_util.bytes_feature(filename),
'image/encoded': dataset_util.bytes_feature(encoded_jpg),
'image/format': dataset_util.bytes_feature(image_format),
'image/object/bbox/xmin': dataset_util.float_list_feature(xmins),
'image/object/bbox/xmax': dataset_util.float_list_feature(xmaxs),
'image/object/bbox/ymin': dataset_util.float_list_feature(ymins),
'image/object/bbox/ymax': dataset_util.float_list_feature(ymaxs),
'image/object/class/text': dataset_util.bytes_list_feature(classes_text),
'image/object/class/label': dataset_util.int64_list_feature(classes),
}))
return tf_example
def main(_):
writer = tf.python_io.TFRecordWriter(FLAGS.output_path)
path = os.path.join(FLAGS.image_dir)
examples = pd.read_csv(FLAGS.csv_input)
grouped = split(examples, 'filename')
for group in grouped:
tf_example = create_tf_example(group, path)
writer.write(tf_example.SerializeToString())
writer.close()
output_path = os.path.join(os.getcwd(), FLAGS.output_path)
print('Successfully created the TFRecords: {}'.format(output_path))
if __name__ == '__main__':
tf.app.run()
label_map.pbtxt文件
item {
id :1
name : 'pedestrain'
}
pipeline.config文件
注意修改路径
model {
faster_rcnn {
num_classes: 1
image_resizer {
keep_aspect_ratio_resizer {
min_dimension: 600
max_dimension: 1024
}
}
feature_extractor {
type: "faster_rcnn_inception_v2"
first_stage_features_stride: 16
}
first_stage_anchor_generator {
grid_anchor_generator {
height_stride: 16
width_stride: 16
scales: 0.25
scales: 0.5
scales: 1.0
scales: 2.0
aspect_ratios: 0.5
aspect_ratios: 1.0
aspect_ratios: 2.0
}
}
first_stage_box_predictor_conv_hyperparams {
op: CONV
regularizer {
l2_regularizer {
weight: 0.0
}
}
initializer {
truncated_normal_initializer {
stddev: 0.00999999977648
}
}
}
first_stage_nms_score_threshold: 0.0
first_stage_nms_iou_threshold: 0.699999988079
first_stage_max_proposals: 100
first_stage_localization_loss_weight: 2.0
first_stage_objectness_loss_weight: 1.0
initial_crop_size: 14
maxpool_kernel_size: 2
maxpool_stride: 2
second_stage_box_predictor {
mask_rcnn_box_predictor {
fc_hyperparams {
op: FC
regularizer {
l2_regularizer {
weight: 0.0
}
}
initializer {
variance_scaling_initializer {
factor: 1.0
uniform: true
mode: FAN_AVG
}
}
}
use_dropout: false
dropout_keep_probability: 1.0
}
}
second_stage_post_processing {
batch_non_max_suppression {
score_threshold: 0.300000011921
iou_threshold: 0.600000023842
max_detections_per_class: 100
max_total_detections: 100
}
score_converter: SOFTMAX
}
second_stage_localization_loss_weight: 2.0
second_stage_classification_loss_weight: 1.0
}
}
train_config {
batch_size: 3
data_augmentation_options {
random_horizontal_flip {
}
}
optimizer {
momentum_optimizer {
learning_rate {
manual_step_learning_rate {
initial_learning_rate: 0.000199999994948
schedule {
step: 2000
learning_rate: 1.99999994948e-05
}
schedule {
step: 6000
learning_rate: 1.99999999495e-06
}
}
}
momentum_optimizer_value: 0.899999976158
}
use_moving_average: false
}
gradient_clipping_by_norm: 10.0
fine_tune_checkpoint: "E:\\TempWorkStation\\python\\pedestrain_detect\\pretrained\\model.ckpt"
from_detection_checkpoint: true
num_steps: 10000
}
train_input_reader {
label_map_path: "E:\\TempWorkStation\\python\\pedestrain_detect\\anotation\\label_map.pbtxt"
tf_record_input_reader {
input_path: "E:\\TempWorkStation\\python\\pedestrain_detect\\train.record"
}
}
eval_config {
num_examples: 250
max_evals: 10
use_moving_averages: false
}
eval_input_reader {
label_map_path: "E:\\TempWorkStation\\python\\pedestrain_detect\\anotation\\label_map.pbtxt"
shuffle: false
num_readers: 1
tf_record_input_reader {
input_path: "E:\\TempWorkStation\\python\\pedestrain_detect\\valid.record"
}
}
模型训练
#训练 num_train_steps根据自己需要调整
#进入E:\TempWorkStation\python\cat_dog_reg\models\research\object_detection
python model_main.py --pipeline_config_path=E:\TempWorkStation\python\pedestrain_detect\pretrained\pipeline.config --model_dir=E:\TempWorkStation\python\pedestrain_detect\train --num_train_steps=10 --sample_1_of_n_eval_eval_examples=1 --alsologtostderr
#导出计算图
#进入E:\TempWorkStation\python\cat_dog_reg\models\research\object_detection
python export_inference_graph.py --pipeline_config_path=E:\TempWorkStation\python\pedestrain_detect\pretrained\pipeline.config --input_type=image_tensor --trained_checkpoint_prefix=E:\TempWorkStation\python\pedestrain_detect\train\model.ckpt-10 --output_directory=E:\TempWorkStation\python\pedestrain_detect\train\save_model\
模型预测
inference_object_detect.py
# coding: utf-8
import numpy as np
import os
import sys
import tensorflow as tf
from collections import defaultdict
from io import StringIO
from matplotlib import pyplot as plt
from PIL import Image
from cv2 import cv2
#下面的视频换成数据集别的视频比较好
cap = cv2.VideoCapture("./TownCentreXVID.avi") #打开视频文件
import time
# ## Object detection imports
# Here are the imports from the object detection module.
from object_detection.utils import label_map_util
from object_detection.utils import visualization_utils as vis_util
# # Model preparation
# ## Variables
#
# Any model exported using the `export_inference_graph.py` tool can be loaded here simply by changing `PATH_TO_CKPT` to point to a new .pb file.
#
# By default we use an "SSD with Mobilenet" model here. See the [detection model zoo](https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/detection_model_zoo.md) for a list of other models that can be run out-of-the-box with varying speeds and accuracies.
# What model to download.
# MODEL_NAME = 'ssd_mobilenet_v1_coco_2017_11_17'
# MODEL_FILE = MODEL_NAME + '.tar.gz'
MODEL_NAME = './train/save_model'
PATH_TO_CKPT = MODEL_NAME + '/frozen_inference_graph.pb'
# List of the strings that is used to add correct label for each box.
PATH_TO_LABELS = "./anotation/label_map.pbtxt"
NUM_CLASSES = 1
detection_graph = tf.Graph()
with detection_graph.as_default():
od_graph_def = tf.GraphDef()
with tf.gfile.GFile(PATH_TO_CKPT, 'rb') as fid:
serialized_graph = fid.read()
od_graph_def.ParseFromString(serialized_graph)
tf.import_graph_def(od_graph_def, name='')
# ## Loading label map
# Label maps map indices to category names, so that when our convolution network predicts `5`, we know that this corresponds to `airplane`. Here we use internal utility functions, but anything that returns a dictionary mapping integers to appropriate string labels would be fine
label_map = label_map_util.load_labelmap(PATH_TO_LABELS)
categories = label_map_util.convert_label_map_to_categories(label_map, max_num_classes=NUM_CLASSES, use_display_name=True)
category_index = label_map_util.create_category_index(categories)
# ## Helper code
def load_image_into_numpy_array(image):
(im_width, im_height) = image.size
return np.array(image.getdata()).reshape(
(im_height, im_width, 3)).astype(np.uint8)
# # Detection
# For the sake of simplicity we will use only 2 images:
# image1.jpg
# image2.jpg
# If you want to test the code with your images, just add path to the images to the TEST_IMAGE_PATHS.
'''
PATH_TO_TEST_IMAGES_DIR = 'test_images'
# PATH_TO_TEST_IMAGES_DIR = 'demo_2017117'
images=os.listdir(PATH_TO_TEST_IMAGES_DIR)
#TEST_IMAGE_PATHS = [ os.path.join(PATH_TO_TEST_IMAGES_DIR, 'image{}.jpg'.format(i)) for i in range(1, 3) ]
TEST_IMAGE_PATHS=[]
for image_name in images:
if(str(image_name.split(".")[-1])=="jpg"):
TEST_IMAGE_PATHS.append(os.path.join(PATH_TO_TEST_IMAGES_DIR,image_name))
# TEST_IMAGE_PATHS = [ os.path.join(PATH_TO_TEST_IMAGES_DIR,images) for i in range(1, 3) ]
'''
# Size, in inches, of the output images.
IMAGE_SIZE = (960,540)
with detection_graph.as_default():
with tf.Session(graph=detection_graph) as sess:
while True:
ret, image_np = cap.read()
if not ret:
print("Over Now!!!!!!!!!")
break
# Expand dimensions since the model expects images to have shape: [1, None, None, 3]
image_np_expanded = np.expand_dims(image_np, axis=0)
# Definite input and output Tensors for detection_graph
image_tensor = detection_graph.get_tensor_by_name('image_tensor:0')
# Each box represents a part of the image where a particular object was detected.
detection_boxes = detection_graph.get_tensor_by_name('detection_boxes:0')
# Each score represent how level of confidence for each of the objects.
# Score is shown on the result image, together with the class label.
detection_scores = detection_graph.get_tensor_by_name('detection_scores:0')
detection_classes = detection_graph.get_tensor_by_name('detection_classes:0')
num_detections = detection_graph.get_tensor_by_name('num_detections:0')
start = time.time()
# Actual detection.
(boxes, scores, classes, num) = sess.run(
[detection_boxes, detection_scores, detection_classes, num_detections],
feed_dict={image_tensor: image_np_expanded})
end = time.time()
# Time elapsed
seconds = end - start
print( "Time taken : {0} seconds".format(seconds))
# Calculate frames per second
fps = 1 / seconds
print( "Estimated frames per second : {0}".format(fps))
# Visualization of the results of a detection.
vis_util.visualize_boxes_and_labels_on_image_array(
image_np,
np.squeeze(boxes),
np.squeeze(classes).astype(np.int32),
np.squeeze(scores),
category_index,
use_normalized_coordinates=True,
line_thickness=8)
cv2.imshow('object detection', cv2.resize(image_np, (800,600)))dsln
if cv2.waitKey(25) & 0xFF == ord('q'):
cv2.destroyAllWindows()
break
附上当时未完成的实验报告
本科课程设计
题 目:四大常用目标检测算法
学 院:计算机科学技术学院
专 业:计算机科学与技术
姓 名:
指导教师:
年 月 日
摘 要
目标检测作为计算机视觉中的四大最基本的、最具挑战性的视觉识别问题之一,在最近的几十年中受到了极大的关注。目标检测旨在在给定图像中找到具有精确定位的特定目标类的对象,并为每个对象实例分配一个对应的类标签。本文研究了过去二十年产生的四种经典目标检测算法(VJ DET,HOG-DET, YOLO, Faster RCNN),并对比了HOG-DET, YOLO, Faster RCNN三种算法在行人检测上的表现。研究发现。。。
关键词 目标检测 VJ DET HOG DET YOLO Faster-RCNN 行人检测
Abstract
Object detection, as one of the four most basic and challenging visual recognition problems in computer vision, has received great attention in recent decades.Visual object detection aims to find objects of certain target classes with precise localization in a given image and assign each object instance a corresponding class label. This paper studies four classic target detection algorithms (VJ DET, HOG DET, YOLO, Faster RCNN) produced in the past two decades, and compares their performance in human detection. We found…
Keywords object detection VJ DET HOG DET YOLO Faster-RCNN human detection
目 录
目 录 III
第1章 绪 论 1
1.1 研究背景和意义 1
1.2 国内外研究现状 1
1.3 主要研究内容 2
1.4 章节安排 2
第2章 目标检测和人体目标检测的基本概念 4
2.1 目标检测的概念 4
2.2 人体目标检测的概念 4
第3章 四大目标检测算法 5
3.1 VJ DET 5
3.1.1 计量值数据 5
3.1.2 计数值数据 5
3.2 HOG DET 5
3.3 YOLO 5
3.3.1 表示数据集中趋势的特征值 5
3.4 FASTER-RCNN 5
第4章 实验结果及分析 6
4.1 现场调查 6
第五章 总结 8
谢 辞 9
参考文献 10
第1章 绪 论
1.1 研究背景和意义
在计算机视觉领域,存在几个基本的视觉识别问题:图像分类[1],目标检测和实例分割[2、3]和语义分割[4](见图1)。特别地,图像分类(图1.1(a))旨在识别给定图像中对象的语义类别。目标检测不仅可以识别目标类别,还可以通过边界框预测每个目标的位置(图1(b))。语义分割(图1(c))旨在预测逐个像素的分类器,以便为每个像素分配特定的类别标签,从而提供对图像的更丰富的理解。但是,与对象检测相反,语义分段不能区分相同类别的多个对象。提出了一种在对象检测和语义分割的交集处相对较新的设置,称为“实例分割”(图1(d)),以识别不同的对象,并为每个对象分配一个单独的分类像素级蒙版。实际上,实例分割可以看作是对象检测的特殊设置,而不是通过边界框来定位对象,而是需要像素级的定位。
(a)图像分类 (b)目标检测
© 语义分割 (d) 实例分割
图像中的行人检测就是把出现在图像中的行人分割出来并精确定位。行人检测是近年来计算机视觉领域的研究热点,它在基于内容的图像检索、智能交通、智能视频监控、高级人机交互等领域具有广泛的应用前景。由于人体外观形状的不确定性,应用场景的复杂性,人体之间以及人体与其它物体之间的相互遮挡等原因导致行人检测成为一个极具挑战性的问题。
1.2 国内外研究现状
现在,对象检测已广泛应用于许多实际应用中,例如自动驾驶,机器人视觉,视频监控等。图1显示了在过去二十年中与“目标检测”相关的出版物数量不断增长。
最近二十年目标检测的历史脉络如下图
经过多年的发展,最新的对象检测系统已与大量技术集成在一起,例如“多尺度检测”,“硬负挖矿”,“边界框回归”等。在任何智能视频监控系统中,行人检测都是一项重要而重要的任务。与通用目标检测不同,行人检测有一些与通用目标检测不同的属性:i)行人对象是结构良好的对象,其纵横比几乎固定(约1.5),但它们也存在很大范围秤; ii)行人检测是现实世界中的应用,因此通常会出现诸如拥挤,遮挡和模糊等挑战。例如,在CityPersons数据集中,验证子集中共有3157个行人注释,其中48.8%与另一个交叉点大于(IoU)的带注释的步行者(IoU)重叠。此外,所有行人中有26.4%的人与另一个IoU高于0.3的带注释的行人有相当大的重叠。频繁的人群遮挡会损害行人检测器的性能。 iii)由于环境复杂,行人检测中存在更多的硬阴性样本(例如交通信号灯,邮箱等)。
在深度学习时代之前,行人检测算法[19,201,202,203,204]主要是从Viola Jones框架[20]扩展而来的,方法是利用带有滑动窗口策略的整体通道特征来定位对象,然后再进行区域分类器例如SVM。早期的工作主要集中在设计用于分类的鲁棒特征描述符上。例如,Dalal和Triggs [19]提出了定向梯度(HOG)描述符的直方图,而Paisitkriangkrai等人则提出了这种方法。 [204]设计了基于低级视觉提示和空间汇集特征的特征描述符。这些方法在行人检测基准上显示出令人鼓舞的结果,但主要基于手工制作的功能。
基于深度学习的行人检测方法[8,9,10,205,206,207,208,209,210,211]显示了出色的性能,并在公共基准测试中取得了最先进的结果。 Angelova等人[10]提出了一种使用级联的深层卷积网络的实时行人检测框架。在他们的工作中,一个简单的模型拒绝了许多简单的否定词,然后通过一个大型的深度网络对其余的困难提议进行了分类。张等。 [212]提出了基于决策树的框架。在他们的方法中,使用了多尺度特征图来提取行人特征,然后将其输入到增强型决策树中进行分类。与FC层相比,增强了决策树
1.3 主要研究内容
本文研究了过去二十年产生的四种经典目标检测算法(VJ DET,HOG-DET, YOLO, Faster RCNN),并对比了HOG-DET, YOLO, Faster RCNN三种算法在行人检测上的表现。研究发现。。。
1.4 章节安排
目标检测旨在在给定图像中找到具有精确定位的特定目标类的对象,并为每个对象实例分配一个对应的类标签。本文研究了过去二十年产生的四种经典目标检测算法(VJ DET,HOG-DET,YOLO,Faster RCNN),并对比了他们在人体检测上的表现。在第一章绪论,我们阐释了我们的研究背景和意义、国内外研究现状,和我们主要的研究内容。明确了研究内容之后我们在第二章定义了我们研究的问题。在接下来我们在第三章介绍了我们对比的四种目标检测算法。在第四章我们根据实验结果对四种算法做了分析。最后我们总结了四大算法的优缺点。
第2章 目标检测和人体目标检测的基本概念
2.1 目标检测的概念
目标检测,也叫目标提取,是一种基于目标几何和统计特征的图像分割,它将目标的分割和识别合二为一,其准确性和实时性是整个系统的一项重要能力。尤其是在复杂场景中,需要对多个目标进行实时处理时,目标自动提取和识别就显得特别重要。
随着计算机技术的发展和计算机视觉原理的广泛应用,利用计算机图像处理技术对目标进行实时跟踪研究越来越热门,对目标进行动态实时跟踪定位在智能化交通系统、智能监控系统、军事目标检测及医学导航手术中手术器械定位等方面具有广泛的应用价值。
2.2 人体目标检测的概念
图像中的人体目标检测就是把出现在图像中的人体分割出来并精确定位。因为人的外观形态变化很大,如,直立,弯腰,蹲下等姿态,造成图像中人体的姿态各异。导致难以对人体目标建模,目前大部分人体检测算法都是基于监督学习方法,也就是通过训练集训练分类器。但由于遮挡,视角变化,光照等因素,会对分类器分类结果产生影响。人体目标检测是近年来计算机视觉领域的研究热点,它在基于内容的图像检索、智能交通、智能视频监控、高级人机交互等领域具有广泛的应用前景。由于人体外观形状的不确定性,应用场景的复杂性,人体之间以及人体与其它物体之间的相互遮挡等原因导致人体目标检测成为一个极具挑战性的问题。
2.3 数据集介绍
本实验所采用的数据集来自于University of Oxford的Active Vision Laboratory,主要用于视觉监视的粗视线估计。该项目着重于在监控视频中获得被动粗视线估计的问题。粗视线估计是使用头部姿势而非眼睛位置获得的人们正在看的位置的估计。在监视视频中,头部的宽度往往小于20像素。为了使粗视线估计系统有用,必须在存在频繁的遮挡和其他干扰因素(例如动物或车辆)的情况下,实时同时跟踪许多人。数据集中存在部分干扰物体,更符合一般场景。
本实验主要应用了Town Centre Dataset,该数据集在CVPR 2011和BMVC 2009论文中均用于测试跟踪性能。我们主要应用了视频文件TownCentreXVID.avi(342MB)与手标地面实况数据文件TownCentre-groundtruth.top(5.3MB)。我们将TownCentreXVID.avi中截取的部分视频帧作为训练集样本,将TownCentre-groundtruth.top中对应的帧作为表针结果,通过计算一系列指标,评价不同算法的性能
、第3章 四大目标检测算法
3.1 VJ DET
Viola-Jones算法在2001年的CVPR上提出,因为其高效而快速的检测即使到现在也依然被广泛使用,OpenCV 和 Matlab中都将这个算法写进了函数库可以很方便的直接调用。VJ人脸检测算法最初是用来检测正面的人脸图像,对于侧脸图像的检测不是很稳健。
Viola-Jones算法基于人脸的haar特征值进行人脸检测方法,整体框架分三部分:
1、提取目标的特征,提取的是haar特征
2、分类器学习的过程,训练弱分类器成为最优弱分类器,多个最优弱分类器组合形成强分类器
3、强分类器进行级联,提高检测的速度和准确率
3.1.1 haar特征
人脸有一些特征,一张正脸图像中,人眼睛区域会比脸颊区域暗,嘴唇区域也会比四周的区域暗,但鼻子区域会比两边脸颊要亮。基于这些特征,VJ使用了四种矩形特征,如下图所示
(A,B为边界特征,C为细线特征,D为对角线特征)
haar特征仅与一个矩形区域内像素取值的和有关,其特征取值为白色区域对应图像的像素值之和减去黑色区域对应图像的像素值之和,这可以通过图像卷积实现。一副图像中这样的特征数量太多,其计算复杂性是个问题,为了提高计算效率,引入积分图技术。对于积分图像中的任何一点,该点的积分图像值等于位于该点左上角所有像素之和。有了积分图像,就可以很方便的计算图像中任何一个矩形区域的像素和,如下图所示
区域D所有的像素点灰度值之和为:
sum(A+B+C+D) - sum(A+C) - sum(A+B) + sum(A)
也就是I(4)−I(2)−I(3)+I(1)(其中,I(i)(i=1,2,3,4)表示图中对应点的积分图像的上的值)
3.1.2利用AdaBoost算法进行训练
AdaBoost 将一系列的弱分类器通过线性组合,构成一个强分类器。算法过程如下:
(1)初始化样本的权重,使权重之和为1
(2)训练弱分类器
(3)更新样本权重
(4)循环第二步
(5)结合各个分类器结果,进行投票。
3.1.3级联分类器
在正常的图像中,人脸区域只是占了很小的一部分,如果使用所有的特征进行训练的话,运算量非常大。在层级分类器架构中,每一层次含有一个”强”分类器,所有的矩形特征被分成几组,每一组都包含部分矩形特征,这些矩形特征用在层级分类器的每一阶段,层级分类器的每一阶段都会判别输入的区域是不是人脸,如果肯定不是,那么这个区域会被立即舍弃掉,只有那些被判别为可能是人脸的区域才会被传入下一阶段用更为复杂的分类器进一步的判别,过程如下:
3.2 HOG DET
1、HOG特征:
方向梯度直方图(Histogram of Oriented Gradient, HOG)特征是一种在计算机视觉和图像处理中用来进行物体检测的特征描述子。它通过计算和统计图像局部区域的梯度方向直方图来构成特征。Hog特征结合SVM分类器已经被广泛应用于图像识别中,尤其在行人检测中获得了极大的成功。需要提醒的是,HOG+SVM进行行人检测的方法是法国研究人员Dalal在2005的CVPR上提出的,而如今虽然有很多行人检测算法不断提出,但基本都是以HOG+SVM的思路为主。
(1)主要思想:
在一副图像中,局部目标的表象和形状(appearance and shape)能够被梯度或边缘的方向密度分布很好地描述。(本质:梯度的统计信息,而梯度主要存在于边缘的地方)。
(2)具体的实现方法是:
首先将图像分成小的连通区域,我们把它叫细胞单元。然后采集细胞单元中各像素点的梯度的或边缘的方向直方图。最后把这些直方图组合起来就可以构成特征描述器。
(3)提高性能:
把这些局部直方图在图像的更大的范围内(我们把它叫区间或block)进行对比度归一化(contrast-normalized),所采用的方法是:先计算各直方图在这个区间(block)中的密度,然后根据这个密度对区间中的各个细胞单元做归一化。通过这个归一化后,能对光照变化和阴影获得更好的效果。
(4)优点:
与其他的特征描述方法相比,HOG有很多优点。首先,由于HOG是在图像的局部方格单元上操作,所以它对图像几何的和光学的形变都能保持很好的不变性,这两种形变只会出现在更大的空间领域上。其次,在粗的空域抽样、精细的方向抽样以及较强的局部光学归一化等条件下,只要行人大体上能够保持直立的姿势,可以容许行人有一些细微的肢体动作,这些细微的动作可以被忽略而不影响检测效果。因此HOG特征是特别适合于做图像中的人体检测的。
2、HOG特征提取算法的实现过程:
大概过程:
HOG特征提取方法就是将一个image(你要检测的目标或者扫描窗口):
1)灰度化(将图像看做一个x,y,z(灰度)的三维图像);
2)采用Gamma校正法对输入图像进行颜色空间的标准化(归一化);目的是调节图像的对比度,降低图像局部的阴影和光照变化所造成的影响,同时可以抑制噪音的干扰;
3)计算图像每个像素的梯度(包括大小和方向);主要是为了捕获轮廓信息,同时进一步弱化光照的干扰。
4)将图像划分成小cells(例如66像素/cell);
5)统计每个cell的梯度直方图(不同梯度的个数),即可形成每个cell的descriptor;
6)将每几个cell组成一个block(例如33个cell/block),一个block内所有cell的特征descriptor串联起来便得到该block的HOG特征descriptor。
7)将图像image内的所有block的HOG特征descriptor串联起来就可以得到该image(你要检测的目标)的HOG特征descriptor了。这个就是最终的可供分类使用的特征向量了。
3.3 YOLO
1.原理:
1.YOLO首先将图像分为S×S的格子。如果一个目标的中心落入格子,该格子就负责检测该目标。每一个网格中预测B个Bounding box 和置信值(confidence score)。这些置信度分数反映了该模型对盒子是否包含目标的信心,以及它预测盒子的准确程度。然后,我们定义置信值为:
如果没有目标,置信值为零。另外,我们希望置信度分数等于预测框与真实值之间联合部分的交集(IOU)。
2每一个bounding box包含5个值:x,y,w,h和confidence。(x,y)坐标表示边界框相对于网格单元边界框的中心。宽度和高度是相对于整张图像预测的。confidence表示预测的box与实际边界框之间的IOU。每个网格单元还预测C个条件类别概率:
这些概率是以网格包含目标为条件的,每个网格单元我们只预测的一组类别概率,而不管边界框的的数量B时多少。
3.在测试时,我们乘以条件类概率和单个盒子的置信度预测:
图1 原理简单示例
2.模型
使用卷积神经网络来实现YOLO算法,网络的初始卷积层从图像中提取特征,而全连接层用来预测输出概率和坐标。卷积神经网络可选择GoogLeNet图像分类模型。
图2 基于GoogLeNet图像分类模型改进的CNN网络
3.4 Faster-RCNN
经过R-CNN和Fast RCNN的积淀,Ross B. Girshick在2016年提出了新的Faster RCNN,在结构上,Faster RCNN已经将特征抽取(feature extraction),proposal提取,bounding box regression(rect refine),classification都整合在了一个网络中,使得综合性能有较大提高,在检测速度方面尤为明显
依作者看来,如图1,Faster RCNN其实可以分为4个主要内容:
- Conv layers。作为一种CNN网络目标检测方法,Faster RCNN首先使用一组基础的conv+relu+pooling层提取image的feature maps。该feature maps被共享用于后续RPN层和全连接层。
- Region Proposal Networks。RPN网络用于生成region proposals。该层通过softmax判断anchors属于foreground或者background,再利用bounding box regression修正anchors获得精确的proposals。
- Roi Pooling。该层收集输入的feature maps和proposals,综合这些信息后提取proposal feature maps,送入后续全连接层判定目标类别。
- Classification。利用proposal feature maps计算proposal的类别,同时再次bounding box regression获得检测框最终的精确位置。
图2展示了python版本中的VGG16模型中的faster_rcnn_test.pt的网络结构,可以清晰的看到该网络对于一副任意大小PxQ的图像,首先缩放至固定大小MxN,然后将MxN图像送入网络;而Conv layers中包含了13个conv层+13个relu层+4个pooling层;RPN网络首先经过3x3卷积,再分别生成foreground anchors与bounding box regression偏移量,然后计算出proposals;而Roi Pooling层则利用proposals从feature maps中提取proposal feature送入后续全连接和softmax网络作classification。
通过上述介绍可以知道,Faster R-CNN与Fast R-CNN最大的区别就是提出了一个叫RPN(Region Proposal Networks)的网络,专门用来推荐候选区域的,RPN可以理解为一种全卷积网络,该网络可以进行end-to-end的训练,最终目的是为了推荐候选区。原文中默认选用三个缩放比例和三个旋转角度,这样就产生了9个可能的anchor, RPN在卷积特征图的基础上对每一个滑动窗口通过中间层网络提取256维的特征,然后通过回归层产生这9种anchor的坐标,通过二分类层输出这个anchor是不是目标。
RPN的输出层有(4+2)*9个输出
第4章 实验结果及分析
VJ 算法
MATLAB级联对象检测器(Vision.CascadeObjectDetector)使用Viola-Jones算法来检测人的面部,鼻子,眼睛,嘴巴或上半身.
- HOG DET
使用Python实现HogDet算法,可以看到下图中存在未能识别行人,这是因为HogDet算法受噪声影响较大;HogDet算法允许行人有极细微的动作变化,一旦行人有较大的动作时,HogDet算法效果变得很差;(具体看动图)
判断两个矩形是否为包含关系,包含返回True,不包含返回False
def is_inside(o, i):
ox, oy, ow, oh = o
ix, iy, iw, ih = i
return ox < ix and oy < iy and ox+ow > ix+iw and oy+oh > iy+ih
算法中的is inside()函数保证当两个框包含关系时,两个框合为一个;
yolo实验结果
我们使用了基于coco数据集训练的weights,通过opencv的api对weights加载,检测视频流中的frame。对于每一个frame初始化边界框,利用YOLO前馈网络计算,使用非极大值抑制方法抑制弱、重叠边界框,最终获取边界框和相应概率。
图3 Yolo分类结果
结果分析:
1.Yolo对于图片中所有出现的person都可以检测出来,无论person的形态及在图片中的位置,Yolo都可以检测到。
2.当person存在部分遮挡情况时,Yolo仍可以检测到,但时概率相当低10%。由此可知,Yolo可以根据部分特征推断出该物体的类别。
Faster RCNN实验结果
第五章 总结
写写几个算法的优缺点,及在行人检测的应用
谢 辞
具备上述基本特征的压滤机称之为第一代压滤机。它适用于高灰分、细粒度、高粘度的煤泥和尾煤的脱水,也适用于精煤与化工原料的脱水和过滤。产品的水分约为20%~22%,滤液浓度为0.030~1g/ L。不足之处主要表现在4个方面::处理能力小,间歇生产,压滤时间长;机体笨重,占用空间大;操作复杂,操作成本高;滤布耗量高,滤板寿命短,维修量大。
参考文献
[1] K. He, X. Zhang, S. Ren, J. Sun, Deep residual learning for image recog- nition, in: CVPR, 2016.
[2] R. Girshick, J. Donahue, T. Darrell, J. Malik, Rich feature hierarchies for accurate object detection and semantic segmentation, in: CVPR, 2014.
[3] K. He, G. Gkioxari, P. Doll´ar, R. Girshick, Mask r-cnn, in: ICCV, 2017.
[4] L.-C. Chen, G. Papandreou, I. Kokkinos, K. Murphy, A. L. Yuille, Se-