Skip to main content

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 SchemeView on IEEE Xplore


Features

  • One-call APIprotect_image() and protect_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 — expose logistic_map, generate_key, shuffle_pixels, encrypt_image for 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:

  1. XOR pass 1 — every pixel byte is XOR'd with a chaotic key generated by iterating the logistic map at r = 3.9 from the given seed.
  2. Pixel shuffle — all pixels are randomly permuted using a seed-reproducible permutation.
  3. 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

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

safelicensing-1.0.0.tar.gz (5.7 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

safelicensing-1.0.0-py3-none-any.whl (5.7 MB view details)

Uploaded Python 3

File details

Details for the file safelicensing-1.0.0.tar.gz.

File metadata

  • Download URL: safelicensing-1.0.0.tar.gz
  • Upload date:
  • Size: 5.7 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.5

File hashes

Hashes for safelicensing-1.0.0.tar.gz
Algorithm Hash digest
SHA256 090ac4f523a823a2d4ab47134fcae8330b4463d0e1a6d7bc1096310bce099178
MD5 2e00b99874f5cbc11439508adbc77daf
BLAKE2b-256 cea67a4be095f485ad7b23fc9ce907d0a4d96c4d1b570f2a9cb55bd832e36b57

See more details on using hashes here.

File details

Details for the file safelicensing-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: safelicensing-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 5.7 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.5

File hashes

Hashes for safelicensing-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ed175c553f0d0e84165251c804e267bdf1591d640c371677e019159bc80219a0
MD5 6e0d2c7f6e6b08c0ab19c43ac9ec5220
BLAKE2b-256 1cd30799543ecd61fe2af699d2e1efc7f3a79924771fffd32ae4a7c30556847e

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page