Blinking Lights detector using Python

This tutorial shows how to detect blinking LEDs. This could be used for blinking light tracking or for calibration.

import os
import numpy as np
from metavision_sdk_core import BaseFrameGenerationAlgorithm
from metavision_core.event_io import EventsIterator
import metavision_sdk_cv
import cv2

from ipywidgets import interact
from PIL import Image

def display_sequence(images):
    def _show(frame=(0, len(images)-1)):
        return Image.fromarray(images[frame])
    interact(_show)

Static camera and static blinking lights

In this sequence, we want to detect two static lights blinking at a certain frequency (here between 120 Hz and 250 Hz). We use metavision_sdk_cv.FrequencyAlgorithm and metavision_sdk_cv.FrequencyClusteringAlgorithm.

from metavision_core.utils import get_sample

sequence_filename = "blinking_leds_td.dat"

get_sample(sequence_filename, folder=".")
assert(os.path.isfile(sequence_filename))
mv_it = EventsIterator(sequence_filename)
height, width = mv_it.get_size()

frequency_filter = metavision_sdk_cv.FrequencyAlgorithm(width=width, height=height, min_freq=120., max_freq=250.)
frequency_clustering_filter = metavision_sdk_cv.FrequencyClusteringAlgorithm(width=width, height=height,
                                                                             min_cluster_size=5, max_time_diff=10000)

freq_buffer = frequency_filter.get_empty_output_buffer()
cluster_buffer = frequency_clustering_filter.get_empty_output_buffer()

im = np.zeros((height, width, 3), dtype=np.uint8)

for idx, ev in enumerate(mv_it):

    if idx >= 250:
        break

    BaseFrameGenerationAlgorithm.generate_frame(ev, im)

    frequency_filter.process_events(ev, freq_buffer)
    frequency_clustering_filter.process_events(freq_buffer, cluster_buffer)

    for cluster in cluster_buffer.numpy():
        x0 = int(cluster["x"]) - 10
        y0 = int(cluster["y"]) - 10
        cv2.rectangle(im, (x0, y0), (x0+20, y0+20), color=(0, 255, 0))
        cv2.putText(im, "id_{}: {} Hz".format(cluster["id"], int(cluster["frequency"])), (x0, y0-10), cv2.FONT_HERSHEY_PLAIN,
                    1, (0, 255, 0), 1)

    cv2.imshow("Events", im[...,::-1])
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
cv2.destroyAllWindows()
import matplotlib.pyplot as plt
%matplotlib inline
fig = plt.figure(figsize=(15,15))
plt.imshow(im, aspect="equal")
<matplotlib.image.AxesImage at 0x7f76b6e327f0>
../../_images/Blinking_lights_detector_6_1.png

Detecting the Propheshield

The Propheshield is a device used to calibrate an event-based camera. It consists of a 2x2 planar pattern of blinking LEDs. The following code also uses metavision_sdk_cv.FrequencyAlgorithm and metavision_sdk_cv.FrequencyClusteringAlgorithm so as to retrieve the positions of the blinking light. This approach could be used to retrieve the poses of a moving Propheshield and compute the camera’s intrisic parameters.

sequence_filename = "calib_propheshield_parking.10_sec.raw"

get_sample(sequence_filename, folder=".")
assert(os.path.isfile(sequence_filename))
mv_it = EventsIterator(sequence_filename)
height, width = mv_it.get_size()

frequency_filter = metavision_sdk_cv.FrequencyAlgorithm(width=width, height=height, min_freq=120., max_freq=250.)
frequency_clustering_filter = metavision_sdk_cv.FrequencyClusteringAlgorithm(width=width, height=height,
                                                                             min_cluster_size=10, max_time_diff=10000)

freq_buffer = frequency_filter.get_empty_output_buffer()
cluster_buffer = frequency_clustering_filter.get_empty_output_buffer()

list_images = []

im = np.zeros((height, width, 3), dtype=np.uint8)

for idx, ev in enumerate(mv_it):
    BaseFrameGenerationAlgorithm.generate_frame(ev, im)

    frequency_filter.process_events(ev, freq_buffer)
    frequency_clustering_filter.process_events(freq_buffer, cluster_buffer)

    for cluster in cluster_buffer.numpy():
        x0 = int(cluster["x"]) - 10
        y0 = int(cluster["y"]) - 10
        cv2.rectangle(im, (x0, y0), (x0+20, y0+20), color=(0, 255, 0))
        cv2.putText(im, "id_{}: {} Hz".format(cluster["id"], int(cluster["frequency"])), (x0, y0-10), cv2.FONT_HERSHEY_PLAIN,
                    1, (0, 255, 0), 1)

    cv2.imshow("Events", im[...,::-1])
    list_images.append(im.copy())
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cv2.destroyAllWindows()
display_sequence(list_images)
fig = plt.figure(figsize=(11,11))
plt.imshow(list_images[666])
interactive(children=(IntSlider(value=503, description='frame', max=1006), Output()), _dom_classes=('widget-in…
<matplotlib.image.AxesImage at 0x7f76cd4e8c50>
../../_images/Blinking_lights_detector_9_2.png

Note

This tutorial was created using Jupiter Notebooks

Download the source code.