7.7.5 Faster RCNN使用示例
7.7.5 faster rcnn使用示例
下面介绍如何使用tensorflow中提供的faster rcnn模型。首先需要加载使用到的库文件。
import numpy as np
import os
import sys
import tensorflow as tf
from distutils.version import strictversion
from collections import defaultdict
from io import stringio
from matplotlib import pyplot as plt
from pil import image
为了提高可移植性,需要在代码里手工指定tensorflow提供的目标检测模型的库文件到系统环境变量中。
# 把需要使用的代码库添加到系统路径中
sys.path.append("..")
sys.path.append("models/models/research/")
sys.path.append("models/models/research/slim/")
sys.path.append("models/models/research/object_detection/")
from object_detection.utils import ops as utils_ops
faster rcnn需要1.9及以上版本的tensorflow,在代码里进行简单的版本判断。
if strictversion(tf.__version__) < strictversion('1.9.0'):
raise importerror('please upgrade your tensorflow installation to v1.9.*
or later!')
定义模型文件的相关路径,包括物体标签和物体名称之间的映射关系表。
path_to_frozen_graph =
'models/faster_rcnn_resnet101_coco_2018_01_28/frozen_inference_graph.pb'
path_to_labels =
'models/models/research/object_detection/data/mscoco_label_map.pbtxt'
加载pb格式的模型文件,初始化tensorflow的计算图和会话。tensorflow把模型的定义以及模型的参数都保存在pb文件中,加载一次即可。
detection_graph = tf.graph()
with detection_graph.as_default():
od_graph_def = tf.graphdef()
with tf.gfile.gfile(path_to_frozen_graph, 'rb') as fid:
serialized_graph = fid.read()
od_graph_def.parsefromstring(serialized_graph)
tf.import_graph_def(od_graph_def, name='')
加载物体标签和物体名称之间的映射关系表。
category_index =
label_map_util.create_category_index_from_labelmap(path_to_labels,
use_display_name=true)
定义需要加载的测试图片的列表,加载的策略是把指定文件夹下的全部文件当作测试图片。
import glob
path_to_test_images_dir = '../picture/objectdetect/*'
test_image_paths = glob.glob(path_to_test_images_dir)
定义需要使用的tensor,tensorflow中可以通过tensor的名称从计算图中直接获得指定tensor的引用,其中最主要的几个tensor的作用如下。
? num_detections:检测到的物体的个数。
? detection_boxes:检测到的region proposals,或者称为bbox,形状为[n,4]。
? detection_scores:检测到的物体分类结果,形式为概率值,形状为[n]。
? detection_classes:检测到的物体分类结果,形式为标签id,形状为[n]。
? detection_masks:检测到物体的掩码。
? image_tensor:输入的图像。
ops = tf.get_default_graph().get_operations()
all_tensor_names = {output.name for op in ops for output in op.outputs}
tensor_dict = {}
for key in [
'num_detections', 'detection_boxes', 'detection_scores',
'detection_classes', 'detection_masks'
]:
tensor_name = key + ':0'
if tensor_name in all_tensor_names:
tensor_dict[key] = tf.get_default_graph().get_tensor_by_name(tensor_name)
image_tensor = tf.get_default_graph().get_tensor_by_name('image_tensor:0')
需要指出的是,tensorflow中的tensor在名称后都有编号,通常获取时加上“:0”即可。调试时可以通过打印全部tensor名称all_tensor_names帮助理解。
如图7-37所示,运行计算图,输入图像并通过指定的tensor获取对应的输出。
# 进行预测
output_dict = sess.run(tensor_dict,
feed_dict={image_tensor: np.expand_dims(image, 0)})
# 由于默认输出是浮点型,需要转换成整数型
output_dict['num_detections'] = int(output_dict['num_detections'][0])
output_dict['detection_classes'] = output_dict[
'detection_classes'][0].astype(np.uint8)
output_dict['detection_boxes'] = output_dict['detection_boxes'][0]
output_dict['detection_scores'] = output_dict['detection_scores'][0]
if 'detection_masks' in output_dict:
output_dict['detection_masks'] = output_dict['detection_masks'][0]
图7-37 faster rcnn的计算图
依次加载测试图片文件夹下的图片,根据预测结果进行可视化,设置最多显示5个物体且只显示概率大于80%的物体,如图7-38所示。
for image_path in test_image_paths:
image = image.open(image_path)
image_np = load_image_into_numpy_array(image)
output_dict = run_inference_for_single_image(image_np, detection_graph)
vis_util.visualize_boxes_and_labels_on_image_array(
image_np,
output_dict['detection_boxes'],
output_dict['detection_classes'],
output_dict['detection_scores'],
category_index,
instance_masks=output_dict.get('detection_masks'),
use_normalized_coordinates=true,
#设置最多显示5个物体
max_boxes_to_draw=5,
#只显示概率大于80%的物体
min_score_thresh=0.8,
line_thickness=2,
skip_scores=true,
skip_labels=false
图7-38 使用tensorflow的faster rcnn检测结果可视化
tensorflow提供了一个用于目标检测结果可视化的api,在原始图像上使用方框显示图像分类的结果以及物体的范围。
vis_util.visualize_boxes_and_labels_on_image_array
其中主要参数含义如下。
? image:原始图像。
? boxes:检测到的region proposals,或者称为bbox,形状为[n,4]。
? scores:检测到的物体分类结果,形式为概率值,形状为[n]。
? classes:检测到的物体分类结果,形式为标签id,形状为[n]。
? category_index:物体标签和物体名称之间的映射关系表。
? max_boxes_to_draw:绘制的region proposals最大个数,如果检测到的物体个数大于max_boxes_to_draw,按照scores排序选取前max_boxes_to_draw个绘制。
? min_score_thresh:阈值,scores大于该阈值的物体才显示。
? line_thickness:绘制的region proposals的线条的宽度。
? skip_scores:绘制region proposals时是否显示对应分数。
? skip_labels:绘制region proposals时是否显示物体名称。
通过tensorflow中提供的faster rcnn模型,我们可以在比较复杂的环境背景下检测多种物体,调试阶段我们可以把显示的阈值降低,增加可以显示的物体的上限,同时显示物体的概率值。
max_boxes_to_draw=100,
min_score_thresh=0.2,
line_thickness=2,
skip_scores=false,
skip_labels=false
如图7-39所示,典型的场景之一就是使用faster rcnn识别交通标志,不过faster rcnn的实时性较差,在对实时性要求高的领域,通常被作为其他手段的补充。
图7-39 使用faster rcnn识别交通标志
如图7-40所示,典型的场景之一就是使用faster rcnn识别路上行人。
图7-40 使用faster rcnn识别路上行人
下面介绍如何使用tensorflow中提供的faster rcnn模型。首先需要加载使用到的库文件。
import numpy as np
import os
import sys
import tensorflow as tf
from distutils.version import strictversion
from collections import defaultdict
from io import stringio
from matplotlib import pyplot as plt
from pil import image
为了提高可移植性,需要在代码里手工指定tensorflow提供的目标检测模型的库文件到系统环境变量中。
# 把需要使用的代码库添加到系统路径中
sys.path.append("..")
sys.path.append("models/models/research/")
sys.path.append("models/models/research/slim/")
sys.path.append("models/models/research/object_detection/")
from object_detection.utils import ops as utils_ops
faster rcnn需要1.9及以上版本的tensorflow,在代码里进行简单的版本判断。
if strictversion(tf.__version__) < strictversion('1.9.0'):
raise importerror('please upgrade your tensorflow installation to v1.9.*
or later!')
定义模型文件的相关路径,包括物体标签和物体名称之间的映射关系表。
path_to_frozen_graph =
'models/faster_rcnn_resnet101_coco_2018_01_28/frozen_inference_graph.pb'
path_to_labels =
'models/models/research/object_detection/data/mscoco_label_map.pbtxt'
加载pb格式的模型文件,初始化tensorflow的计算图和会话。tensorflow把模型的定义以及模型的参数都保存在pb文件中,加载一次即可。
detection_graph = tf.graph()
with detection_graph.as_default():
od_graph_def = tf.graphdef()
with tf.gfile.gfile(path_to_frozen_graph, 'rb') as fid:
serialized_graph = fid.read()
od_graph_def.parsefromstring(serialized_graph)
tf.import_graph_def(od_graph_def, name='')
加载物体标签和物体名称之间的映射关系表。
category_index =
label_map_util.create_category_index_from_labelmap(path_to_labels,
use_display_name=true)
定义需要加载的测试图片的列表,加载的策略是把指定文件夹下的全部文件当作测试图片。
import glob
path_to_test_images_dir = '../picture/objectdetect/*'
test_image_paths = glob.glob(path_to_test_images_dir)
定义需要使用的tensor,tensorflow中可以通过tensor的名称从计算图中直接获得指定tensor的引用,其中最主要的几个tensor的作用如下。
? num_detections:检测到的物体的个数。
? detection_boxes:检测到的region proposals,或者称为bbox,形状为[n,4]。
? detection_scores:检测到的物体分类结果,形式为概率值,形状为[n]。
? detection_classes:检测到的物体分类结果,形式为标签id,形状为[n]。
? detection_masks:检测到物体的掩码。
? image_tensor:输入的图像。
ops = tf.get_default_graph().get_operations()
all_tensor_names = {output.name for op in ops for output in op.outputs}
tensor_dict = {}
for key in [
'num_detections', 'detection_boxes', 'detection_scores',
'detection_classes', 'detection_masks'
]:
tensor_name = key + ':0'
if tensor_name in all_tensor_names:
tensor_dict[key] = tf.get_default_graph().get_tensor_by_name(tensor_name)
image_tensor = tf.get_default_graph().get_tensor_by_name('image_tensor:0')
需要指出的是,tensorflow中的tensor在名称后都有编号,通常获取时加上“:0”即可。调试时可以通过打印全部tensor名称all_tensor_names帮助理解。
如图7-37所示,运行计算图,输入图像并通过指定的tensor获取对应的输出。
# 进行预测
output_dict = sess.run(tensor_dict,
feed_dict={image_tensor: np.expand_dims(image, 0)})
# 由于默认输出是浮点型,需要转换成整数型
output_dict['num_detections'] = int(output_dict['num_detections'][0])
output_dict['detection_classes'] = output_dict[
'detection_classes'][0].astype(np.uint8)
output_dict['detection_boxes'] = output_dict['detection_boxes'][0]
output_dict['detection_scores'] = output_dict['detection_scores'][0]
if 'detection_masks' in output_dict:
output_dict['detection_masks'] = output_dict['detection_masks'][0]
图7-37 faster rcnn的计算图
依次加载测试图片文件夹下的图片,根据预测结果进行可视化,设置最多显示5个物体且只显示概率大于80%的物体,如图7-38所示。
for image_path in test_image_paths:
image = image.open(image_path)
image_np = load_image_into_numpy_array(image)
output_dict = run_inference_for_single_image(image_np, detection_graph)
vis_util.visualize_boxes_and_labels_on_image_array(
image_np,
output_dict['detection_boxes'],
output_dict['detection_classes'],
output_dict['detection_scores'],
category_index,
instance_masks=output_dict.get('detection_masks'),
use_normalized_coordinates=true,
#设置最多显示5个物体
max_boxes_to_draw=5,
#只显示概率大于80%的物体
min_score_thresh=0.8,
line_thickness=2,
skip_scores=true,
skip_labels=false
图7-38 使用tensorflow的faster rcnn检测结果可视化
tensorflow提供了一个用于目标检测结果可视化的api,在原始图像上使用方框显示图像分类的结果以及物体的范围。
vis_util.visualize_boxes_and_labels_on_image_array
其中主要参数含义如下。
? image:原始图像。
? boxes:检测到的region proposals,或者称为bbox,形状为[n,4]。
? scores:检测到的物体分类结果,形式为概率值,形状为[n]。
? classes:检测到的物体分类结果,形式为标签id,形状为[n]。
? category_index:物体标签和物体名称之间的映射关系表。
? max_boxes_to_draw:绘制的region proposals最大个数,如果检测到的物体个数大于max_boxes_to_draw,按照scores排序选取前max_boxes_to_draw个绘制。
? min_score_thresh:阈值,scores大于该阈值的物体才显示。
? line_thickness:绘制的region proposals的线条的宽度。
? skip_scores:绘制region proposals时是否显示对应分数。
? skip_labels:绘制region proposals时是否显示物体名称。
通过tensorflow中提供的faster rcnn模型,我们可以在比较复杂的环境背景下检测多种物体,调试阶段我们可以把显示的阈值降低,增加可以显示的物体的上限,同时显示物体的概率值。
max_boxes_to_draw=100,
min_score_thresh=0.2,
line_thickness=2,
skip_scores=false,
skip_labels=false
如图7-39所示,典型的场景之一就是使用faster rcnn识别交通标志,不过faster rcnn的实时性较差,在对实时性要求高的领域,通常被作为其他手段的补充。
图7-39 使用faster rcnn识别交通标志
如图7-40所示,典型的场景之一就是使用faster rcnn识别路上行人。
图7-40 使用faster rcnn识别路上行人