Skip to main content

Tensorflow2 Crash Course - Part III

Mong Kok, Hongkong

This set of Notebooks provides a complete set of code to be able to train and leverage your own custom object detection model using the Tensorflow Object Detection API.

This article is based on a Tutorial by @nicknochnack.

Github Repository

Object Detection

Load Train Model From Checkpoint

This step requires a few import that caused some - Manjaro Linux / Anaconda3 related - issues - see Debugging below.

The previous training generated 3 check point in TFODCourse/Tensorflow/workspace/models/my_ssd_mobnet out of which I will choose the last one:

ckpt.restore(os.path.join(paths['CHECKPOINT_PATH'], 'ckpt-3')).expect_partial()

Detect Object from an Image File

Select an image from the test folder that you want to run your algorithm against, e.g.

Tensorflow/workspace/images/test/metal.tyrxdf6-zzggg-RGdgfc-zdfg-1cDGF17f.jpg

And add it to the corresponding line in your notebook:

IMAGE_PATH = os.path.join(paths['IMAGE_PATH'], 'test', 'metal.tyrxdf6-zzggg-RGdgfc-zdfg-1cDGF17f.jpg')

Now run the detection code and see if the object is classified correctly:

Tensorflow Object Detection Walkthrough

Detect Object from your Live Videstream

Here I got another Error Message:

(-2:Unspecified error) Rebuild the library with Windows, GTK+ 2.x or Carbon support. If you are on Ubuntu or Debian, install libgtk2.0-dev and pkg-config, then re-run cmake or configure script in function 'cvShowImage'.

This is a problem with openCV and missing libraries. I found that you can install the following package using pip inside your virtual environment:

pip install opencv-contrib-python

And the second solution was to globally install the following packages using your distro's package manager:

sudo pacman -Syu gtk4 pkg-config

Once I had done that everything worked as expected:

Tensorflow Object Detection Walkthrough

The artifacts inside the video come from the UDP protocol and can be fixed by switching it to TCP. But I am currently having some issues with the RTSP server and have only the UDP option.

Debugging

The notebook import two libraries that rely have a c++ dependency - libstdc++.so, cpython-39-x86_64-linux-gnu.so:

from object_detection.utils import visualization_utils as viz_utils
from object_detection.builders import model_builder

The first ERROR Message that I received while importing visualization_utils was:

ImportError: /opt/Python/TFODCourse/tfod/lib/python3.9/site-packages/matplotlib/ft2font.cpython-39-x86_64-linux-gnu.so: undefined symbol: _ZSt28__throw_bad_array_new_lengthv

This could be solved by upgrading Matplotlib from 3.2.0 to version 3.2.2:

pip uninstall -y matplotlib
pip install matplotlib==3.2.2

When I now re-try the import the ERROR Message changes to:

ImportError: /home/myuser/anaconda3/bin/../lib/libstdc++.so.6: version `GLIBCXX_3.4.29' not found (required by /opt/Python/TFODCourse/tfod/lib/python3.9/site-packages/matplotlib/_path.cpython-39-x86_64-linux-gnu.so)`

I have Manjaro (Arch) Linux installed and am running the latest version of Anaconda3. The latter uses libstdc++.so.6.0.28 while the newest version of Manjaro comes with libstdc++.so.6.0.29. When I check the Anaconda version I can see that it only goes up to `GLIBCXX_3.4.28':

/home/myuser/anaconda3/lib/libstdc++.so.6 | grep GLIBCXX

GLIBCXX_3.4
GLIBCXX_3.4.1
GLIBCXX_3.4.2
GLIBCXX_3.4.3
GLIBCXX_3.4.4
GLIBCXX_3.4.5
GLIBCXX_3.4.6
GLIBCXX_3.4.7
GLIBCXX_3.4.8
GLIBCXX_3.4.9
GLIBCXX_3.4.10
GLIBCXX_3.4.11
GLIBCXX_3.4.12
GLIBCXX_3.4.13
GLIBCXX_3.4.14
GLIBCXX_3.4.15
GLIBCXX_3.4.16
GLIBCXX_3.4.17
GLIBCXX_3.4.18
GLIBCXX_3.4.19
GLIBCXX_3.4.20
GLIBCXX_3.4.21
GLIBCXX_3.4.22
GLIBCXX_3.4.23
GLIBCXX_3.4.24
GLIBCXX_3.4.25
GLIBCXX_3.4.26
GLIBCXX_3.4.27
GLIBCXX_3.4.28
GLIBCXX_DEBUG_MESSAGE_LENGTH

I created an backup of all libstdc++.so* files/symlinks and linked in the system library in their place:

mv /home/myuser/anaconda3/lib/libstdc++.so /home/myuser/anaconda3/lib/libstdc++.so.bak
ln -s /usr/lib/libstdc++.so.6.0.29 /home/myuser/anaconda3/lib/libstdc++.so

mv /home/myuser/anaconda3/lib/libstdc++.so.6 /home/myuser/anaconda3/lib/libstdc++.so.6.bak
ln -s /usr/lib/libstdc++.so.6.0.29 /home/myuser/anaconda3/lib/libstdc++.so.6

mv /home/myuser/anaconda3/lib/libstdc++.so.6.0.28 /home/myuser/anaconda3/lib/libstdc++.so.6.0.28.bak
ln -s /usr/lib/libstdc++.so.6.0.29 /home/myuser/anaconda3/lib/libstdc++.so.6.0.28

The result looks like this:

ll /home/myuser/anaconda3/lib | grep ibstdc++ 

lrwxrwxrwx 1 myuser myuser 28 Jan 2 16:17 libstdc++.so -> /usr/lib/libstdc++.so.6.0.29
lrwxrwxrwx 1 myuser myuser 28 Jan 2 16:17 libstdc++.so.6 -> /usr/lib/libstdc++.so.6.0.29
lrwxrwxrwx 1 myuser myuser 28 Jan 2 15:10 libstdc++.so.6.0.28 -> /usr/lib/libstdc++.so.6.0.29
-rwxrwxr-x 3 myuser myuser 13121976 Jun 3 2021 libstdc++.so.6.0.28.bak
lrwxrwxrwx 1 myuser myuser 19 Dec 25 17:01 libstdc++.so.6.bak -> libstdc++.so.6.0.28
lrwxrwxrwx 1 myuser myuser 19 Dec 25 17:01 libstdc++.so.bak -> libstdc++.so.6.0.28

When I recheck the file I now see the necessary reference to GLIBCXX_3.4.29:

/home/myuser/anaconda3/lib/libstdc++.so.6 | grep GLIBCXX

GLIBCXX_3.4
GLIBCXX_3.4.1
GLIBCXX_3.4.2
GLIBCXX_3.4.3
GLIBCXX_3.4.4
GLIBCXX_3.4.5
GLIBCXX_3.4.6
GLIBCXX_3.4.7
GLIBCXX_3.4.8
GLIBCXX_3.4.9
GLIBCXX_3.4.10
GLIBCXX_3.4.11
GLIBCXX_3.4.12
GLIBCXX_3.4.13
GLIBCXX_3.4.14
GLIBCXX_3.4.15
GLIBCXX_3.4.16
GLIBCXX_3.4.17
GLIBCXX_3.4.18
GLIBCXX_3.4.19
GLIBCXX_3.4.20
GLIBCXX_3.4.21
GLIBCXX_3.4.22
GLIBCXX_3.4.23
GLIBCXX_3.4.24
GLIBCXX_3.4.25
GLIBCXX_3.4.26
GLIBCXX_3.4.27
GLIBCXX_3.4.28
GLIBCXX_3.4.29
GLIBCXX_DEBUG_MESSAGE_LENGTH

Re-running the import now works as expected:

from object_detection.utils import visualization_utils as viz_utils
from object_detection.builders import model_builder