Object detection¶
Object detection services enable the extraction of objects such as vehicles or people, patterns, sub-images, etc. within images using the Multimedia API.
By default, ecu.test supports simple algorithms for recognizing sub-images within an image (template matching and feature-based matching). It is possible to integrate additional algorithms for object detection using UserPyModules. For example, AI models such as YOLO, which can detect different object classes such as people, vehicles, animals, etc.
User-defined object detection¶
Object detection in ecu.test uses an object detector to identify individual objects within the image and output them as a MatchList. To do this, a Python module must be provided. In order for this to be recognized as a valid UserObjectDetector, several requirements must be met:
The module must be located in the
UserPyModulesfolder of the current workspace.The variable MODULE_TYPE = ‘ObjectDetector’ must be defined at the top level of the script.
An ObjectDetector class with any name must be implemented that fulfills the following interface:
__init__
GetId
GetDocumentation
DetectObjects
GetAvailableParameters
GetParameter
SetParamter
No two object detectors with the same ID may exist.
Further details on the interface can be found in the example in the following section.
Newly added or modified object detectors are recognized by ecu.test after the user libraries have been updated. This is done in the main menu “Extras”.
To use a user-defined object detector via the internal multimedia API, an instance can be created via
api.Multimedia.GetObjectDetector
The implemented methods of the interface can be called directly on the returned object, e.g.
api.Multimedia.GetObjectDetector('ExampleObjectDetector').GetParamter('objects').
Minimal example for object detection¶
An example implementation of a custom object detector can be found in the ecu.test installation directory:
Templates/DefaultData/UserPyModules/UserObjectDetector/ExampleObjectDetector.py
The minimal example in ExampleObjectDetector.py contains the following code. Further
information on the individual methods can be found in the doc strings.
from __future__ import annotations
from typing import TYPE_CHECKING, Any
import numpy as np
if TYPE_CHECKING:
import numpy.typing as npt
MODULE_TYPE = 'ObjectDetector'
class ExampleObjectDetector:
def __init__(self):
"""
The object detector can be created when *GetObjectDetector(detectorId)* is called on
the internal multimedia API, where *detectorId* is the identifier returned by *GetId()*.
"""
self._params: dict[str, Any] = {
param['name']: param['default'] for param in self.GetAvailableParameters()
}
def DetectObjects(self, img: npt.NDArray) -> list[dict[str, int | float]]:
"""
Calls the detection algorithm of you object detector. This example detector creates
(pseudo-random) object matches in the image dimensions and returns it.
:param img: Numpy image (width x height x channels)
:return: A list of dictionaries that describe the (pseudo-random) objects in the image with
position, dimensions and confidence.
"""
objects = []
# retrieve image dimensions
height, width = img.shape[:2]
# create pseudo random number generator with fixed seed
gen = np.random.default_rng(seed=42)
# create objects at random positions. The number of objects is defined in the 'objects'
# parameter
for _ in range(self._params.get('objects', 10)):
objWidth = gen.random() * 100
objHeight = gen.random() * 100
x = gen.random() * (width - objWidth)
y = gen.random() * (height - objHeight)
objects.append(
{
'x': x,
'y': y,
'width': objWidth,
'height': objHeight,
'confidence': gen.random(),
}
)
return objects
@staticmethod
def GetDocumentation() -> str:
"""
Returns a short documentation for your ObjectDetector class.
:return: A documentation string.
"""
return (
'This is an example object detector that detects a parameterized number of objects at '
'random positions.'
)
@staticmethod
def GetId() -> str:
"""
The identifier of the object detector which is used to create the detector via the
multimedia api.
:return: Identifier of the object detector.
"""
return 'ExampleObjectDetector'
def GetAvailableParameters(self) -> list[dict[str, Any]]:
"""
Returns a list of all configureable parameters. Each parameter must be described by a unique
name and a default value. A short description is optional.
:return: List of all available paramters
"""
return [
{
'name': 'objects',
'default': 10,
'description': 'Number of objects to detect',
}
]
def GetParameter(self, name: str) -> Any:
"""
Get the current value of a given parameter.
:param name: Name of the parameter. Available parameters can be queried via
GetAvailableParameters() method.
:return: Value of the given parameter.
"""
return self._params.get(name, None)
def SetParameter(self, name: str, value: Any) -> None:
"""
Set a new value to the given parameter.
:param name: Name of the parameter. Available parameters can be queried via
GetAvailableParameters() method.
:param value: The new value of the given parameter.
"""
self._params[name] = value