基于谷歌开源的Object-Detection API实现视频目标检测(tensorflow+opencv+anaconda3)

之前在做实时监控中人脸识别、人体姿态识别等项目,可以说一直在与视频打交道,今日心血来潮,顺便帮助师妹快速了解目标检测,特意选择了谷歌开源的Object-Detection API实现基于视频的目标检测。

测试环境:Win7、Anaconda3、tensorflow、opencv、CPU

一、Anaconda3下安装tensorflow和opencv

1、创建anaconda虚拟环境

[添加链接描述](https://blog.****.net/qq_37902216/article/details/84957240)
conda create -n tf_object python=3.6.7

其中tf_object为虚拟环境名称,可以根据自己喜好起名。

**虚拟环境 activate tf_object  若退出可执行deactivate

基于谷歌开源的Object-Detection API实现视频目标检测(tensorflow+opencv+anaconda3)

2、安装tensorflow

打开Anaconda中的Anaconda Navigator

基于谷歌开源的Object-Detection API实现视频目标检测(tensorflow+opencv+anaconda3)

基于谷歌开源的Object-Detection API实现视频目标检测(tensorflow+opencv+anaconda3)

点击环境,然后选择虚拟环境tf_object

基于谷歌开源的Object-Detection API实现视频目标检测(tensorflow+opencv+anaconda3)

然后选择All,再搜索tensorflow再点击Apply进行安装;opencv的安装按照同样的方式进行安装,具体操作可以搜索相关****博客。

进行验证,是否安装成功!!

打开cmd,再**tf_object环境,然后输入python,再输入

  1. import tensorflow
  2. import cv2

不报错则安装成功!!

基于谷歌开源的Object-Detection API实现视频目标检测(tensorflow+opencv+anaconda3)

二、protoc安装

什么是Protoc?Protoc是用来编译.Proto文件,Protocol Buffers (ProtocolBuffer/ protobuf )是Google公司开发的一种数据描述语言,类似于XML能够将结构化数据序列化,可用于数据存储、通信协议等方面。现阶段支持C++、JAVA、Python等三种编程语言。

Protoc用于编译相关程序运行文件,进入Protoc下载页,下载类似下图中带win32的压缩包。

基于谷歌开源的Object-Detection API实现视频目标检测(tensorflow+opencv+anaconda3)

然后解压这个文件,并记住bin文件夹路径,最好不要出现中文。

三、Git安装

git +网址是目前主流的在线下载指令,在官网找到Windows下载安装,按步骤操作就行,记得选择windows的命令框

四、安装其他包

  1. pip install pillow
  2. pip install lxml
  3. pip install jupyter
  4. pip install matplotlib
  5. pip install requests
  6. pip install moviepy

注意这些需要先**虚拟环境下再安装这些包

五、下载模型并编译

打开cmd输入

git clone http://github.com/tensorflow/models.git

下载后放在某个文件夹内,然后在cmd中进入models/research下,再进行编译

E:\protoc\bin\protoc object_detection\protos\*.proto --python_out=.

其中E:\protoc\bin\protoc表示你解压的protoc路径;object_detection\protos\*.proto --python_out=.是进行编译object_detection\protos\下的所有proto文件,运行成功,会编译生成py文件。

六、运行notebook demo

打开cmd 进入models/research再输入

jupyter-notebook

浏览器自动打开如下

基于谷歌开源的Object-Detection API实现视频目标检测(tensorflow+opencv+anaconda3)

然后新建python3程序,输入以下代码(对之前原始代码进行了些许改进):

  1. import os
  2. import cv2
  3. import time
  4. import argparse
  5. import multiprocessing
  6. import numpy as np
  7. import tensorflow as tf
  8. from matplotlib import pyplot as plt
  9. %matplotlib inline
  10. import six.moves.urllib as urllib
  11. import sys
  12. import tarfile
  13. import zipfile
  14. from collections import defaultdict
  15. from io import StringIO
  16. from PIL import Image
  17. from object_detection.utils import label_map_util
  18. from object_detection.utils import visualization_utils as vis_util
  19. CWD_PATH = os.getcwd()
  20. # Path to frozen detection graph. This is the actual model that is used for the object detection.
  21. MODEL_NAME = 'ssd_mobilenet_v1_coco_2017_11_17'
  22. PATH_TO_CKPT = os.path.join(CWD_PATH, 'object_detection', MODEL_NAME, 'frozen_inference_graph.pb')
  23. # List of the strings that is used to add correct label for each box.
  24. PATH_TO_LABELS = os.path.join(CWD_PATH, 'object_detection', 'data', 'mscoco_label_map.pbtxt')
  25. NUM_CLASSES = 90
  26. # Loading label map
  27. label_map = label_map_util.load_labelmap(PATH_TO_LABELS)
  28. categories = label_map_util.convert_label_map_to_categories(label_map, max_num_classes=NUM_CLASSES, use_display_name=True)
  29. category_index = label_map_util.create_category_index(categories)
  30. def detect_objects(image_np, sess, detection_graph):
  31. # Expand dimensions since the model expects images to have shape: [1, None, None, 3]
  32. image_np_expanded = np.expand_dims(image_np, axis=0)
  33. image_tensor = detection_graph.get_tensor_by_name('image_tensor:0')
  34. # Each box represents a part of the image where a particular object was detected.
  35. boxes = detection_graph.get_tensor_by_name('detection_boxes:0')
  36. # Each score represent how level of confidence for each of the objects.
  37. # Score is shown on the result image, together with the class label.
  38. scores = detection_graph.get_tensor_by_name('detection_scores:0')
  39. classes = detection_graph.get_tensor_by_name('detection_classes:0')
  40. num_detections = detection_graph.get_tensor_by_name('num_detections:0')
  41. # Actual detection.
  42. (boxes, scores, classes, num_detections) = sess.run(
  43. [boxes, scores, classes, num_detections],
  44. feed_dict={image_tensor: image_np_expanded})
  45. # Visualization of the results of a detection.
  46. vis_util.visualize_boxes_and_labels_on_image_array(
  47. image_np,
  48. np.squeeze(boxes),
  49. np.squeeze(classes).astype(np.int32),
  50. np.squeeze(scores),
  51. category_index,
  52. use_normalized_coordinates=True,
  53. line_thickness=8)
  54. return image_np
  55. # First test on images
  56. PATH_TO_TEST_IMAGES_DIR = 'object_detection/test_images'
  57. TEST_IMAGE_PATHS = [ os.path.join(PATH_TO_TEST_IMAGES_DIR, 'image{}.jpg'.format(i)) for i in range(1, 3) ]
  58. # Size, in inches, of the output images.
  59. IMAGE_SIZE = (12, 8)
  60. def load_image_into_numpy_array(image):
  61. (im_width, im_height) = image.size
  62. return np.array(image.getdata()).reshape(
  63. (im_height, im_width, 3)).astype(np.uint8)
  64. from PIL import Image
  65. for image_path in TEST_IMAGE_PATHS:
  66. image = Image.open(image_path)
  67. image_np = load_image_into_numpy_array(image)
  68. plt.imshow(image_np)
  69. print(image.size, image_np.shape)

运行之后出来结果

基于谷歌开源的Object-Detection API实现视频目标检测(tensorflow+opencv+anaconda3)

继续输入代码:

  1. #Load a frozen TF model
  2. detection_graph = tf.Graph()
  3. with detection_graph.as_default():
  4. od_graph_def = tf.GraphDef()
  5. with tf.gfile.GFile(PATH_TO_CKPT, 'rb') as fid:
  6. serialized_graph = fid.read()
  7. od_graph_def.ParseFromString(serialized_graph)
  8. tf.import_graph_def(od_graph_def, name='')
  9. with detection_graph.as_default():
  10. with tf.Session(graph=detection_graph) as sess:
  11. for image_path in TEST_IMAGE_PATHS:
  12. image = Image.open(image_path)
  13. image_np = load_image_into_numpy_array(image)
  14. image_process = detect_objects(image_np, sess, detection_graph)
  15. print(image_process.shape)
  16. plt.figure(figsize=IMAGE_SIZE)
  17. plt.imshow(image_process)

得到图片检测结果如下所示

基于谷歌开源的Object-Detection API实现视频目标检测(tensorflow+opencv+anaconda3)

下面部分是对视频进行检测,继续输入代码

  1. # Import everything needed to edit/save/watch video clips
  2. import imageio
  3. imageio.plugins.ffmpeg.download()
  4. from moviepy.editor import VideoFileClip
  5. from IPython.display import HTML
  6. def process_image(image):
  7. # NOTE: The output you return should be a color image (3 channel) for processing video below
  8. # you should return the final output (image with lines are drawn on lanes)
  9. with detection_graph.as_default():
  10. with tf.Session(graph=detection_graph) as sess:
  11. image_process = detect_objects(image, sess, detection_graph)
  12. return image_process
  13. white_output = 'video1_out.mp4'
  14. clip1 = VideoFileClip("video1.mp4").subclip(0,2)
  15. white_clip = clip1.fl_image(process_image) #NOTE: this function expects color images!!s
  16. %time white_clip.write_videofile(white_output, audio=False)

结果如下

基于谷歌开源的Object-Detection API实现视频目标检测(tensorflow+opencv+anaconda3)

输出视频video1_out.mp4保存到了代码所在文件目录中。

可以查看,输入下面代码

  1. HTML("""
  2. <video width="960" height="540" controls>
  3. <source src="{0}">
  4. </video>
  5. """.format(white_output))

基于谷歌开源的Object-Detection API实现视频目标检测(tensorflow+opencv+anaconda3)