01. Tensorflow2gpu docker image 기반의 TF2 Object Detection API를 활용한 객체 탐지 - pineland/object-tracking GitHub Wiki

1. 작업디렉토리 생성 및 Tensorflow Models repository의 master branch 복제

mkdir tf2gpu_od_docker && cd tf2gpu_od_docker
git clone https://github.com/tensorflow/models.git

2. Docker image 생성 및 진입

2.1 Dockerfile 가져오기

https://github.com/pineland/object-tracking 의 Dockerfile_tf2.2gpu_od을 현재의 디렉토리로 가져와서 Dockerfile 이름으로 저장한다.

2.2 Docker image 생성

docker build -t tf2gpu_od .

2.3 Docker Container 생성(진입)

# GUI 사용위한 X11 forwarding
xhost +local:docker
XSOCK=/tmp/.X11-unix

# 액세스 권한이 있는 xauth 파일을 생성하여 사용자 자격 증명
XAUTH=/tmp/.docker.xauth
xauth nlist $DISPLAY | sed -e 's/^..../ffff/' | xauth -f $XAUTH nmerge -      # 에러가 발생할 경우, 한번 더 실행

# 진입(1)
docker run --privileged -it --env DISPLAY=$DISPLAY --env="QT_X11_NO_MITSHM=1" -v /dev/video0:/dev/video0 -v $XSOCK:$XSOCK -v $XAUTH:$XAUTH -e XAUTHORITY=$XAUTH tf2gpu_od_docker /bin/bash

# 진입(2) : 현재의 디렉토리 밑에 있는 models를 컨테이너에 마운트
docker run --privileged -it --env DISPLAY=$DISPLAY --env="QT_X11_NO_MITSHM=1" -v $(pwd)/models/:/home/tensorflow/models/ -v /dev/video0:/dev/video0 -v $XSOCK:$XSOCK -v $XAUTH:$XAUTH -e XAUTHORITY=$XAUTH tf2gpu_od /bin/bash

2.4. Proto들 컴파일 (Dockerfile에 기반영하였는지 확인)

cd models/research

# Compile protos.
protoc object_detection/protos/*.proto --python_out=.

2.5. TensorFlow Object Detection API 설치 (Dockerfile에 기반영하였는지 확인)

# Install TensorFlow Object Detection API.
cp object_detection/packages/tf2/setup.py .
python -m pip install .

# 테스트
python object_detection/builders/model_builder_tf2_test.py
    :
 [ RUN      ] ModelBuilderTF2Test.test_unknown_ssd_feature_extractor
 [       OK ] ModelBuilderTF2Test.test_unknown_ssd_feature_extractor
 ----------------------------------------------------------------------
 Ran 20 tests in 91.767s
 OK (skipped=1)

2.6. 실행(테스트)

https://github.com/pineland/object-tracking 의 object_detection_tutorial.py를 다운받아서 models/research/object_detection에 저장한 다음, 실행한다.

python object_detection_tutorial.py

opencv 4.x의 특정 function들을 가져올 수 없다는 에러 메시지가 나타나면, 위 절차대로 컨테이너 생성부분과 컨테이너에 들어와서 해야될 부분을 다시 차근차근 실행해야 한다.

03. Run a pre trained model to detect images

/home/tensorflow/models/research/object_detection 에서 아래의 파일(object_detection_tutorials.py)을 작성하여 실행한다.

import matplotlib
import matplotlib.pyplot as plt

import os
import numpy as np
from six import BytesIO
from PIL import Image

import tensorflow as tf

def load_image_into_numpy_array(path):
  """Load an image from file into a numpy array.

  Puts image into numpy array to feed into tensorflow graph.
  Note that by convention we put it into a numpy array with shape
  (height, width, channels), where channels=3 for RGB.

  Args:
    path: a file path.

  Returns:
    uint8 numpy array with shape (img_height, img_width, 3)
  """
  img_data = tf.io.gfile.GFile(path, 'rb').read()
  image = Image.open(BytesIO(img_data))
  (im_width, im_height) = image.size
  return np.array(image.getdata()).reshape(
      (im_height, im_width, 3)).astype(np.uint8)

# Load images and visualize
train_image_dir = '/home/tensorflow/models/research/object_detection/test_images/f-16/train/'
train_images_np = []
for i in range(1, 6):
  image_path = os.path.join(train_image_dir, 'robertducky' + str(i) + '.jpg')
  train_images_np.append(load_image_into_numpy_array(image_path))

plt.rcParams['axes.grid'] = False
plt.rcParams['xtick.labelsize'] = False
plt.rcParams['ytick.labelsize'] = False
plt.rcParams['xtick.top'] = False
plt.rcParams['xtick.bottom'] = False
plt.rcParams['ytick.left'] = False
plt.rcParams['ytick.right'] = False
plt.rcParams['figure.figsize'] = [14, 7]

for idx, train_image_np in enumerate(train_images_np):
  plt.subplot(2, 3, idx+1)
  img = Image.fromarray(train_image_np, 'RGB')
  plt.imshow(img)
plt.show()

04. Use object detection on a video stream

/home/tensorflow/models/research/object_detection 에서 01.02의 object_detection_tutorials.py에 아래를 추가하여 실행한다.

def run_inference(model):
    cap = cv2.VideoCapture(0) # or cap = cv2.VideoCapture("<video-path>")
    while cap.isOpened():
        ret, image_np = cap.read()
        # Actual detection.
        output_dict = run_inference_for_single_image(model, image_np)
        # Visualization of the results of a detection.
        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_reframed', None),
            use_normalized_coordinates=True,
            line_thickness=8)
        cv2.imshow('object_detection', cv2.resize(image_np, (800, 600)))
        if cv2.waitKey(25) & 0xFF == ord('q'):
            cap.release()
            cv2.destroyAllWindows()
            break

run_inference(detection_model)
⚠️ **GitHub.com Fallback** ⚠️