Tensorflow Object Detection API (SSD, Faster-R-CNN)


2017.6.15에 Google에서 Tensorflow로 구현된Object Detection코드를 공개 했다. 말은 API라고 적혀 있지만 그냥 구현 코드이다. 지원하는 모델은 아래와 같다.

  • Single Shot Multibox Detector (SSD) with MobileNet
  • SSD with Inception V2
  • Region-Based Fully Convolutional Networks (R-FCN) with ResNet 101
  • Faster R-CNN with Resnet 101
  • Faster RCNN with Inception Resnet v2

설치 및 테스팅

일단 TF관련 예제를 구글이 만들어 놓은곳은 모두 modelsgithub에 있다.

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

클론한 다음 object detection으로 들어간 다음Jupyter Notebook으로object_detection_tutorial.ipynb을 실행 한다.

코드를 정상적으로 실행 하기 위해선 아래의 작업을 수행해 줘야 한다.

dependencies

  • Protobuf 2.6
  • Pillow 1.0
  • lxml
  • tf Slim (which is included in the "tensorflow/models" checkout)
  • Jupyter notebook
  • Matplotlib
  • Tensorflow

Ubuntu 16.04 기준

sudo apt-get install protobuf-compiler python-pil python-lxml
sudo pip install jupyter
sudo pip install matplotlib

sudo pip install pillow
sudo pip install lxml
sudo pip install jupyter
sudo pip install matplotlib

Protobuf 컴파일

clone한 models에서 실행 한다.

# From tensorflow/models/
protoc object_detection/protos/*.proto --python_out=.

실행하면 아래와 같이 python코드들이 생성된다.

jemin@jemin-desktop:~/tf_examples/models/object_detection/protos$ ls
BUILD                         losses_pb2.py
__init__.py                   matcher.proto
__pycache__                   matcher_pb2.py
anchor_generator.proto        mean_stddev_box_coder.proto
anchor_generator_pb2.py       mean_stddev_box_coder_pb2.py
argmax_matcher.proto          model.proto
argmax_matcher_pb2.py         model_pb2.py
bipartite_matcher.proto       optimizer.proto
bipartite_matcher_pb2.py      optimizer_pb2.py
box_coder.proto               pipeline.proto
box_coder_pb2.py              pipeline_pb2.py
box_predictor.proto           post_processing.proto
box_predictor_pb2.py          post_processing_pb2.py
eval.proto                    preprocessor.proto
eval_pb2.py                   preprocessor_pb2.py
faster_rcnn.proto             region_similarity_calculator.proto
faster_rcnn_box_coder.proto   region_similarity_calculator_pb2.py
faster_rcnn_box_coder_pb2.py  square_box_coder.proto
faster_rcnn_pb2.py            square_box_coder_pb2.py
grid_anchor_generator.proto   ssd.proto
grid_anchor_generator_pb2.py  ssd_anchor_generator.proto
hyperparams.proto             ssd_anchor_generator_pb2.py
hyperparams_pb2.py            ssd_pb2.py
image_resizer.proto           string_int_label_map.proto
image_resizer_pb2.py          string_int_label_map_pb2.py
input_reader.proto            train.proto
input_reader_pb2.py           train_pb2.py
losses.proto

Add Libraries to PYTHONPATH

slim 디렉터리를 append시키기 위함이다.

# From tensorflow/models/
export PYTHONPATH=$PYTHONPATH:`pwd`:`pwd`/slim

Testing the Installation
최종적으로 설치가 정상적으로 되었는지 아래의 명령어로 확인한다.

python object_detection/builders/model_builder_test.py

.......
----------------------------------------------------------------------
Ran 7 tests in 0.013s

OK

기타

  • Tensorflow 1.2.1 버전
  • Jupyter 5.4.0
  • Python 3.5.2

Troubleshooting

  • Load a Tensorflow model into memory 부분에서 에러가 발생하면 python3으로 커널을 변경하면 해결 된다.

실행 결과

COCO 이미지 두개를 불러와서 바운딩 박스를 치면 아래와 같다.

with detection_graph.as_default():
  with tf.Session(graph=detection_graph) as sess:
    for image_path in TEST_IMAGE_PATHS:
      image = Image.open(image_path)
      # the array based representation of the image will be used later in order to prepare the
      # result image with boxes and labels on it.
      image_np = load_image_into_numpy_array(image)
      # Expand dimensions since the model expects images to have shape: [1, None, None, 3]
      image_np_expanded = np.expand_dims(image_np, axis=0)
      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.
      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.
      scores = detection_graph.get_tensor_by_name('detection_scores:0')
      classes = detection_graph.get_tensor_by_name('detection_classes:0')
      num_detections = detection_graph.get_tensor_by_name('num_detections:0')
      # Actual detection.
      (boxes, scores, classes, num_detections) = sess.run(
          [boxes, scores, classes, num_detections],
          feed_dict={image_tensor: image_np_expanded})
      # 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)
      plt.figure(figsize=IMAGE_SIZE)
      plt.imshow(image_np)


+ Recent posts