SLMotion logo

Python API documentation

SLMotion can be controlled with general purpose Python scripts, using an API that it provides. This document provides a short reference of the different functions and classes that the API exposes. All of the content described here is contained within the slmotion module in the embedded Python interpreter, which can be accessed by the usual import means.

Index

Function and class reference

process(skip=0, framesMax=SIZE_MAX)

Overview

Runs the component chain on each video with the given settings. Usually, this is the last function to be called.

Arguments

Return values

None

setAnnotationTextFormat(format)

Overview

Sets the format of the text displayed on the annotation bar below the output video. The syntax resembles that of the printf function in C, i.e. special characters are marked with % followed by a single character. The list of these variables is shown below:

Arguments

Return values

None

class Component

Overview

This class is a Python abstraction of the C++ components. Basically, what it does is provide the necessary information for instantiating the actual component objects on the C++ side.

Component.Component(componentName, options)

Overview

This is the relevant constructor for the Component class. The values passed here will be used for instantiating the actual C++ components later on.

Arguments

Return values

None

setComponents(componentList)

Overview

Sets the components to be used in the given component chain.

Arguments

Return values

None

verbose(level=1)

Overview

Sets the verbosity level, i.e. the amount of debugging information printed to stdout.

Arguments

Return values

None

setVisualisation(script)

Overview

Sets a simple script to control the visualisation facilites of the SLMotion process. The script consists of simple semi-colon separated statements. Some of the recognised statements are shown below.

Arguments

Return values

None

class BlackBoard

Overview

This class is a Python abstraction of the C++ BlackBoard. The class represents a kind of data storage through which data passes between components. The data is stored on two tables: a frame-specific table and a global table. The only difference is that data on the frame-specific table is indexed with a frame number along with they property key. Property keys are component-specific strings that identify different data entries. This class has no public constructors, so the only instance is simply called "slmotion.blackboard" (note the case), so it may be regarded as a singleton on the Python side.

BlackBoard.has(propertyName, framenumber=default)

Overview

Queries the black board for the existence of entries.

Arguments

Return values

A boolean value.

BlackBoard.get(propertyName, framenumber=default)

Overview

Queries the black board for the existence of an entry, and returns it converted to a Python type. The details of the conversion depend entirely on the type in question.

Arguments

Return values

An object of an appropriate type.

BlackBoard.set(object, propertyName, framenumber=default, attribs=default)

Overview

Sets the given object as the entry for the propertyName/framenumber key on the black board.

Arguments

Return values

None.

BlackBoard.setAs(object, typespec, propertyName, framenumber=default, attribs=default)

Overview

Sets the given object as the entry for the propertyName/framenumber key on the black board. This function behaves almost exactly like set(), except that conversion to a specific type can be requested via the typespec parameter.

Arguments

Return values

None.

BlackBoard.delete(propertyName, framenumber=default)

Overview

Removes the given instance from the global board, or if framenumber is given, from the frame board.

Arguments

Return values

None.

BlackBoard.deleteAll(propertyName)

Overview

Removes all instances from the global board and the frame board that go by the given name.

Arguments

Return values

None.

BlackBoard.clear()

Overview

Removes everything from the black board.

Arguments

None.

Return values

None.

BlackBoard.COMPRESS_WITHOUT_REFERENCES

Overview

A constant that specifies the attribute value that makes matrices be compressed using the DEFLATE algorithm when they are not being referred to by a C++ pointer.

BlackBoard.NONE

Overview

A constant that specifies the attribute value that makes matrices never compressed.

class FrameSource

Overview

This class is a Python abstraction of the C++ FrameSource. The class provides access to the input fed to the components. Access is done on a per-frame basis via the bracket operator. Additionally, there may be several subtracks embedded into the one object, possibly representing depth information, another camera angle or some other type of information. This class has no public constructors, so the only public instance is simply called "slmotion.blackboard" (note the case). However, the class should not be regarded as a singleton on the Python side because additional instances may be available through the getTrack() function.

FrameSource.__getitem__(framenumber)

Overview

This is the bracket operator. It can be used to access the default track.

Arguments

Return values

A numpy.ndarray representing the desired frame.

FrameSource.__len__()

Overview

Queries the total number of frames.

Arguments

None.

Return values

The number of frames as an integer.

FrameSource.getNumberOfTracks()

Overview

Queries the number of tracks.

Arguments

None.

Return values

The number of tracks as an integer.

FrameSource.getTrack(trackNumber)

Overview

Queries a subtrack. An exception is raised if trackNumber is not within [0,getNumberOfTracks()-1].

Arguments

Return values

Another FrameSource instance representing the desired subtrack.

constructFeatureVector(specification, firstFrame=0, lastFrame=SIZE_MAX)

Overview

Constructs a feature vector from entries on the black board according to a specification.

Arguments

Return values

None

outputVideo(first=default, last=default)

Overview

Performs visualisation and writes the results to the video output file (or image sequence).

Arguments

Return values

None

storeFeatureData()

Overview

Writes the feature vector constructed above onto disk.

Arguments

None

Return values

None

storeElanAnnotations()

Overview

Writes the Elan annotations constructed from the feature vector according to the annotation templates to disk.

Arguments

None

Return values

None

class PythonComponentBase

Overview

This is a base class that can be used to aid the creation of new Python-based components. The class is not intended to be instantiated on its own; rather, it should work only as a base class to user-created actual component classes. For an example, please see PythonExampleComponent.py.

The class is abstract in the sense that attempting to use it as such will raise a NotImplementedError exception. The user should override the basic functions that report some information about the class (i.e. the component name and the requirements and such), and either process() or processRange(), or both. A default implementation is provided for processRange() that will call process() function for each frame in the range.

Note: The module also contains a class called PythonComponentBaseBase which is a base of this class. The user should not touch it. It is for internal use only, and is related to the C++/Python wrapping facilities. That class does not expose any members in its Python interface.

PythonComponentBase.processRange(firstFrame, lastFrame)

Overview

The default implementation calls the process() function for each frame i in firstFrame, firstFrame+1, ... , lastFrame-1, i.e. the first frame number is inclusive, the last frame number is exclusive. The frame numbers are 0-based, and, naturally, lastFrame > firstFrame ought to be true.

The function should call the callback() function from time to time to report the progress to the user interface and check if the user has requested process termination. The default implementation does so after each process() function call.

Arguments

Return values

A boolean value that indicates if the process was completed successfully.

PythonComponentBase.process(framenumber)

Overview

The default implementation simply raises a NotImplementedError exception. The overridden version of this function should contain the logic to perform any necessary processing on a single frame as requested in the framenumber parameter.

This function is of course not necessary if single frame processing is not meaningful to the component. In that case, the user is requested to override the processRange() function.

Arguments

Return values

None.

PythonComponentBase.callback(percentage)

Overview

Reports the percentage complete to the user interface, and returns information about whether the user wants to terminate the process prematurely. This function cannot be overridden.

Arguments

Return values

A boolean value. True will mean that everything should go on normally. False will mean that the process should be terminated as soon as possible.

PythonComponentBase.getShortDescription()

Overview

Returns a short description, typically about one sentence long, that briefly describes what the component does. This text may appear e.g. on user interfaces. The function should be overridden.

Arguments

None.

Return values

A string. The default implementation returns "A Python component".

PythonComponentBase.getLongDescription()

Overview

Returns a detailed description that describes what the component does. This text may appear e.g. on documentation. The function should be overridden.

Arguments

None.

Return values

A string. The default implementation returns "A Python configuration file help text".

PythonComponentBase.getRequirements()

Overview

Returns a set of strings that describe which properties should exist on the black board before the component is run. The user should override this function; the default implementation will only raise a NotImplementedError exception.

Arguments

None.

Return values

A set of strings.

PythonComponentBase.getProvided()

Overview

Returns a set of strings that describe which properties the component will store (add or modify) on the black board when it is run. The user should override this function; the default implementation will only raise a NotImplementedError exception.

Arguments

None.

Return values

A set of strings.

PythonComponentBase.getShortName()

Overview

Returns a short name for the component. It should not contain white space characters. This name is used when identifying the component internally, or by the user. Typically, it should correspond to the name of the class. The user should override this function; the default implementation will only raise a NotImplementedError exception.

Arguments

None.

Return values

A string.

PythonComponentBase.getComponentName()

Overview

Returns a user-readable name for the component. It may contain white space characters. This name is used e.g. when displaying information about the component in the user interface. The user should override this function; the default implementation will only raise a NotImplementedError exception.

Arguments

None.

Return values

A string.

Type conversion information

This section explains how certain type conversions are performed when moving data between Python and C++ environments.

Matrices

Matrices are typically presented as cv::Mat objects on the C++ side. On the Python side, numpy.ndarrays are used because this is the convention adopted by the newer OpenCV Python interface. Conversions - when performed through the BlackBorad - are very straightforward: the data is copied and mapped to a similar data type. There is typically a 1:1 correspondence between matrices and their data types.

However, the dimensionalities have different interpretations. Vectors are considered 2D matrices in OpenCV, whereas numpy assumes one dimension. Therefore, matrices with unit length in one dimension are mapped to one dimension. On the other hand, typically colour images are represented as 2D matrices with three channels in OpenCV. Numpy does not know the channel notion, so these images are mapped to 3D ndarrays.

Rectangles

Rectangles are typically presented as cv::Rect objects on the C++ side. However, the cv2 interface does not seem to provide an equivalent. Therefore, cv::Rect objects are converted to one-dimensional numpy.ndarrays with four elements: top-left x coordinate, top-left y coordinate, the width, and the height, respectively. Because conversion to the other side is ambiguous, and the interpretation that an numpy.ndarray represents a matrix is preferred, rectangles can be explicitly constructed by using the setAs() function with "Rect" as the type specifier.

Point vectors

Point vectors are typically presented as std::vector<cv::Point> or std::vector<cv::Point2f> objects on the C++ side, depending on the data type. However, the cv2 interface does not seem to provide an equivalent to the Point class. Instead, points are represented as 2-element row vectors, and point vectors as 3-dimensional matrices whose first dimension corresponds to the number of points, second dimension is one, and the third dimension is 2. Therefore, point vector objects are converted to three-dimensional numpy.ndarrays. Because conversion to the other side is ambiguous, and the interpretation that an numpy.ndarray represents a matrix is preferred, rectangles can be explicitly constructed by using the setAs() function with "vector<Point>" or "vector<Point2f>" as the type specifier.

Rectangle vectors

Rectangle vectors are typically presented as std::vector<cv::Rect> objects on the C++ side. However, the cv2 interface does not seem to provide an equivalent to the Rect class, as noted above. Therefore, on the Python side, rectangle vectors are represented as lists of ndarrays. When storing these vectors on the black board, setAs with vector<Rect> as type specifier may be needed to disambiguate the list from a list of ndarrays.

Type conversion table

This table summarises how slmotion handles type conversions between C++ and Python environments. In all cases, data is copied.

C++ type Python type Notes
(unsigned) short int The Python int corresponds to C long in CPython.
(unsigned) int int The Python int corresponds to C long in CPython.
(unsigned) long int The Python int corresponds to C long in CPython.
float float The Python float internally corresponds to IEEE 754 double precision
double float The Python float internally corresponds to IEEE 754 double precision
FeatureVector list (of lists of floats) When converting to a Python object, the feature vector is first converted into a deque of double vectors. The deque is then converted to a list of lists of floats. Each inner list corresponds to one frame, and they all have equal dimensionality. Each element in the inner lists corresponds to one feature entry. All metadata is lost in the conversion.
cv::Mat numpy.ndarray Precise conversion depends on the type of the matrix (i.e. data type, dimensionality, and number of channels)
cv::Rect numpy.ndarray Explicit conversion is available via setAs().
cv::Point numpy.ndarray Explicit conversion is available via setAs().
cv::Point2f numpy.ndarray Explicit conversion is available via setAs().

References

[1] Ville Viitaniemi, Matti Karppa, Jorma Laaksonen, and Tommi Jantunen. Detecting Hand-Head Occlusions in Sign Language Video. In Proceedings of the 18th Scandinavian Conference on Image Analysis (SCIA 2013), Espoo, Finland, June 2013. Available online at http://users.ics.aalto.fi/jmkarppa/scia2013occlusion.pdf.

[2] M. Uřičář, V. Franc and V. Hlaváč, Detector of Facial Landmarks Learned by the Structured Output SVM, VISAPP '12: Proceedings of the 7th International Conference on Computer Vision Theory and Applications, 2012. pdf