Minimal application of a Birds Eye View application

From RidgeRun Developer Connection
Jump to: navigation, search




Previous: Getting_Started/Startup_Guide Index Next: Examples





Building a BEV Minimal Application

The following example aims to show a minimal full Bird's Eye View library application. It loads frames from 4 input fisheye videos, removes the fisheye distortion, applies the required transformation to each image, computes the BEV, shows the frame to the screen, and saves each frame to a file. If you want to skip code explanation go to full example source code.

Prerequisites

To compile and run the following example, RidgeRun's BEV library must be installed. You can refer to the following Build and Installation Guide.

Code structure

First, include the library headers. The library structure is based on the Factory design pattern. Create a factory object with the desired framework, for example, OpenCV. Then create a loader object, that will be in charge of loading the settings from a JSON file to the settings object as follows:

 1 #include <bev/bev.h>
 2 
 3 int main (int argc, char **argv) {
 4 
 5   bev::runtimeError err;
 6 
 7   //Create factory to build framework objects
 8   auto factory = bev::iFrameworkFactory::makeFactory(bev::frameworkCode::OPENCV,err);
 9 
10   //Create settings loader and settings objects
11   auto loader = std::make_shared<bev::json::fileSettingsLoader>();
12   auto settings = std::make_shared<bev::settings>();

Load the settings from the JSON file. Please notice the way to check if the method ended with an error, for example, if the file was not found. All of the methods in the library that may end with an error can return the error object or use a parameter as a reference to recording the error status of the method. Always checking for the error status is a good practice. The rest of the code in this example does not check for errors in each method that may return an error for simplicity and ease code reading. If you want to review full error checking, you can check the library examples included in the source code.

14   //Load settings from file and verify if loading was correct
15   err = loader->load("carSettings.json",settings);
16   if(err.isError()){
17     std::cerr << err.getDescription() << std::endl;
18     exit(1);
19   }

Create the Bird's Eye View library engine, which will be in charge of performing the removal of fisheye distortion and computing the BEV. Also, create the needed objects for video display, video saving, and video loading. Also, create an image loader object to load a car image to overlay the BEV output image.

21   //Create Bird's Eye View engine object
22   auto engine = factory->makeEngine(settings, err);
23 
24   //Create display object
25   auto vDisplay = factory->makeDisplay(err);
26 
27   //Create videoSaver object
28   auto vidSaver = factory->makeVideoSaver(err);
29   //Save video to output.avi at 30 FPS
30   vidSaver->init("output.avi",settings,30);
31 
32   //Create video loaders
33   auto vFront = factory->makeVideoLoader(err);
34   auto vBack = factory->makeVideoLoader(err);
35   auto vLeft = factory->makeVideoLoader(err);
36   auto vRight = factory->makeVideoLoader(err);
37 
38   //Create image loader for car overlay image
39   auto imgLoader = factory->makeImageLoader(err);
40   imgLoader->load("../prototype/imgs/docs/topCar.png");
41   auto car = imgLoader->getFrame(err);

Load videos from local files, and get the first frame from each of the videos. Here, errors should be checked, for example, if the file was not found, or if the first frame was not valid due to file corruption or any other reason.

43   //Load videos from file
44   vFront->load("videos/camera0.mp4");
45   vRight->load("videos/camera1.mp4");
46   vLeft->load("videos/camera2.mp4");
47   vBack->load("videos/camera3.mp4");
48   
49   //Get first frame from all videos
50   auto fFront = vFront->getFrame(err);
51   auto fBack = vBack->getFrame(err);
52   auto fLeft = vLeft->getFrame(err);
53   auto fRight = vRight->getFrame(err);

The following code block is a loop that loads frames from video files while they are available, removes the fisheye distortion, gets a frame with the four images merge in position with the computed BEV perspective. Then optionally a car image overlay can be added using the engine addOverlay method. Also, the current video frame can be saved using the videoSaver object. Finally, the next frame is requested.

55   //Keep running until no more frames are available
56   while(fFront != nullptr && fBack != nullptr &&
57         fLeft != nullptr && fRight != nullptr ){
58 
59     //Remove fisheye distortion from all videos
60     fFront = engine->removeFisheye(fFront,0,err);
61     fBack = engine->removeFisheye(fBack,3,err);
62     fLeft = engine->removeFisheye(fLeft,2,err);
63     fRight = engine->removeFisheye(fRight,1,err);
64     
65     //Compute the BEV with undistorted images
66     auto output = engine->getBEV(fFront, fBack, fLeft, fRight, err);
67 
68     //Add car overlay to generatedBEV
69     output = engine->addOverlay(car,output,err);
70 
71     //Show BEV output frame
72     vDisplay->showImage(output);
73     vDisplay->wait(1);
74 
75     //Save BEV frame to output file
76     vidSaver->saveFrame(output);
77 
78     //Get next frame from videos
79     fFront = vFront->getFrame(err);
80     fBack = vBack->getFrame(err);
81     fLeft = vLeft->getFrame(err);
82     fRight = vRight->getFrame(err);
83 
84   };
85   return 0;
86 };

Compilation

Basic compilation

To compile the example you must link against the RidgeRun's Bird's Eye View library as follows:

  g++ example.cpp $(pkg-config --libs --cflags bev) -o example

Then you can execute the example

  ./example

You will get a live video preview, similar to the following:

Error creating thumbnail: Unable to save thumbnail to destination

Meson compilation

If you are using meson as your build system, you can use the following as a minimal template:

project('BEV Example', 'cpp',
        version : '0.1.0',
        meson_version : '>= 0.50',
        default_options : ['c_std=c11', 'cpp_std=c++11'])

bev_dep = dependency('bev')

executable('example',
           'example.cpp',
           dependencies: [bev_dep])

Full example source code

  1 /* 
  2  * Copyright (C) 2019-2020 RidgeRun, LLC (http://www.ridgerun.com)
  3  * All Rights Reserved.
  4  *
  5  * The contents of this software are proprietary and confidential to RidgeRun,
  6  * LLC.  No part of this program may be photocopied, reproduced or translated
  7  * into another programming language without prior written consent of
  8  * RidgeRun, LLC.  The user is free to modify the source code after obtaining
  9  * a software license from RidgeRun.  All source code changes must be provided
 10  * back to RidgeRun without any encumbrance. This is a free example of the
 11  * Bird's Eye View library.
 12 */
 13 
 14 #include <bev/bev.h>
 15 
 16 /*
 17  * Example: Basic example application
 18  *
 19  * The following example shows how to use the library to 
 20  * get a BEV from 4 input fisheye videos, apply an overlay
 21  * and save it to an output file.
 22  */
 23 int main (int argc, char **argv) {
 24 
 25   bev::runtimeError err;
 26 
 27   //Create factory to build framework objects
 28   auto factory = bev::iFrameworkFactory::makeFactory(bev::frameworkCode::OPENCV,err);
 29 
 30   //Create settings loader and settings objects
 31   auto loader = std::make_shared<bev::json::fileSettingsLoader>();
 32   auto settings = std::make_shared<bev::settings>();
 33   
 34   //Load settings from file and verify if loading was correct
 35   err = loader->load("carSettings.json",settings);
 36   if(err.isError()){
 37     std::cerr << err.getDescription() << std::endl;
 38     exit(1);
 39   }
 40 
 41   //Create Bird's Eye View engine object
 42   auto engine = factory->makeEngine(settings, err);
 43 
 44   //Create display object
 45   auto vDisplay = factory->makeDisplay(err);
 46 
 47   //Create videoSaver object
 48   auto vidSaver = factory->makeVideoSaver(err);
 49   //Save video to output.avi at 30 FPS
 50   vidSaver->init("output.avi",settings,30);
 51 
 52   //Create video loaders
 53   auto vFront = factory->makeVideoLoader(err);
 54   auto vBack = factory->makeVideoLoader(err);
 55   auto vLeft = factory->makeVideoLoader(err);
 56   auto vRight = factory->makeVideoLoader(err);
 57 
 58   //Create image loader for car overlay image
 59   auto imgLoader = factory->makeImageLoader(err);
 60   imgLoader->load("videos/topCar.png");
 61   auto car = imgLoader->getFrame(err);
 62 
 63   //Load videos from file
 64   vFront->load("videos/camera0.mp4");
 65   vRight->load("videos/camera1.mp4");
 66   vLeft->load("videos/camera2.mp4");
 67   vBack->load("videos/camera3.mp4");
 68   
 69   //Get first frame from all videos
 70   auto fFront = vFront->getFrame(err);
 71   auto fBack = vBack->getFrame(err);
 72   auto fLeft = vLeft->getFrame(err);
 73   auto fRight = vRight->getFrame(err);
 74 
 75   //Keep running until no more frames are available
 76   while(fFront != nullptr && fBack != nullptr &&
 77         fLeft != nullptr && fRight != nullptr ){
 78 
 79     //Remove fisheye distortion from all videos
 80     fFront = engine->removeFisheye(fFront,0,err);
 81     fBack = engine->removeFisheye(fBack,3,err);
 82     fLeft = engine->removeFisheye(fLeft,2,err);
 83     fRight = engine->removeFisheye(fRight,1,err);
 84     
 85     //Compute the BEV with undistorted images
 86     auto output = engine->getBEV(fFront, fBack, fLeft, fRight, err);
 87 
 88     //Add car overlay to generatedBEV
 89     output = engine->addOverlay(car,output,err);
 90 
 91     //Show BEV output frame
 92     vDisplay->showImage(output);
 93     vDisplay->wait(1);
 94 
 95     //Save BEV frame to output file
 96     vidSaver->saveFrame(output);
 97 
 98     //Get next frame from videos
 99     fFront = vFront->getFrame(err);
100     fBack = vBack->getFrame(err);
101     fLeft = vLeft->getFrame(err);
102     fRight = vRight->getFrame(err);
103 
104   };
105 
106   return 0;
107 
108 };



Previous: Getting_Started/Startup_Guide Index Next: Examples