JeVois Tutorials
1.22
JeVois Smart Embedded Machine Vision Tutorials
|
|
Here we develop a simple C++ OpenCV vision module that counts the total number of pips on some dice presented to JeVois. This application scenario was suggested by JeVois user mapembert at the JeVois Tech Zone in this post:
http://jevois.org/qa/index.php?qa=328
In this tutorial, you will learn:
This tutorial assumes JeVois v1.3 or later.
Because we need to cross-compile C++ code for execution on the JeVois processor, this tutorial is for Linux only.
See JeVois python tutorial: A dice counting module for an implementation of this algorithm in Python + OpenCV (Linux, Windows, or Mac host).
The easiest to get started is to grab a copy of the samplemodule in the JeVois github https://github.com/jevois/samplemodule and to modify it.
If you have installed the jevois-sdk and followed the instructions in Setting up for programming JeVois, you should use the script jevois-create-module
which will grab that sample code from GitHub, and will also immediately change names of classes and files to match our new module's name: usage is jevois-create-module <VendorName> <ModuleName>
, so here let us just run:
cd jevois-create-module Tutorial DiceCounter
you should now have the following:
dicecounter ├── CMakeLists.txt ├── COPYING ├── INSTALL ├── README ├── rebuild-host.sh ├── rebuild-platform.sh └── src └── Modules └── DiceCounter ├── DiceCounter.C ├── icon.png ├── postinstall └── screenshot1.png
The author of the original module mentioned in the above post, Yohann Payet, sent us his code, which is written in C++ and as follows (this is standalone code not intended for operation on JeVois; in this tutorial we will convert adapt it for use in JeVois):
Our tasks now are:
This algorithm was written for 640x480 resolution. Let us use that in our module as well. We edit ~/dicecounter/src/Modules/DiceCounter/postinstall as follows:
jevois-add-videomapping YUYV 640 480 17 YUYV 640 480 17 Tutorial DiceCounter
The postinstall script will be run by the JeVois camera after we install our new module to microSD. The video mapping required by our module and defined in postinstall will then be added to the main videomappings.cfg file on the microSD. Note that postinstall applies to the platform hardware only. To add the videomapping to your host configuration, just run the above command on your host computer (using sudo).
Note how here we have chosen 17 frames/s as our initial guess for framerate. Because 640x480 is a popular resolution, this will also allow us to avoid clashes with other modules that use this same resolution but rates of 30 frames/s or others. We will adjust this rate later once we know how fast this algorithm runs on JeVois.
The JeVois samplemodule runs fine out of the box and thus our module should run as well if we have not introduced any mistakes.
Compiling and installing the module to live microSD inside a connected JeVois camera has been automated through CMake, just connect JeVois and let it boot, then type:
cd ~/dicecounter ./rebuild-platform.sh --live
Which will instruct JeVois to export its microSD as a virtual flash drive to the host computer, will copy the required files, and will eject the drive to reboot JeVois. The module will be ready for use once JeVois has restarted.
You should see an output like this:
itti@iLab1:~/dicecounter$ ./rebuild-platform.sh --live -- JeVois version 1.2.3 -- JEVOIS_PLATFORM: ON -- JEVOIS_VENDOR: Tutorial -- JeVois microSD card mount point: /media/itti/JEVOIS -- JeVois serial-over-USB device: /dev/ttyACM0 -- JEVOIS_MODULES_TO_STAGING: OFF -- JEVOIS_MODULES_TO_MICROSD: OFF -- JEVOIS_MODULES_TO_LIVE: ON -- Install prefix for executable programs: /var/lib/jevois-build/usr -- Host path to jevois modules root: /var/lib/jevois-microsd -- The C compiler identification is GNU 6.1.0 -- The CXX compiler identification is GNU 6.1.0 -- Check for working C compiler: /lab/itti/jevois/software/jevois-sdk/out/sun8iw5p1/linux/common/buildroot/host/usr/bin/arm-buildroot-linux-gnueabihf-gcc -- Check for working C compiler: /lab/itti/jevois/software/jevois-sdk/out/sun8iw5p1/linux/common/buildroot/host/usr/bin/arm-buildroot-linux-gnueabihf-gcc -- works -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- Detecting C compile features -- Detecting C compile features - done -- Check for working CXX compiler: /lab/itti/jevois/software/jevois-sdk/out/sun8iw5p1/linux/common/buildroot/host/usr/bin/arm-buildroot-linux-gnueabihf-g++ -- Check for working CXX compiler: /lab/itti/jevois/software/jevois-sdk/out/sun8iw5p1/linux/common/buildroot/host/usr/bin/arm-buildroot-linux-gnueabihf-g++ -- works -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- Detecting CXX compile features -- Detecting CXX compile features - done -- JeVois SDK root: /lab/itti/jevois/software/jevois-sdk -- Adding compilation directives for C++ module DiceCounter base src/Modules -- Configuring done -- Generating done -- Build files have been written to: /lab/itti/dicecounter/pbuild Scanning dependencies of target modinfo_DiceCounter [ 50%] Generating ../src/Modules/DiceCounter/modinfo.yaml, ../src/Modules/DiceCounter/modinfo.html [ 50%] Built target modinfo_DiceCounter Scanning dependencies of target DiceCounter [100%] Building CXX object CMakeFiles/DiceCounter.dir/src/Modules/DiceCounter/DiceCounter.C.o Linking CXX shared library DiceCounter.so [100%] Built target DiceCounter [ 50%] Built target modinfo_DiceCounter [100%] Built target DiceCounter Install the project... -- Install configuration: "" JeVois smart camera virtual USB ready at /media/itti/JEVOIS -- Installing: /media/itti/JEVOIS/modules/Tutorial/DiceCounter -- Installing: /media/itti/JEVOIS/modules/Tutorial/DiceCounter/postinstall -- Installing: /media/itti/JEVOIS/modules/Tutorial/DiceCounter/screenshot1.png -- Installing: /media/itti/JEVOIS/modules/Tutorial/DiceCounter/icon.png -- Installing: /media/itti/JEVOIS/modules/Tutorial/DiceCounter/DiceCounter.so -- Removed runtime path from "/media/itti/JEVOIS/modules/Tutorial/DiceCounter/DiceCounter.so" JeVois smart camera virtual USB disk ejected -- rebooting JeVois
Fire up your video capture software and set it to 640x480 @ 17fps. You should see the sample python module running, but under our new name:
Let us just edit DiceCounter.C to use the code above. The main changes are:
Here is the resulting code:
You should see something like this:
Note that this algorithm runs a bit slow on JeVois, about 8 frames/s. One could adjust the videomapping accordingly.
Interestingly, it runs at about the same speed with this implementation as the Python implementation developed in JeVois python tutorial: A dice counting module, although we had hypothesized in that Python tutorial that we might be able to make the C++ code run faster! Here is the reason: Image conversion from YUYV to BGR and to grayscale (in img = inframe.getCvBGR()
and grayImage = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
of the python code, and from BGR to YUYV in outframe.sendCvBGR(im_with_keypoints)
is not counted as processing time in the Python module, but all conversions are counted by the timer of the C++ implementation. So the C++ algorithm including all conversions runs about as fast as just the core of the Python implementation not including any conversion. In any case, it looks like the JeVois and the OpenCV Python bindings are indeed quite efficient!
Given that anyone is unlikely to be needing any kind of fast frame rate for this application (since dice will not get thrown too often), here no further optimization is necessary. The low frame rate will allow the camera sensor to perform well even in low light conditions.
To create a nice packaged module that you can send to your friends, just type:
./rebuild-platform.sh
Which installs instead to a directory jvpkg in your module:
Install the project... -- Install configuration: "" -- Installing: /lab/itti/dicecounter/jvpkg/modules/Tutorial/DiceCounter -- Installing: /lab/itti/dicecounter/jvpkg/modules/Tutorial/DiceCounter/postinstall -- Installing: /lab/itti/dicecounter/jvpkg/modules/Tutorial/DiceCounter/screenshot1.png -- Installing: /lab/itti/dicecounter/jvpkg/modules/Tutorial/DiceCounter/icon.png -- Installing: /lab/itti/dicecounter/jvpkg/modules/Tutorial/DiceCounter/DiceCounter.so -- Removed runtime path from "/lab/itti/dicecounter/jvpkg/modules/Tutorial/DiceCounter/DiceCounter.so"
You would then finally type:
cd pbuild make jvpkg
which creates ~/dicecounter/Tutorial_dicecounter.jvpkg
You can send that file to your friends, and tell them to copy it to JEVOIS:/packages/ on their microSD. Next time JeVois restarts, it will unpack, install, configure, and delete the package, and the new module will be ready for use.
This module has now been integrated into jevoisbase, as the DiceCounter module with output resolution 640x480 @ 7.5 fps.