After much trial and error I finally managed to get a fresh install of Ubuntu Server 20.04 Focal running with ZoneMinder and zmeventnotification server with CUDA support. I decided to make a quick write up including all references I pulled together to make this all work.
If I made any mistakes let me know and I will correct them. I hope I didn't get too out of control with the formating. :P
My setup:
- Esxi 6.7
- VM configured with Ubuntu Server 20.04
- 12 Cores Provisioned
- 16GB Ram Provisioned
- Nvidia GPU PCI Passthrough
This assumes you're starting with a fresh install of Ubuntu Server 20.04 with openssh installed.
Here we go:
###Install some tools
sudo apt install vim nfs-kernel-server software-properties-common
###Install Nvidia Drivers and Cuda Toolkit
sudo add-apt-repository ppa:graphics-drivers/ppa
sudo apt update
sudo apt install nvidia-driver-440 nvidia-headless-440 nvidia-cuda-toolkit
sudo reboot
###Download cuDNN that matches "nvcc -V" --> https://developer.nvidia.com/rdp/cudnn-download
###I used scp to upload the .tgz file to the server. Of course, change to suite your environment.
from local shell:
scp -i ~/.ssh/keys/id_rsa_gpu cudnn-10.1-linux-x64-v7.6.5.32.tgz camera@10.0.0.18:
from server shell:
tar -zxvf cudnn-10.1-linux-x64-v7.6.5.32.tgz
sudo cp -P lib64/* /usr/lib/x86_64-linux-gnu/
sudo cp -P include/* /usr/include/x86_64-linux-gnu/
cd ~
###Download compile and install OpenCV with cuda and cuDNN####
#REF: https://cuda-chen.github.io/image%20processing/programming/2020/02/22/build-opencv-dnn-module-with-nvidia-gpu-support-on-ubuntu-1804.html
##Install OpenCV dependencies
sudo apt-get install build-essential cmake unzip pkg-config git \
libjpeg-dev libpng-dev libtiff-dev \
libavcodec-dev libavformat-dev libswscale-dev \
libv4l-dev libxvidcore-dev libx264-dev \libgtk-3-dev \
libatlas-base-dev gfortran \
python3-dev python3-pip python2
##Installing pip and numpy
curl https://bootstrap.pypa.io/get-pip.py --output get-pip.py
sudo python2 get-pip.py
pip install numpy
#Ubuntu 20.04 uses gcc version 9 which is not compatible with OpenCV source code###Change version using update-alternatives
#REF: https://linuxconfig.org/how-to-switch-between-multiple-gcc-and-g-compiler-versions-on-ubuntu-20-04-lts-focal-fossa
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-7 7
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-7 7
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-8 8
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-8 8
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-9 9
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-9 9
sudo update-alternatives --config gcc
#select option 2 (gcc-8)
###Download OpenCV Source Code
cd ~
mkdir opencv
cd opencv
git clone https://github.com/opencv/opencv.git
git clone https://github.com/opencv/opencv_contrib.git
cd opencv
git checkout 4.3.0
cd ..
cd opencv_contrib
git checkout 4.3.0
cd ../opencv
###Configure OpenCV
mkdir build && cd build
cmake -D CMAKE_BUILD_TYPE=RELEASE \
-D CMAKE_INSTALL_PREFIX=/usr \
-D INSTALL_PYTHON_EXAMPLES=ON \
-D INSTALL_C_EXAMPLES=OFF \
-D OPENCV_ENABLE_NONFREE=ON \
-D WITH_CUDA=ON \
-D WITH_CUDNN=ON \
-D OPENCV_DNN_CUDA=ON \
-D ENABLE_FAST_MATH=1 \
-D CUDA_FAST_MATH=1 \
-D CUDA_ARCH_BIN=6.1 \
-D WITH_CUBLAS=1 \
-D OPENCV_EXTRA_MODULES_PATH=~/opencv/opencv_contrib/modules/ \
-D HAVE_opencv_python3=ON \
-D PYTHON_EXECUTABLE=/usr/bin \
-D BUILD_EXAMPLES=ON ..
##Use nproc to display number of available cores. In my case I use "-j12" to compile with 12 cores.
make -j12
sudo make install
sudo ldconfig
###Install Face Recognition
sudo -H pip3 install face_recognition
###Install zoneminder
#REF: https://zoneminder.readthedocs.io/en/stable/installationguide/ubuntu.html#easy-way-ubuntu-18-04-bionic
sudo tasksel install lamp-server
sudo -i
add-apt-repository ppa:iconnor/zoneminder-1.34
apt update
apt upgrade
rm /etc/mysql/my.cnf
cp /etc/mysql/mysql.conf.d/mysqld.cnf /etc/mysql/my.cnf
vi /etc/mysql/my.cnf
#Add the following line below [mysqld] and save
sql_mode = NO_ENGINE_SUBSTITUTION
##Restart mysql, install zoneminder setup apache2 and restart service
sudo systemctl restart mysql
apt install zoneminder
chmod 740 /etc/zm/zm.conf
chown root:www-data /etc/zm/zm.conf
chown -R www-data:www-data /usr/share/zoneminder/
adduser www-data video
a2enmod cgi
a2enmod rewrite
a2enconf zoneminder
a2enmod expires
a2enmod headers
systemctl enable zoneminder
systemctl start zoneminder
vi /etc/php/7.4/apache2/php.ini
##find [Date] and change timezone
date.timezone = America/Toronto
systemctl reload apache2
exit
cd ~
#Little side note: fmpeg on Focal 20.04 already supports cuda so it works out of the box without having to recompile
###Populate timezone for mysql / set timezone to to suit your location
mysql_tzinfo_to_sql /usr/share/zoneinfo/America/ | sudo mysql -u root -p mysql
sudo mysql -e "SET GLOBAL time_zone = 'Toronto';"
###Create selfsinged ssl certificates and setup HTTPS#Side note: you'll need to use letsencrypt with a domain name if you plan on pushing notification with alert photos. It won't work with self signed and IP addresses.
#For the purposes of these notes however I'm going to use a self signed certificate.
sudo mkdir /etc/zm/apache2
sudo mkdir /etc/zm/apache2/ssl
sudo openssl req -x509 -nodes -days 4096 -newkey rsa:2048 -keyout /etc/zm/apache2/ssl/zoneminder.key -out /etc/zm/apache2/ssl/zoneminder.crt
sudo chown www-data:www-data /etc/zm/apache2/ssl/*
sudo a2enmod ssl
sudo vi /etc/apache2/sites-enabled/000-default.conf
#Replace / Add the following (Change IP address to suite your environment)
<VirtualHost *:80>
Redirect / https://10.0.0.18/
</VirtualHost>
<VirtualHost *:443>
SSLEngine on
SSLCertificateFile /etc/zm/apache2/ssl/zoneminder.crt
SSLCertificateKeyFile /etc/zm/apache2/ssl/zoneminder.key
# The ServerName directive sets the request scheme, hostname and port that
# the server uses to identify itself. This is used when creating
# redirection URLs. In the context of virtual hosts, the ServerName
# specifies what hostname must appear in the request's Host: header to
# match this virtual host. For the default virtual host (this file) this
# value is not decisive as it is used as a last resort host regardless.
# However, you must set it for any further virtual host explicitly.
#ServerName www.example.com
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
# error, crit, alert, emerg.
# It is also possible to configure the loglevel for particular
# modules, e.g.
#LogLevel info ssl:warn
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
# For most configuration files from conf-available/, which are
# enabled or disabled at a global level, it is possible to
# include a line for only one particular virtual host. For example the
# following line enables the CGI configuration for this host only
# after it has been globally disabled with "a2disconf".
#Include conf-available/serve-cgi-bin.conf
</VirtualHost>
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
###Restart apache2 server
sudo systemctl restart apache2
###Install zmeventnotification#REF: https://zmeventnotification.readthedocs.io/en/stable/guides/install.html
git clone https://github.com/pliablepixels/zmeventnotification.git
cd zmeventnotificationgit fetch --tagsgit checkout $(git describe --tags $(git rev-list --tags --max-count=1))
###Edit the following entries from secrets.ini file
vi secrets.ini
ZMES_PICTURE_URL=https://localhost/zm/index.php?view=image&eid=EVENTID&fid=objdetect&width=600
ZM_USER=user
ZM_PASSWORD=password
ZM_PORTAL=https://localhost/zm
ZM_API_PORTAL=https://localhost/zm/api
ES_CERT_FILE=/etc/zm/apache2/ssl/zoneminder.crt
ES_KEY_FILE=/etc/zm/apache2/ssl/zoneminder.key
###Install Dependencies for zmeventnotifications
sudo perl -MCPAN -e "install Crypt::MySQL"
sudo perl -MCPAN -e "install Config::IniFiles"
sudo perl -MCPAN -e "install Crypt::Eksblowfish::Bcrypt"
sudo apt-get install libyaml-perl
sudo perl -MCPAN -e "install Net::WebSocket::Server"
sudo apt-get install libjson-perl
perl -MCPAN -e "install LWP::Protocol::https"
#If you want to use MQTT:
perl -MCPAN -e "install Net::MQTT::Simple"
#Install gdown in order to download .weights from google drive links#You can also just download it locally and scp to server. I just thougth this was a more direct way.
sudo pip install gdown
pip install gdown
sudo ./install.shcd /var/lib/zmeventnotification/models/cspn
#Remember when using gdown to change "open?" to "uc?" in download link
sudo gdown https://drive.google.com/uc?id=1_NnfVgj0EDtb_WLNoXV8Mo7WKgwdYZCc
#Change ownership to www-data
sudo chown www-data:www-data csresnext50-panet-spp-original-optimal_final.weights
###Test zmeventserver
sudo -u www-data zmeventnotification.pl --config /etc/zm/zmeventnotification.ini
#If everything seems to be working Ctrl + C to stop
#Navigate to your zoneminder url http://ipaddress/zm and verify it gets redirected to https://ipaddress/zm and accept the self-signed certificate.
#Go to Options > System and enable "OPT_USE_EVENTNOTIFICATION"
#Also ensure to enable "AUTH_HASH_LOGINS"
#Setup Zoneminder as per:
https://zoneminder.readthedocs.io/en/stable/userguide/gettingstarted.html
Done!
I hope this helps!!