Quick Start

a naive fake example including:
  • ImageProducer (generate image)
  • ObjectDetector (generate detection result: detected objects on the image)
  • DetectionResultHandler(write the detection result to db)

we will provide a fake image producer, object_detector in following code.

Pre-requirement

install eyewitness

pip install eyewitness

download the pikachu image as pikachu.png

wget -O pikachu.png https://upload.wikimedia.org/wikipedia/en/a/a6/Pok%C3%A9mon_Pikachu_art.png
_images/pikachu.png

Implement a pikachu ImageProducer

keep yielding a pikachu image

import time
import arrow
from eyewitness.image_id import ImageId
from eyewitness.image_utils import Image
from eyewitness.config import IN_MEMORY
from eyewitness.image_utils import ImageHandler, ImageProducer

class InMemoryImageProducer(ImageProducer):
   def __init__(self, image_path, channel='pikachu', interval_s=3):
      self.pikachu =  ImageHandler.read_image_file(image_path)
      self.interval_s = interval_s
      self.channel = channel

   def produce_method(self):

      return IN_MEMORY

   def produce_image(self):
      while True:
            image_id = ImageId(channel=self.channel, timestamp=arrow.now().timestamp, file_format='png')
            image_obj = Image(image_id, pil_image_obj=self.pikachu)
            yield image_obj
            time.sleep(self.interval_s)

Implement a fake ObjectDetector

always detect and draw bbox at same place

import os
from pathlib import Path

from eyewitness.object_detector import ObjectDetector
from eyewitness.detection_utils import DetectionResult
from eyewitness.config import (
   BBOX,
   BoundedBoxObject,
   DRAWN_IMAGE_PATH,
   IMAGE_ID,
   DETECTED_OBJECTS,
   DETECTION_METHOD
)

class FakePikachuDetector(ObjectDetector):
   def __init__(self, enable_draw_bbox=True):
      self.enable_draw_bbox = enable_draw_bbox

   def detect(self, image_obj):
      """
      fake detect method for FakeObjDetector

      Parameters
      ----------
      image_obj: eyewitness.image_utils.Image

      Returns
      -------
      DetectionResult

      """
      image_dict = {
            IMAGE_ID: image_obj.image_id,
            DETECTED_OBJECTS: [
               BoundedBoxObject(*(15, 15, 250, 225, 'pikachu', 0.5, ''))
            ],
            DETECTION_METHOD: BBOX
      }
      if self.enable_draw_bbox:
            image_dict[DRAWN_IMAGE_PATH] = str(
               Path(Path.cwd(), '%s_out.png' % image_obj.image_id))
            ImageHandler.draw_bbox(image_obj.pil_image_obj, image_dict[DETECTED_OBJECTS])
            ImageHandler.save(image_obj.pil_image_obj, image_dict[DRAWN_IMAGE_PATH])

      detection_result = DetectionResult(image_dict)
      return detection_result

We can now run a fake example

always detect and draw bbox at same place

from eyewitness.result_handler.db_writer import BboxPeeweeDbWriter
from peewee import SqliteDatabase
import arrow

# init InMemoryImageProducer
image_producer = InMemoryImageProducer('pikachu.png')

# init FakePikachuDetector
object_detector = FakePikachuDetector()

# prepare detection result handler
database = SqliteDatabase("example.sqlite")
bbox_sqlite_handler = BboxPeeweeDbWriter(database)

for image_obj in image_producer.produce_image():
   # generate the image_obj
   bbox_sqlite_handler.register_image(image_obj.image_id, {})  # register the image_info
   detection_result = object_detector.detect(image_obj)
   bbox_sqlite_handler.handle(detection_result)    # insert detection bbox result

which will keeping generate pikachu image, and write detection result into db

_images/drawn_pikachu.png

Real Detector Implement with Yolov3

start with the yolov3 Implement

the repo implements:

  • naive_detector.py: wrapper the detector
  • eyewitness_evaluation.py: run a evaluation example
  • end2end_detector.py: a end2end detector example with webcam
  • detector_with_flask.py: a end2end detector example with flask server

a naive detector example

class YoloV3DetectorWrapper(ObjectDetector):
   def __init__(self, model_config, threshold=0.5):
      self.core_model = YOLO(**vars(model_config))
      self.threshold = threshold

   def detect(self, image_obj) -> DetectionResult:
      (out_boxes, out_scores, out_classes) = self.core_model.predict(image_obj.pil_image_obj)
      detected_objects = []
      for bbox, score, label_class in zip(out_boxes, out_scores, out_classes):
            label = self.core_model.class_names[label_class]
            y1, x1, y2, x2 = bbox
            if score > self.threshold:
               detected_objects.append(BoundedBoxObject(x1, y1, x2, y2, label, score, ''))

      image_dict = {
            'image_id': image_obj.image_id,
            'detected_objects': detected_objects,
      }
      detection_result = DetectionResult(image_dict)
      return detection_result

also there is a docker example in the docker/yolov3_pytorch

Docker examples

more with real detector examples with docker here