SOL4Py Sample: EfficientDet

SOL4Py Samples

1 Install EfficientDetector

At first, you have to install Microsoft Visual Studio 2019 Community Edition.
How to setting up an environment for AutoML on Windows 10.

pip install tensorflow==2.4.0
pip install cython
git clone https://github.com/google/automl.git
cd automl
git clone https://github.com/cocodataset/cocoapi.git
cd cocoapi/PythonAPI

# Probably you have to modify extra_compiler_args in setup.py in the following way:
# setup.py
#extra_compile_args=['-Wno-cpp', '-Wno-unused-function', '-std=c99'],
extra_compile_args=['-std=c99'],

python setup.py build_ext install
pip install pyyaml
Please clone the latest EfficientDetector.git in a working directory(det).

mkdir c:\work
cd c:\work
git clone https://github.com/atlan-antillia/EfficientDetector.git

You may also like to download EfficientDetecotr.zip from this web-site.

2 Run EfficientDetector

Step1
You have to run the following script to download an efficinetdet-d0 model checkpoint file:

>cd c:\work\EfficientDetector
>python DownloadCkpt.py


Step2
If you have no savedmodel for the efficientdet-d0 model, please run the following command EfficientDetSavedModelCreator.py to create a savedmodel from the checkpoint file in the following way.

>python EfficientDetSavedModelCreator.py ./projects/coco/config/saved_model.config

;saved_model.config

[configuration]
runmode            = saved_model
name               = efficientdet-d0
model_name         = efficientdet-d0

log_dir            = ./projects/coco/
tensorrt           = None
threads            = 0
trace_filname      = None
use_xla            = False
freeze             = False
export_ckpt        = None
delete_logdir      = True
ckpt_dir           = ./efficientdet-d0
saved_model_dir    = ./projects/coco/saved_model
hparams            = ./projects/coco/configs/default.yaml
output_image_dir   = ./projects/coco/outputs

Step 3
Please run the following command to use EfficientDetObjectDetector.py in the following way.

>cd c:\work\EfficientDetector
>python EfficientDetObjectDetector.py ./projects/coco/configs/detect.config

detect.config in ./projects/coco/configs
;detect_config

[configuration]
runmode            = saved_model_infer

model_name         = efficientdet-d0
       
ckpt_dir           = ./efficientdet-d0
saved_model_dir    = ./projects/coco/saved_model
;output_dir         = ./projects/coco/outputs
hparams            = None

;filters           = [car]
;filters           = [car,person]
;filters           = [person]
;filters            = None

log_dir            = ./projects/coco/
label_map_pbtxt    = ./projects/coco/mscoco_label_map.pbtxt
tensorrt           = None
threads            = 0
trace_filname      = None
use_xla            = False
freeze             = False
export_ckpt        = None


delete_logdir      = True
batch_size         = 1
output_image_dir   = ./projects/coco/outputs

detect_results_dir = ./projects/coco/results

input_image        = ./images/*.*
input_video        = None
output_video       = None
trace_filename     = ./projects/coco/trace.log

line_thickness     = 2
max_boxes_to_draw  = 100
min_score_thresh   = 0.2
nms_method         = gaussian

Please edit this detect.config file for your own needs.
If you would like to apply a filter which enables to select objects only belonging to classes specified by a list of class names, please set filters parameter in the detect.config as shown below.
filters           = [car,person]

The above command will generate detected_image, detected_objects_csv, objects_stats.csv files from the file(s) in input_image , and writes them into output_dir.

3 Inference Examples

Example 1: input_image=./images/img.png

>python EfficientDetObjectDetector.py ./projects/coco/configs/detect.config

img.png


img.png.csv


img.png_stats.csv



Example 2:input_image=./images/ShinJuku.jpg

>python EfficientDetObjectDetector.py ./projects/coco/configs/detect.config





Example 3: input_image=./images/ShinJuku2.jpg, filters=[person]

>python EfficientDetObjectDetector.py ./projects/coco/configs/detect.config




You can run the following command to apply a batch of detection processes to all image files under the input_image_dir.

efficentdet>python EfficientDetector.py input_image_dir outout_image_dir otional_filters_like_[person, car,..something]


#******************************************************************************
#
#  Copyright (c) 2020-2021 Antillia.com TOSHIYUKI ARAI. ALL RIGHTS RESERVED.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#******************************************************************************

#  
# DownloadCkpt.py

import sys
import os
import traceback
import tarfile
import shutil
import tensorflow as tf

def download_checkpoint_file():
  try:
      #Download checkpoint file
      url = "https://storage.googleapis.com/cloud-tpu-checkpoints/efficientdet/coco/efficientdet-d0.tar.gz"
      folder = "efficientdet-d0"
      tar_file = "efficientdet-d0.tar.gz"

      if os.path.exists(folder) != True:
          print("Try download {}".format(url))

          tar_file = tf.keras.utils.get_file(tar_file, url)
          print("You have downloaded {}".format(tar_file))

          with tarfile.open(tar_file, "r:gz") as tar:
             tar.extractall()
      else:
          print("OK, you have the weight file {}!".format(tar_file))
       
  except Exception as ex:
    traceback.print_exc()


if __name__=="__main__":
         
  try:
      MODEL = "efficientdet-d0"
      ckpt_path = os.path.join(os.getcwd(), MODEL);
      download_checkpoint_file()

  except Exception as ex:
    traceback.print_exc()


#******************************************************************************
#
#  Copyright (c) 2020-2021 Antillia.com TOSHIYUKI ARAI. ALL RIGHTS RESERVED.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#******************************************************************************
#  
# DownloadImage.py

import sys
import os
import time
import traceback
import numpy as np

import shutil


def download_image_file(img_file):

  try:   
    path = os.path.join(os.getcwd(), "images")
    os.makedirs(path, exist_ok=True)
    local_image_path = os.path.join(path, img_file)
    if os.path.exists(local_image_path) != True:

         url = 'https://user-images.githubusercontent.com/11736571/77320690-099af300-6d37-11ea-9d86-24f14dc2d540.png'
         print("Downloading a file {}".format(url))

         img_file = tf.keras.utils.get_file(img_file, url)
         shutil.move(img_file, local_image_path)

         print("You have downloaded {}".format(local_image_path))
    else:
         print("Found a downloaded file {}".format(local_image_path))

    return local_image_path

  except Exception as ex:
    traceback.print_exc()

if __name__=="__main__":
         
  try:
      img_file="img.png"

      download_image_file(img_file)

  except Exception as ex:
    traceback.print_exc()



# ==============================================================================
# Copyright 2020 Google Research. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================

# Copyright 2020-2021 antillia.com Toshiyuki Arai

# 2021/09/22 atlan-antillia

# EfficientDetObjectDetector.py

r"""Tool to inspect a model."""
import os
#  arai
os.environ['TF_FORCE_GPU_ALLOW_GROWTH'] = 'true'
# 
import sys

import time
from typing import Text, Tuple, List

from absl import app
from absl import flags
from absl import logging

import numpy as np
from PIL import Image
import tensorflow.compat.v1 as tf

import hparams_config

import inference2 as inference
import utils
import traceback

from tensorflow.python.client import timeline  # pylint: disable=g-direct-tensorflow-import

from EfficientDetModelInspector import EfficientDetModelInspector
from DetectResultsWriter      import DetectResultsWriter

class EfficientDetObjectDetector(EfficientDetModelInspector):
  """A simple helper class for inspecting a model."""

  def __init__(self, config):
    super().__init__(config)
    print("=== EfficientDetObjectDetector")
    if self.runmode == "saved_model_infer":
      if os.path.exists(self.saved_model_dir) == False:
         message = "Specified runmode='saved_model_infer', but the saved_model '" + self.saved_model_dir + "' was not found -----"
         raise Exception (message)
    #print("--- output_image_dir {}".format(self.output_image_dir))
    if self.output_image_dir != None:
       if os.path.exists(self.output_image_dir) == False:
          os.makedirs(self.output_image_dir)
          print("--- Created output_image_dir {}".format(self.output_image_dir))


  # Override saved_model_inference in EfficientDetModelInspector
  def saved_model_inference(self, image_path_pattern, output_dir, **kwargs):
    """Perform inference for the given saved model."""
    print("=== EfficientDetObjectDetector.saved_model_inference -----------")
    driver = inference.ServingDriver(
        self.model_name,
        self.ckpt_path,
        batch_size   = self.batch_size,
        use_xla      = self.use_xla,
        model_params = self.model_config.as_dict(),
        **kwargs)
    driver.load(self.saved_model_dir)
    
    # Serving time batch size should be fixed.
    batch_size = self.batch_size or 1
    all_files = list(tf.io.gfile.glob(image_path_pattern))
    #print('all_files=', all_files)
    num_batches = (len(all_files) + batch_size - 1) // batch_size

    for i in range(num_batches):
      batch_files = all_files[i * batch_size:(i + 1) * batch_size]
      height, width = self.model_config.image_size
      images = [Image.open(f) for f in batch_files]
      filenames = [f for f in batch_files]
      #print("--- filenames {}".format(filenames))
      if len(set([m.size for m in images])) > 1:
        # Resize only if images in the same batch have different sizes.
        images = [m.resize(height, width) for m in images]
      raw_images = [np.array(m) for m in images]
      size_before_pad = len(raw_images)
      if size_before_pad < batch_size:
        padding_size = batch_size - size_before_pad
        raw_images += [np.zeros_like(raw_images[0])] * padding_size

      detections_bs = driver.serve_images(raw_images)
      for j in range(size_before_pad):

        (image, detected_objects, objects_stats)= driver.visualize(self.filters, 
                                                                    raw_images[j], 
                                                                    detections_bs[j], 
                                                                    **kwargs)

        img_id = str(i * batch_size + j)

        filename = all_files[int(img_id)]
        name = os.path.basename(filename)
        output_image_path = os.path.join(output_dir, self.str_filters + name )
        #output_image_path = os.path.join(output_dir, img_id + '.jpg')
        
        Image.fromarray(image).save(output_image_path)
        print('=== writing file to %s' % output_image_path)
        detect_results_writer = DetectResultsWriter(output_image_path)
        print("=== Writing detected_objects and objects_stats to csv files")
        detect_results_writer.write(detected_objects, objects_stats)


def main(_):
  detect_config      = ""
  if len(sys.argv)==2:
    detect_config    = sys.argv[1]
  else:
    raise Exception("Usage: python EfficientDetObjectDetector.py detect_config")
  if os.path.exists(detect_config) == False:
    raise Exception("Not found detect_config {}".format(detect_config))
      
  detector = EfficientDetObjectDetector(detect_config)
  detector.run_model()


##
#
if __name__ == '__main__':
  logging.set_verbosity(logging.WARNING)
  tf.enable_v2_tensorshape()
  tf.disable_eager_execution()
  app.run(main)



Last modified: 10 Oct. 2021