Plug-ins' functions

Previous tutorial: Building simple motion detector


As the Lua scripting API suggests, there are number of plug-in types aimed for different purpose. Each type has its own fixed interface, which is implemented by all plug-ins of that type. And this interface allows applications like Computer Vision Sandbox to make use of those plug-ins. However, there are cases, when a particular plug-in may need to provide some extra functions, some APIs which don't fit the defined and fixed interface.

Starting from version 1.2.2 of Computer Vision Sandbox, the base interface of plug-ins is extended with a new CallFunction() API, which allows calling functions exposed by plug-ins. The application itself does not use this new API, but Lua scripting engine does support it since API revision 3 and so allows calling plug-ins' functions from scripts.

Information about functions exposed by plug-ins, their description and arguments list is available on plug-in's description page (plug-ins' help system) when browsing in scripting mode. Any plug-in of any type potentially may expose functions, if the the fixed interface they implement is not enough to provide functionality they aim. However, in practice most plug-ins will stick to the fixed interface and do only the one thing they are designed for - perform image/video processing, image loading/saving, etc. What is more likely to happen in practice, is to have some plug-ins, whose only purpose is to provide some tool functions, which are only aimed to be used from scripting. These plug-ins don't need any of the standard fixed interface - base interface is enough for them. However, to highlight their role, a new Scripting APIs plug-in type was defined. It does not extend base plug-ins interface in any way. Only to make it explicit to users and the system - the plug-in provides functions, which are only aimed to be used from scripting.

The first provided Scripting APIs plug-in is Image Drawing - a plug-in which provides set of functions implementing some drawing primitives on images: drawing lines, rectangle, circles/ellipses, text, images, etc. This plug-in may be useful to highlight something detected on an image, output some status information, decorate it, etc. Below are some of the examples of calling functions of this plug-in.

-- create instance of the Image Drawing plug-in
drawing = Host.CreatePluginInstance( 'ImageDrawing' )

-- drawing and filling rectangles
drawing:CallFunction( 'DrawRectangle', image, { 30, 30 }, { 120, 40 }, '00FF00' )
drawing:CallFunction( 'FillRectangle', image, { 32, 32 }, { 118, 38 }, '8000FF00' )

-- line from (x1, y1) to (x2, y2)
drawing:CallFunction( 'DrawLine', image, { 50, 50 }, { 170, 90 }, '00FF00' )

-- drawing cicle and ellipse
drawing:CallFunction( 'DrawCircle',  image, { 100, 100 }, 50, '00FF00' )
drawing:CallFunction( 'DrawEllipse', image, { 100, 100 }, 90, 55, '8000FF00' )

-- text uses two colors - foreground and background
drawingPlugin:CallFunction( 'DrawText', image, 'Some text to draw',
                            { 100, 150 }, '00FF00', '400000FF' )

-- drawing one image on top of another
imageLoader = Host.CreatePluginInstance( 'ImageDrawing' )
myImage = imageLoader:ImportImage( 'some-image-to-load.png' )
drawingPlugin:CallFunction( 'DrawImage', image, myImage, { 100, 200 } )

As the above scripting sample demonstrates, the first argument to CallFunction() API is always the plug-in's function name to call. The rest of arguments (if any) and their types are explained on plug-in's description page. For converting functions' arguments types (which are same as plug-ins' property types) to Lua types, the Lua scripting API should be consulted, which provides types conversion table.

And finally below is a quick sample of drawing something on an image from camera before it gets displayed, saved or processed further in any way.

One thing to keep in mind while calling too many functions is that transitions from scripting to native code costs CPU cycles - all the function's arguments must be checked and converted to native types, the requested function must be found and invoked, and finally function's return value (if any) must be pushed back into scripting world. It is not terribly slow. Just don't get too crazy with them. In the end you still want to maintain certain frame rate of your video processing.


Next tutorial: Image statistics