License plate detection and chaotic-map encryption for images and videos
Project description
SafeLicensing
License plate detection and chaotic-map encryption for images and videos.
Detect vehicle license plates with YOLOv8 and encrypt only the sensitive regions using a dual-pass chaotic XOR scheme, leaving the rest of the image or video completely intact.
Built on the research published at IEEE ECCE 2024:
Vehicle Number Plate Detection and Encryption in Digital Images Using YOLOv8 and Chaotic-Based Encryption Scheme - View on IEEE Xplore
Features
- One-call API:
protect_image()andprotect_video()handle detection and encryption end-to-end - Bundled model: 6 MB YOLOv8 weights ship with the package; no separate download needed
- Programmable low-level API: exposes
logistic_map,generate_key,shuffle_pixels,encrypt_imagefor research use - Streamlit UI: launch a full browser-based interface with a single command
- Video support: frame-by-frame plate detection and encryption with audio preservation
Installation
From PyPI
pip install safelicensing
From source
git clone https://github.com/FahimFBA/safelicensing-pypi.git
cd safelicensing-pypi
pip install -r requirements.txt
pip install -e .
Python 3.8+ required.
Quick Start
CLI - Streamlit web app
safelicensing
Opens a browser UI where you can upload images or videos, tune the encryption seed, and download protected output.
Protect an image
import safelicensing as sl
from PIL import Image
model = sl.load_model() # loads bundled best.pt
image = Image.open("car.jpg")
result = sl.protect_image(image, seed=0.42, model=model)
result.original.show() # original image
result.detected.show() # plates highlighted in red
result.encrypted.save("car_protected.jpg") # plates encrypted
print(f"Plates found : {len(result.bboxes)}")
print(f"Elapsed : {result.elapsed:.2f}s")
Protect a video
import safelicensing as sl
model = sl.load_model()
result = sl.protect_video(
"dashcam.mp4",
seed=0.42,
model=model,
output_path="dashcam_protected.mp4",
)
print(f"Output : {result.output_path}")
print(f"Frames : {result.frame_count}")
print(f"FPS : {result.fps:.2f}")
print(f"Elapsed : {result.elapsed:.2f}s")
API Reference
High-level
sl.protect_image(image, seed=0.5, model=None, model_path=None) -> ProtectImageResult
Detect and encrypt all license plates in a PIL image.
| Parameter | Type | Description |
|---|---|---|
image |
PIL.Image.Image |
Input image (any colour mode). |
seed |
float |
Encryption seed in (0.0, 1.0). Default 0.5. |
model |
YOLO instance | Pre-loaded model. Loads bundled model when None. |
model_path |
str |
Path to custom .pt weights. Ignored when model is given. |
Returns ProtectImageResult:
| Field | Type | Description |
|---|---|---|
original |
PIL.Image.Image |
Unmodified RGB input. |
detected |
PIL.Image.Image |
Input with red bounding boxes. |
encrypted |
PIL.Image.Image |
Plate regions encrypted. |
bboxes |
list[tuple] |
(x1, y1, x2, y2) per detected plate. |
elapsed |
float |
Processing time in seconds. |
sl.protect_video(video_path, seed=0.5, output_path=None, model=None, model_path=None, progress_callback=None) -> ProtectVideoResult
Detect and encrypt license plates in every frame of a video.
| Parameter | Type | Description |
|---|---|---|
video_path |
str |
Path to input video (mp4, avi, mov). |
seed |
float |
Encryption seed in (0.0, 1.0). Default 0.5. |
output_path |
str |
Output path. Defaults to <stem>_encrypted.mp4. |
model |
YOLO instance | Pre-loaded model. Loads bundled model when None. |
model_path |
str |
Custom weights path. Ignored when model is given. |
progress_callback |
callable |
Receives a float in [0.0, 1.0] per frame. |
Returns ProtectVideoResult:
| Field | Type | Description |
|---|---|---|
output_path |
str |
Absolute path to the encrypted video. |
frame_count |
int |
Total frames processed. |
fps |
float |
Output frame rate. |
elapsed |
float |
Processing time in seconds. |
sl.load_model(weights_path=None) -> YOLO
Load a YOLOv8 model. Uses the bundled best.pt when weights_path is None.
Mid-level
from safelicensing import detect_license_plates, encrypt_image
annotated, bboxes = detect_license_plates(model, pil_image)
encrypted_region = encrypt_image(np_array, seed=0.42)
Low-level (research)
from safelicensing.encryption import logistic_map, generate_key, shuffle_pixels
from safelicensing.detection import load_model, detect_license_plates
from safelicensing.video import process_video, create_video_from_frames
logistic_map(r, x) -> float
Single step of the logistic map: r * x * (1 - x).
generate_key(seed, n) -> np.ndarray
Generates a chaotic byte key of length n using the logistic map seeded at seed.
shuffle_pixels(img_array, seed) -> (np.ndarray, np.ndarray)
Shuffles pixels of a (H, W, C) uint8 array. Returns (shuffled, indices).
encrypt_image(img_array, seed) -> np.ndarray
Full two-layer encryption: XOR -> shuffle -> XOR. Returns encrypted array, same shape.
process_video(video_path, model, key_seed, progress_callback=None)
Frame-by-frame detection and encryption. Returns (frames, fps, (width, height)).
create_video_from_frames(frames, fps, output_path, audio_path=None) -> str
Encodes a list of RGB frames into a video file. Returns absolute output path.
Custom model
Bring your own YOLOv8 weights trained for license plate detection:
model = sl.load_model("path/to/my_model.pt")
result = sl.protect_image(image, seed=0.5, model=model)
Encryption details
The scheme applies two passes per region:
- XOR pass 1: every pixel byte is XOR'd with a chaotic key generated by iterating the logistic map at
r = 3.9from the given seed. - Pixel shuffle: all pixels are randomly permuted using a seed-reproducible permutation.
- XOR pass 2: the shuffled bytes are XOR'd with a second chaotic key derived from a perturbed seed (
min(seed * 1.1, 0.9999)).
The same seed always produces the same encrypted output, making the process deterministic and auditable.
Development setup
git clone https://github.com/FahimFBA/safelicensing-pypi.git
cd safelicensing-pypi
pip install -r requirements-dev.txt
pip install -e .
requirements-dev.txt includes all runtime dependencies plus pytest and pytest-cov.
Running tests
pytest # unit tests only (no model or video files needed)
pytest -m integration # also run integration tests
pytest --cov=safelicensing # with coverage report
Authors
Citation
If you use SafeLicensing in your research, please cite:
@inproceedings{amin2024safelicensing,
title = {Vehicle Number Plate Detection and Encryption in Digital Images
Using YOLOv8 and Chaotic-Based Encryption Scheme},
author = {Amin, Md. Fahim Bin and Khan, Israt Jahan},
booktitle = {2024 International Conference on Electrical, Computer and
Communication Engineering (ECCE)},
year = {2024},
publisher = {IEEE},
url = {https://ieeexplore.ieee.org/abstract/document/10534375/}
}
License
Apache License 2.0 - see LICENSE for details.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file safelicensing-1.0.1.tar.gz.
File metadata
- Download URL: safelicensing-1.0.1.tar.gz
- Upload date:
- Size: 5.7 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
287fc0ec87d9ae19ad0055a7b0160ffa1b53d02664d1085e39f32fe3eac44087
|
|
| MD5 |
104dd0dbcd09d9c484a5c072b832e35e
|
|
| BLAKE2b-256 |
6646c30dfc4f01f96a8e58face176ccf1eb47f2bd3435af528721602d8257a1c
|
Provenance
The following attestation bundles were made for safelicensing-1.0.1.tar.gz:
Publisher:
publish.yml on FahimFBA/safelicensing-pypi
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
safelicensing-1.0.1.tar.gz -
Subject digest:
287fc0ec87d9ae19ad0055a7b0160ffa1b53d02664d1085e39f32fe3eac44087 - Sigstore transparency entry: 1711275452
- Sigstore integration time:
-
Permalink:
FahimFBA/safelicensing-pypi@342b1bbbe6531d02311c22297ccda0a8eaad9cc3 -
Branch / Tag:
refs/tags/v1.0.1 - Owner: https://github.com/FahimFBA
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@342b1bbbe6531d02311c22297ccda0a8eaad9cc3 -
Trigger Event:
release
-
Statement type:
File details
Details for the file safelicensing-1.0.1-py3-none-any.whl.
File metadata
- Download URL: safelicensing-1.0.1-py3-none-any.whl
- Upload date:
- Size: 5.7 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8a5f6df4e13ae826ea54e856cc444bd53073e872d31470b53d297f421faa3cf5
|
|
| MD5 |
0cb1a5896159bbc7a28323b2242d41e2
|
|
| BLAKE2b-256 |
2e83540396bb531035a0bcf2bdf5ab207af77360c2afa098b7450548e40dcbae
|
Provenance
The following attestation bundles were made for safelicensing-1.0.1-py3-none-any.whl:
Publisher:
publish.yml on FahimFBA/safelicensing-pypi
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
safelicensing-1.0.1-py3-none-any.whl -
Subject digest:
8a5f6df4e13ae826ea54e856cc444bd53073e872d31470b53d297f421faa3cf5 - Sigstore transparency entry: 1711275663
- Sigstore integration time:
-
Permalink:
FahimFBA/safelicensing-pypi@342b1bbbe6531d02311c22297ccda0a8eaad9cc3 -
Branch / Tag:
refs/tags/v1.0.1 - Owner: https://github.com/FahimFBA
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@342b1bbbe6531d02311c22297ccda0a8eaad9cc3 -
Trigger Event:
release
-
Statement type: