


VStabilizerCv C++ lib. Fast cross-platform video stabilisation library
C++ library VStabilizerCv v5.2.0 is designed for 2D and 3D digital video stabilization (horizontal offset, vertical offset and rotation).
LICENSE: We sell source code of this library as is, without future updates and technical support according to perpetual non-exclusive royalty-free license. You pay once and can use this library in your software and hardware products without limits. Please read the license agreement before purchasing: DOWNLOAD LICENSE. You can buy technical support service for this product.
C++ library VStabilizerCv v5.2.0 is designed for 2D and 3D digital video stabilization (horizontal offset, vertical offset and rotation).
LICENSE: We sell source code of this library as is, without future updates and technical support according to perpetual non-exclusive royalty-free license. You pay once and can use this library in your software and hardware products without limits. Please read the license agreement before purchasing: DOWNLOAD LICENSE. You can buy technical support service for this product.
C++ library VStabilizerCv v5.2.0 is designed for 2D and 3D digital video stabilization (horizontal offset, vertical offset and rotation).
LICENSE: We sell source code of this library as is, without future updates and technical support according to perpetual non-exclusive royalty-free license. You pay once and can use this library in your software and hardware products without limits. Please read the license agreement before purchasing: DOWNLOAD LICENSE. You can buy technical support service for this product.
Purchase options
You can by this software online by bank transfer. Bank transfer available only for companies. To buy software by bank transfer please send us request to info@constantrobotics.com. Also, you can buy technical support service for this product.
Overview
VStabiliserCv C++ library performs 2D and 3D digital video stabilization (horizontal offset, vertical offset and rotation). The library is used in camera systems for video vibration compensation. The library is written in C++ (C++17 standard) and utilizes the OpenCV library (version 4.5 and higher) to perform various operations (cv::dft, cd::idft, cv::warpAffine etc.) and uses Nvidia VPI for Nvidia Jetson platforms. The library provides flexibility in choosing type of backend for different operations in stabilization algorithm. The library has a simple programming interface and a minimal number of parameters. It inherits interface from VStabiliser (source code included, Apache 2.0 license) class which provides flexible and customizable parameters. Additionally, the demo application depends on open source SimpleFileDialog library (provides file dialog functions to open video files, source code included Apache 2.0 license). The library supports varies pixel formats (RBG24, BGR24, GRAY, YUV24, YUYV, UYVY, NV12, NV21, YV12, YU12, listed in Frame class) and performs calculations in a single computational thread. The library is supplied as source code only.
Demo video

What’s new in v5.2.0
Camera trajectory filter changed to Kalman filter.
Code optimization.
Add Jetson VPI support.
Benchmarks
In order to evaluate the calculation speed of the VStabilizerCv library on a particular processor and operating system, the VStabilizerCvBenchmark test program is provided. It allows you to test the library with different parameters. The VStabilizerCvDemo application is provided as well for testing on your video. Additionally, a test video file is provided to ensure uniform testing conditions across different platforms. The test video provides the most challenging conditions for the stabilisation algorithms. For scenarios with lower vibrations, the processing time can be even lower. Detailed information about benchmark results can be found in Programmer’s manual. Some results (processing time for one video frame, best results):
Intel(TM) i7-13700H, 1920x1080 pixels video, 2D stabilisation - 1.2 msec.
Intel(TM) i7-13700H, 1920x1080 pixels video, 3D stabilisation - 2.1 msec.
Raspberry PI 4B, 1920x1080 pixels video, 2D stabilisation - 9.0 msec.
Raspberry PI 4B, 1920x1080 pixels video, 3D stabilisation - 16.1 msec.
Jetson Orin NX, 1920x1080 pixels video, 2D stabilisation (VPI) - 3.9 msec.
Jetson Orin NX, 1920x1080 pixels video, 3D stabilisation (VPI) - 5.1 msec.
Test video and stabilisation results with different library parameters you can check on video.
Library principles
The stabilization algorithm compensates horizontal displacement, vertical displacement and the rotation of video frames, taking into account the constant motion of the camera. The library provides flexibility in choosing type of backend for different operations in stabilization algorithm. The algorithm consists of the following sequential steps:
Obtaining the source video frame and converting it to GRAY format (grayscale).
Calculation offsets between current video frame and previous video frame (based on FFT or optical flow depends on parameters).
To compensate for the constant camera movement, the components of the camera constant motion (estimated by algorithm) are subtracted from the calculated transformation parameters.
The resulting transformation matrix is applied to the current image to compensate displacements and rotations.
The library delivered as source code only. To use the library, the developer must include library files in his project. It is also necessary to connect the OpenCV library version 4.5 or higher to the project. The sequence of using the library is as follows:
Include library files in the project.
Connect the OpenCV library to the project (in Linux install OpenCV libraries).
Create an instance of the VStabiliserCv C++ class.
If necessary, change the default library parameters by calling the setParam(…).
Create Frame class objects for input and output video frames.
Call the stabilise(…) method to stabilise video frame.
Simple interface
class VStabiliserCv: public VStabiliser
{
public:
/// Class constructor.
VStabiliserCv();
/// Class destructor.
~VStabiliserCv();
/// Get string of current VStabiliserCv class version.
static std::string getVersion();
/// Init all video stabiliser parameters by params structure.
bool initVStabiliser(cr::vstab::VStabiliserParams& params) override;
/// Set feature detector type. Default is OpenCV.
void setFeatureDetectorType(int type);
/// Set optical flow type. Default is OpenCV.
void setOpticalFlowType(int type);
/// Set image transformation type. Default is OpenCV.
void setImageTransformationType(int type);
/// Set value to parameter with given id.
bool setParam(cr::vstab::VStabiliserParam id, float value) override;
/// Get parameter with given id.
float getParam(cr::vstab::VStabiliserParam id) override;
/// Get params.
void getParams(VStabiliserParams& params) override;
/// Execute command.
bool executeCommand(VStabiliserCommand id, float value = 0.0f) override;
/// Stabilise video frame.
bool stabilise(cr::video::Frame& src, cr::video::Frame& dst) override;
/// Get offsets: horizontal, vertical and rotation.
void getOffsets(float& dX, float& dY, float& dA) override;
/// Decode and execute command.
bool decodeAndExecuteCommand(uint8_t* data, int size) override;
};
Simple example
#include <iostream>
#include <opencv2/opencv.hpp>
#include <VStabiliserCv.h>
int main(void)
{
// Init video source.
cv::VideoCapture cap;
if (!cap.open("test.mp4"))
return -1;
// Get video frame size.
int width = (int)cap.get(cv::CAP_PROP_FRAME_WIDTH);
int height = (int)cap.get(cv::CAP_PROP_FRAME_HEIGHT);
// Init images.
cv::Mat opencvSrcFrame(cv::Size(width, height), CV_8UC3);
cv::Mat opencvDstFrame(cv::Size(width, height), CV_8UC3);
cr::video::Frame srcFrame(width, height, cr::video::Fourcc::BGR24);
cr::video::Frame dstFrame(width, height, cr::video::Fourcc::BGR24);
// Create video stabilizer object.
cr::vstab::VStabiliserCv videoStabilizer;
// Set video stabilizer parameters.
videoStabilizer.setParam(cr::vstab::VStabiliserParam::SCALE_FACTOR, 1);
videoStabilizer.setParam(cr::vstab::VStabiliserParam::TYPE, 0);
// Main loop.
while (true)
{
// Capture next video frame.
cap >> opencvSrcFrame;
if (opencvSrcFrame.empty())
{
// If we have video we can set initial video position.
cap.set(cv::CAP_PROP_POS_FRAMES, 1);
// Reset video stabiliser.
videoStabilizer.executeCommand(cr::vstab::VStabiliserCommand::RESET);
continue;
}
// Copy video frame data from OpenCV image to Frame object.
memcpy(srcFrame.data, opencvSrcFrame.data, srcFrame.size);
// Stabilise frame.
if (!videoStabilizer.stabilise(srcFrame, dstFrame))
std::cout << "Stabilisation not calculated" << std::endl;
// Copy Frame object data to OpenCV image.
memcpy(opencvDstFrame.data, dstFrame.data, dstFrame.size);
// Show source and result images.
cv::imshow("SOURCE VIDEO", opencvSrcFrame);
cv::imshow("RESULT VIDEO", opencvDstFrame);
// Process keyboard events.
switch (cv::waitKey(1))
{
case 27: // ESC - exit.
exit(0);
case 32: // SPACE - reset video stabilizer.
videoStabilizer.executeCommand(cr::vstab::VStabiliserCommand::RESET);
break;
}
}
return 1;
}