Compare commits
No commits in common. "c692f88fce7d3dd3d3d11e044206c76342016c93" and "c124d3c45b8c620301697c239a12fa502e90cb27" have entirely different histories.
c692f88fce
...
c124d3c45b
20
README.md
20
README.md
@ -42,12 +42,24 @@ the ``dist`` folder.
|
|||||||
|
|
||||||
## Setup development environment
|
## Setup development environment
|
||||||
|
|
||||||
### Use automatic setup script
|
### Install ultimateALPR SDK
|
||||||
You can use the ``build_and_setup_ultimatealvr.sh`` script to automatically install the necessary packages and build the ultimateALPR SDK wheel, copy the assets and the libs.
|
#### Manually build the wheel
|
||||||
|
If you want to build the wheel yourself, you can use the ``build_and_setup_ultimatealvr.sh`` script. It will create a new
|
||||||
|
directory ``tmp`` and build the wheel in there. It also includes the assets and libs folders needed when developing.
|
||||||
> [!IMPORTANT]
|
> [!IMPORTANT]
|
||||||
> Make sure to install the package python3-dev (APT) python3-devel (RPM) before running the build and setup script.
|
> Make sure to install the package python3-dev (APT) python3-devel (RPM) before running the build and setup script.
|
||||||
|
#### Use already built wheel (quick and easy but not recommended for dev)
|
||||||
|
I have already built the ultimateALPR SDK for x86_64 and ARM64 and included the python3.10 wheel in the wheel folder.
|
||||||
|
You can install the wheel using : ``pip install wheel/*.whl``
|
||||||
|
|
||||||
The end structure should look like this:
|
### Copy necessary files/folders
|
||||||
|
Copy the ``assets`` and ``libs`` folders to the same directory as the script.
|
||||||
|
|
||||||
|
- If you built the wheel in the previous step, you can copy the ``assets`` and ``libs`` folders from the ``tmp`` directory.
|
||||||
|
|
||||||
|
- *If you used the already built wheel, you can find the 'assets' and 'libs' folders on the [GitHub repository](https://github.com/DoubangoTelecom/ultimateALPR-SDK/tree/master/assets), although you will manually copy every ``*.so*`` file from ``/binaries/linux/<arch>/`` into a newly created ``libs`` folder.*
|
||||||
|
|
||||||
|
The structure should look like this:
|
||||||
```bash
|
```bash
|
||||||
.
|
.
|
||||||
├── alpr_api.py
|
├── alpr_api.py
|
||||||
@ -62,7 +74,7 @@ The end structure should look like this:
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Important notes
|
### Important notes
|
||||||
When running, building or developing the script, make sure to set the ``LD_LIBRARY_PATH`` environment variable to the libs folder
|
When building or developing the script, make sure to set the ``LD_LIBRARY_PATH`` environment variable to the libs folder
|
||||||
*(limitation of the ultimateALPR SDK)*.
|
*(limitation of the ultimateALPR SDK)*.
|
||||||
```bash
|
```bash
|
||||||
export LD_LIBRARY_PATH=libs:$LD_LIBRARY_PATH
|
export LD_LIBRARY_PATH=libs:$LD_LIBRARY_PATH
|
||||||
|
@ -1 +1 @@
|
|||||||
pyinstaller --noconfirm --onefile --console --add-data libs:. --add-data assets:assets --add-data static:static --add-data templates:templates --name easy-local-alpr-1.0.0-linux_x86_64 "alpr_api.py"
|
pyinstaller --noconfirm --onefile --console --add-data libs:. --add-data assets:assets --add-data static:static --add-data templates:templates --add-binary plugins.xml:. --name easy-local-alpr-1.0.0-linux_x86_64 "alpr_api.py"
|
||||||
|
@ -1,173 +1,58 @@
|
|||||||
#!/bin/bash
|
# clone sdk
|
||||||
|
mkdir ./tmp
|
||||||
|
cd tmp
|
||||||
|
wget https://github.com/DoubangoTelecom/ultimateALPR-SDK/archive/8130c76140fe8edc60fe20f875796121a8d22fed.zip -O temp-sdk.zip
|
||||||
|
unzip temp-sdk.zip
|
||||||
|
rm temp-sdk.zip
|
||||||
|
|
||||||
# Function to create virtual environment, install the wheel, and copy assets and libs
|
mkdir temp-sdk
|
||||||
install_and_setup() {
|
mv ultimateALPR-SDK*/* ./temp-sdk
|
||||||
echo "Creating virtual environment at the root..."
|
rm -R ultimateALPR-SDK*
|
||||||
python3.10 -m venv "$ROOT_DIR/venv" >/dev/null 2>&1
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
echo "Failed to create virtual environment."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Activating virtual environment..."
|
# create env to build ultimatealpr-sdk for python
|
||||||
source "$ROOT_DIR/venv/bin/activate"
|
python3.10 -m venv venv
|
||||||
|
source venv/bin/activate
|
||||||
|
pip install setuptools wheel Cython
|
||||||
|
|
||||||
echo "Installing the wheel..."
|
cd temp-sdk
|
||||||
pip install "$BUILD_DIR"/ultimateAlprSdk-*.whl >/dev/null 2>&1
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
echo "Failed to install the wheel."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Deactivating virtual environment..."
|
# move folders to simplify build
|
||||||
deactivate
|
mkdir -p binaries/linux/x86_64/c++
|
||||||
|
cp c++/* binaries/linux/x86_64/c++
|
||||||
|
cp python/* binaries/linux/x86_64/
|
||||||
|
|
||||||
echo "Copying assets and libs folders to the root directory..."
|
# edit setup.py to simplify build
|
||||||
cp -r "$BUILD_DIR/assets" "$ROOT_DIR"
|
cd binaries/linux/x86_64/
|
||||||
cp -r "$BUILD_DIR/libs" "$ROOT_DIR"
|
|
||||||
|
|
||||||
if [ -f "$ROOT_DIR/requirements.txt" ]; then
|
|
||||||
echo "Installing requirements..."
|
|
||||||
source "$ROOT_DIR/venv/bin/activate"
|
|
||||||
pip install -r "$ROOT_DIR/requirements.txt" >/dev/null 2>&1
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
echo "Failed to install requirements."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
deactivate
|
|
||||||
fi
|
|
||||||
|
|
||||||
rm -rf "$BUILD_DIR"
|
|
||||||
|
|
||||||
echo "Virtual environment created and wheel installed successfully."
|
|
||||||
echo "Assets and libs folders copied to the root directory."
|
|
||||||
|
|
||||||
echo "Setup completed."
|
|
||||||
}
|
|
||||||
|
|
||||||
# Function to prompt user for auto setup choice
|
|
||||||
prompt_auto_setup() {
|
|
||||||
read -r -p "Do you want to automatically create a new virtual environment, install the wheel and copy the assets and libs? (y/n): " choice
|
|
||||||
case "$choice" in
|
|
||||||
y|Y ) install_and_setup;;
|
|
||||||
n|N ) echo "Setup completed.";;
|
|
||||||
* ) echo "Invalid choice. Please run the script again and choose y or n.";;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
# Directories
|
|
||||||
ROOT_DIR=$(pwd)
|
|
||||||
BUILD_DIR="$ROOT_DIR/tmp-build-env"
|
|
||||||
SDK_ZIP_URL="https://github.com/DoubangoTelecom/ultimateALPR-SDK/archive/8130c76140fe8edc60fe20f875796121a8d22fed.zip"
|
|
||||||
SDK_ZIP="$BUILD_DIR/temp-sdk.zip"
|
|
||||||
SDK_DIR="$BUILD_DIR/temp-sdk"
|
|
||||||
BIN_DIR="$SDK_DIR/binaries/linux/x86_64"
|
|
||||||
|
|
||||||
# Create build environment
|
|
||||||
mkdir -p "$BUILD_DIR"
|
|
||||||
cd "$BUILD_DIR" || exit
|
|
||||||
|
|
||||||
# Clone SDK
|
|
||||||
echo "Downloading SDK..."
|
|
||||||
wget "$SDK_ZIP_URL" -O "$SDK_ZIP" >/dev/null 2>&1
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
echo "Failed to download SDK."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Unzipping SDK..."
|
|
||||||
unzip "$SDK_ZIP" >/dev/null 2>&1
|
|
||||||
rm "$SDK_ZIP"
|
|
||||||
mkdir "$SDK_DIR"
|
|
||||||
mv ultimateALPR-SDK*/* "$SDK_DIR"
|
|
||||||
rm -r ultimateALPR-SDK*
|
|
||||||
|
|
||||||
# Create environment to build ultimatealpr-sdk for Python
|
|
||||||
echo "Creating virtual environment for building SDK..."
|
|
||||||
python3.10 -m venv "$BUILD_DIR/venv" >/dev/null 2>&1
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
echo "Failed to create virtual environment."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Activating virtual environment..."
|
|
||||||
source "$BUILD_DIR/venv/bin/activate"
|
|
||||||
|
|
||||||
echo "Installing build dependencies..."
|
|
||||||
pip install setuptools wheel Cython >/dev/null 2>&1
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
echo "Failed to install build dependencies."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Move folders to simplify build
|
|
||||||
mkdir -p "$BIN_DIR/c++"
|
|
||||||
mv "$SDK_DIR/c++"/* "$BIN_DIR/c++"
|
|
||||||
mv "$SDK_DIR/python"/* "$BIN_DIR/"
|
|
||||||
|
|
||||||
# Edit setup.py to simplify build
|
|
||||||
echo "Editing setup.py for simplified build..."
|
|
||||||
cd "$BIN_DIR" || exit
|
|
||||||
sed -i "s|sources=\[os.path.abspath('../../../python/ultimateALPR-SDK-API-PUBLIC-SWIG_python.cxx')\]|sources=[os.path.abspath('ultimateALPR-SDK-API-PUBLIC-SWIG_python.cxx')]|g" setup.py
|
sed -i "s|sources=\[os.path.abspath('../../../python/ultimateALPR-SDK-API-PUBLIC-SWIG_python.cxx')\]|sources=[os.path.abspath('ultimateALPR-SDK-API-PUBLIC-SWIG_python.cxx')]|g" setup.py
|
||||||
sed -i "s|include_dirs=\['../../../c++'\]|include_dirs=['c++']|g" setup.py
|
sed -i "s|include_dirs=\['../../../c++'\]|include_dirs=['c++']|g" setup.py
|
||||||
sed -i "s|library_dirs=\['.'\]|library_dirs=['libs']|g" setup.py
|
sed -i "s|library_dirs=\['.'\]|library_dirs=['libs']|g" setup.py
|
||||||
|
|
||||||
# Move all .so files into libs folder
|
# move all .so files into libs folder
|
||||||
mkdir "$BIN_DIR/libs"
|
mkdir libs
|
||||||
mv "$BIN_DIR/"*.so* "$BIN_DIR/libs"
|
mv *.so libs/
|
||||||
|
mv *.so.* libs/
|
||||||
|
|
||||||
# Download TensorFlow
|
# build the wheel
|
||||||
read -r -p "Do you want TensorFlow for CPU or GPU? (cpu/gpu): " tf_choice
|
python setup.py bdist_wheel -v
|
||||||
mkdir -p "$BIN_DIR/tensorflow"
|
|
||||||
if [ "$tf_choice" == "gpu" ]; then
|
|
||||||
echo "Downloading TensorFlow GPU..."
|
|
||||||
wget https://storage.googleapis.com/tensorflow/libtensorflow/libtensorflow-gpu-linux-x86_64-2.6.0.tar.gz >/dev/null 2>&1
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
echo "Failed to download TensorFlow GPU."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
echo "Extracting TensorFlow GPU..."
|
|
||||||
tar -xf libtensorflow-gpu-linux-x86_64-2.6.0.tar.gz -C "$BIN_DIR/tensorflow" >/dev/null 2>&1
|
|
||||||
else
|
|
||||||
echo "Downloading TensorFlow CPU..."
|
|
||||||
wget https://storage.googleapis.com/tensorflow/libtensorflow/libtensorflow-cpu-linux-x86_64-2.6.0.tar.gz >/dev/null 2>&1
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
echo "Failed to download TensorFlow CPU."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
echo "Extracting TensorFlow CPU..."
|
|
||||||
tar -xf libtensorflow-cpu-linux-x86_64-2.6.0.tar.gz -C "$BIN_DIR/tensorflow" >/dev/null 2>&1
|
|
||||||
fi
|
|
||||||
|
|
||||||
mv "$BIN_DIR/tensorflow/lib/"* "$BIN_DIR/libs/"
|
# move the built whl and the libs back to root dir
|
||||||
cp "$BIN_DIR/libs/libtensorflow.so.2" "$BIN_DIR/libs/libtensorflow.so.1"
|
mv dist/* ../../../../
|
||||||
|
|
||||||
# Build the wheel
|
mv libs ../../../../
|
||||||
echo "Building the wheel..."
|
|
||||||
python "$BIN_DIR/setup.py" bdist_wheel -v >/dev/null 2>&1
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
echo "Failed to build the wheel."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Move the built wheel and the libs back to the root directory
|
# move the assets to root dir
|
||||||
mv "$BIN_DIR/dist/"*.whl "$BUILD_DIR"
|
cd ../../../
|
||||||
mv "$BIN_DIR/libs" "$BUILD_DIR"
|
mv assets ../assets
|
||||||
mv "$BIN_DIR/plugins.xml" "$BUILD_DIR/libs"
|
|
||||||
|
|
||||||
# Move the assets to the root directory
|
## install the whl
|
||||||
mv "$SDK_DIR/assets" "$BUILD_DIR/assets"
|
#cd ..
|
||||||
|
#pip install *.whl
|
||||||
|
#rm *.whl
|
||||||
|
|
||||||
# Deactivate and clean up the build virtual environment
|
cd ../
|
||||||
echo "Deactivating and cleaning up virtual environment..."
|
|
||||||
deactivate
|
|
||||||
cd "$ROOT_DIR" || exit
|
|
||||||
rm -rf "$BUILD_DIR/venv"
|
|
||||||
rm -rf "$SDK_DIR"
|
|
||||||
|
|
||||||
# Inform the user of the successful build
|
# remove sdk
|
||||||
echo "UltimateALPR SDK built and setup successfully."
|
rm -R temp-sdk
|
||||||
echo "You can now create a virtual environment, install the wheel and copy the assets and libs and start developing. Say 'y' to the next prompt to do this automatically (recommended)."
|
|
||||||
echo "Tip: Look at the assets folder as you might not need all the models depending on your platform/use case."
|
echo "UltimateALPR SDK built and setup successfully"
|
||||||
# Prompt user for auto setup choice
|
echo "You can now install the wheel using 'pip install ultimateAlprSdk-*.whl'"
|
||||||
prompt_auto_setup
|
|
20
plugins.xml
Normal file
20
plugins.xml
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<ie>
|
||||||
|
<plugins>
|
||||||
|
<plugin name="GNA" location="libGNAPlugin.so">
|
||||||
|
</plugin>
|
||||||
|
<plugin name="HETERO" location="libHeteroPlugin.so">
|
||||||
|
</plugin>
|
||||||
|
<plugin name="CPU" location="libMKLDNNPlugin.so">
|
||||||
|
</plugin>
|
||||||
|
<plugin name="MULTI" location="libMultiDevicePlugin.so">
|
||||||
|
</plugin>
|
||||||
|
<plugin name="GPU" location="libclDNNPlugin.so">
|
||||||
|
</plugin>
|
||||||
|
<plugin name="MYRIAD" location="libmyriadPlugin.so">
|
||||||
|
</plugin>
|
||||||
|
<plugin name="HDDL" location="libHDDLPlugin.so">
|
||||||
|
</plugin>
|
||||||
|
<plugin name="FPGA" location="libdliaPlugin.so">
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</ie>
|
@ -12,18 +12,18 @@
|
|||||||
background-color: #f0f2f5;
|
background-color: #f0f2f5;
|
||||||
background-image: radial-gradient(#7c7c7c 1px, rgba(0, 0, 0, 0) 1px);
|
background-image: radial-gradient(#7c7c7c 1px, rgba(0, 0, 0, 0) 1px);
|
||||||
background-size: 20px 20px;
|
background-size: 20px 20px;
|
||||||
font-family: 'Google Sans', sans-serif;
|
font-family: 'Google Sans', sans-serif; /* Apply Google Sans font to the entire page */
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body class="bg-neutral-100 dark:bg-neutral-900 dark:text-white flex items-center justify-center min-h-screen p-4">
|
<body class="bg-neutral-100 dark:bg-neutral-900 dark:text-white flex items-center justify-center h-screen">
|
||||||
<!-- Logo -->
|
<!-- Logo -->
|
||||||
<div class="absolute top-4 left-4 z-50">
|
<div class="absolute top-4 left-4">
|
||||||
<img id="logo" src="{{ url_for('static', filename='logo_black.webp') }}" alt="Logo" class="h-12 dark:hidden">
|
<img id="logo" src="{{ url_for('static', filename='logo_black.webp') }}" alt="Logo" class="h-12 dark:hidden">
|
||||||
<img id="logoDark" src="{{ url_for('static', filename='logo_white.webp') }}" alt="Logo" class="h-12 hidden dark:block">
|
<img id="logoDark" src="{{ url_for('static', filename='logo_white.webp') }}" alt="Logo" class="h-12 hidden dark:block">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="bg-white dark:bg-neutral-800 p-6 rounded-lg shadow-lg w-full max-w-md mt-16">
|
<div class="bg-white dark:bg-neutral-800 p-6 rounded-lg shadow-lg w-full max-w-md relative">
|
||||||
<h1 class="text-2xl font-bold mb-4 text-center dark:text-gray-200">Upload Image for ALPR</h1>
|
<h1 class="text-2xl font-bold mb-4 text-center dark:text-gray-200">Upload Image for ALPR</h1>
|
||||||
<form id="uploadForm" enctype="multipart/form-data" class="space-y-4">
|
<form id="uploadForm" enctype="multipart/form-data" class="space-y-4">
|
||||||
<div>
|
<div>
|
||||||
@ -43,7 +43,7 @@
|
|||||||
</form>
|
</form>
|
||||||
<div class="mt-6">
|
<div class="mt-6">
|
||||||
<h2 class="text-xl font-semibold mb-2 dark:text-gray-200">Response</h2>
|
<h2 class="text-xl font-semibold mb-2 dark:text-gray-200">Response</h2>
|
||||||
<pre id="responseBox" class="bg-neutral-100 dark:bg-neutral-900 p-4 border rounded-lg text-sm text-gray-900 dark:text-gray-200 overflow-x-auto"></pre>
|
<pre id="responseBox" class="bg-neutral-100 dark:bg-neutral-900 p-4 border rounded-lg text-sm text-gray-900 dark:text-gray-200"></pre>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -69,6 +69,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check for dark mode and switch logo accordingly
|
||||||
const prefersDarkScheme = window.matchMedia("(prefers-color-scheme: dark)");
|
const prefersDarkScheme = window.matchMedia("(prefers-color-scheme: dark)");
|
||||||
function toggleLogo() {
|
function toggleLogo() {
|
||||||
const logo = document.getElementById('logo');
|
const logo = document.getElementById('logo');
|
||||||
@ -82,7 +83,10 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Initial call to set logo based on dark mode preference
|
||||||
toggleLogo();
|
toggleLogo();
|
||||||
|
|
||||||
|
// Listen for changes in dark mode preference
|
||||||
prefersDarkScheme.addEventListener('change', toggleLogo);
|
prefersDarkScheme.addEventListener('change', toggleLogo);
|
||||||
|
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
|
Loading…
Reference in New Issue
Block a user