MareArts ANPR V14 Models - Complete Performance Guide & Benchmarks


⚡ MareArts ANPR V14 Models - Performance, Metrics & How to Choose

Choosing the right ANPR model is crucial for your application. Too heavy? Slow performance. Too light? Lower accuracy. In this comprehensive guide, we'll break down all MareArts ANPR V14 models with real benchmarks to help you make the perfect choice.

🎯 Two-Stage Pipeline Architecture

MareArts ANPR uses a two-stage pipeline:

  1. Detector - Finds license plates in images (Where is the plate?)
  2. OCR - Reads text from detected plates (What does it say?)

You can mix and match models from each stage to optimize for your specific needs!

πŸ“Š Detector Models - Find License Plates

Model Sizes Explained

Size Parameters Speed Accuracy Best For
pico Smallest Fast Good (96-98%) Mobile, Edge devices
micro Small Very Fast Excellent (97-99%) πŸ† Best overall
small Medium Fastest Excellent (98-99%) High-speed applications
medium Large Fast Excellent (98-99%) Balanced
large Largest Moderate Highest (99%+) Maximum accuracy

Resolution Options

  • 320p models (320×320) - 2× faster, 96-98% detection
  • 640p models (640×640) - Highest accuracy, 98-99% detection

Precision Options

  • FP32 - Fastest on GPU (2× faster than FP16), standard size
  • FP16 - 50% smaller file size, same accuracy, slower inference

Complete Detector Performance Table

Model Name Detection Rate Speed (GPU) Size Recommendation
micro_320p_fp32 97.13% 128 FPS (7.8ms) 83 MB πŸ† Best overall
micro_320p_fp16 97.13% 56 FPS (17.9ms) 42 MB πŸ† Best mobile
small_320p_fp32 98.00% 142 FPS (7.0ms) 114 MB ⚡ Fastest
medium_320p_fp32 98.06% 136 FPS (7.4ms) 153 MB High detection
large_320p_fp32 98.40% 131 FPS (7.6ms) 164 MB Strong performance
pico_320p_fp32 96.02% 129 FPS (7.8ms) 75 MB πŸ“± Smallest + fast
pico_640p_fp32 98.54% 66 FPS (15.2ms) 75 MB Balanced
small_640p_fp32 99.15% 70 FPS (14.3ms) 114 MB High detection
medium_640p_fp32 99.21% 66 FPS (15.1ms) 153 MB Very high
large_640p_fp32 99.31% 60 FPS (16.7ms) 164 MB 🎯 Highest accuracy

Key Findings:

  • ✅ 320p models: 2× faster than 640p (96-98% accuracy)
  • ✅ 640p models: Highest accuracy (98-99%) for difficult cases
  • ✅ FP16 models: 50% smaller, same accuracy, ~50% slower
  • ✅ Recommended: micro_320p_fp32 (best speed/accuracy balance)

πŸ“– OCR Models - Read License Plate Text

Two Key Metrics

  • Exact Match - Entire plate number is 100% correct
  • Character Accuracy - Percentage of individual characters correct

Example: Actual plate: "ABC-1234"

  • OCR reads "ABC-1234" → ✅ Exact Match = Yes, Char Accuracy = 100%
  • OCR reads "ABC-1235" → ❌ Exact Match = No, Char Accuracy = 87.5% (7/8 correct)

Complete OCR Performance by Region

🌍 Universal (univ) - All Regions
Model Exact Match Char Accuracy FPS Size
pico_fp32 97.48% 98.87% 264 20 MB
micro_fp32 97.54% 98.86% 260 71 MB
small_fp32 97.51% 98.85% 291 112 MB
medium_fp32 97.57% 98.89% 245 164 MB
large_fp32 97.75% 98.91% 253 179 MB
πŸ‡°πŸ‡· Korean (kr) - Best Overall Accuracy
Model Exact Match Char Accuracy FPS
pico_fp32 98.99% 99.77% 272
micro_fp32 99.21% 99.80% 250
small_fp32 99.19% 99.80% 295
medium_fp32 99.21% 99.80% 267
large_fp32 99.27% 99.82% 265
πŸ‡ͺπŸ‡Ί Europe+ (eup) - EU + Additional Countries
Model Exact Match Char Accuracy FPS
pico_fp32 94.98% 97.39% 280
micro_fp32 95.07% 97.46% 266
small_fp32 94.98% 97.43% 304
medium_fp32 95.03% 97.46% 278
large_fp32 95.32% 97.54% 260
πŸ‡ΊπŸ‡Έ North America (na) - USA, Canada, Mexico
Model Exact Match Char Accuracy FPS
pico_fp32 71.21% 88.43% 268
micro_fp32 71.21% 87.67% 269
small_fp32 69.70% 88.27% 311
medium_fp32 63.64% 87.24% 284
large_fp32 69.70% 86.25% 271
πŸ‡¨πŸ‡³ China (cn)
Model Exact Match Char Accuracy FPS
pico_fp32 96.24% 98.82% 268
micro_fp32 96.30% 98.74% 265
small_fp32 96.36% 98.88% 301
medium_fp32 96.36% 98.89% 276
large_fp32 96.49% 98.87% 262

OCR Model Averages (All Regions)

Model Avg Exact Match Avg Char Accuracy Avg FPS Size
small_fp32 91.54% 96.64% 300 FPS 112 MB
pico_fp32 91.78% 96.65% 270 FPS 20 MB
micro_fp32 91.86% 96.50% 262 FPS 71 MB
medium_fp32 90.36% 96.45% 270 FPS 164 MB
large_fp32 91.70% 96.27% 262 FPS 179 MB

🌍 Regional Vocabulary Support

Region Code Coverage Character Sets
Universal univ All regions (default) All character sets
Korea kr South Korea Hangul + Latin + Digits
Europe+ eup EU + UK, Switzerland, Norway Latin + Cyrillic + Special
North America na USA, Canada, Mexico Latin + Digits
China cn China Chinese + Latin + Digits

Pro Tip: Always use specific regions for best accuracy. Only use univ when the region is unknown!

🎯 How to Choose the Right Models

Use Case 1: Parking Management

Requirements: Good accuracy, real-time performance, cost-effective

# Recommended Configuration
detector = ma_anpr_detector_v14(
    "micro_320p_fp32",  # 97% detection, 128 FPS
    user, key, sig,
    backend="cuda",
    conf_thres=0.25
)

ocr = ma_anpr_ocr_v14(
    "small_fp32",       # 95%+ exact match, 300 FPS
    "eup",              # Specific region
    user, key, sig
)

Why: Excellent balance of speed and accuracy. Handles 90%+ of plates easily.

Use Case 2: Security Checkpoint (Critical)

Requirements: Maximum accuracy, can't miss plates

# Recommended Configuration
detector = ma_anpr_detector_v14(
    "large_640p_fp32",  # 99.31% detection (highest!)
    user, key, sig,
    backend="cuda",
    conf_thres=0.20     # Lower threshold for more detections
)

ocr = ma_anpr_ocr_v14(
    "large_fp32",       # 95%+ exact match, best accuracy
    "kr",               # Specific region for your area
    user, key, sig
)

Why: Maximum detection and recognition accuracy. No compromises.

Use Case 3: Traffic Monitoring (High Volume)

Requirements: Maximum speed, process many cameras

# Recommended Configuration
detector = ma_anpr_detector_v14(
    "small_320p_fp32",  # 98% detection, 142 FPS (fastest!)
    user, key, sig,
    backend="cuda",
    conf_thres=0.25
)

ocr = ma_anpr_ocr_v14(
    "small_fp32",       # 300 FPS (fastest OCR!)
    "univ",             # Universal for mixed traffic
    user, key, sig
)

Why: Fastest processing for high-volume applications. Can handle multiple streams.

Use Case 4: Mobile/Edge Device

Requirements: Small size, low power, on-device processing

# Recommended Configuration
detector = ma_anpr_detector_v14(
    "micro_320p_fp16",  # 97% detection, 42 MB (50% smaller!)
    user, key, sig,
    backend="cpu",      # CPU for mobile
    conf_thres=0.25
)

ocr = ma_anpr_ocr_v14(
    "pico_fp32",        # 20 MB, 270 FPS
    "kr",               # Specific region
    user, key, sig
)

Why: Smallest models, excellent for mobile/edge. Total size: 62 MB.

Use Case 5: Law Enforcement (Difficult Conditions)

Requirements: Works in poor lighting, angles, damaged plates

# Recommended Configuration
detector = ma_anpr_detector_v14(
    "medium_640p_fp32", # 99.21% detection
    user, key, sig,
    backend="cuda",
    conf_thres=0.15     # Very low threshold for difficult cases
)

ocr = ma_anpr_ocr_v14(
    "large_fp32",       # Best OCR accuracy
    "na",               # Specific region
    user, key, sig
)

Why: Handles difficult conditions better. Lower threshold catches more plates.

πŸ“ˆ Performance Comparison Chart

Detector Models: Speed vs Accuracy

Category Fastest Balanced Most Accurate
320p small_320p_fp32
142 FPS, 98.00%
micro_320p_fp32
128 FPS, 97.13%
large_320p_fp32
131 FPS, 98.40%
640p small_640p_fp32
70 FPS, 99.15%
medium_640p_fp32
66 FPS, 99.21%
large_640p_fp32
60 FPS, 99.31%
Mobile pico_320p_fp16
50+ FPS, 37 MB
micro_320p_fp16
56 FPS, 42 MB
small_320p_fp16
70+ FPS, 57 MB

OCR Models: Speed vs Accuracy

Priority Smallest Fastest Most Accurate
Choice pico_fp32
20 MB, 270 FPS
91.78% exact
small_fp32
112 MB, 300 FPS
91.54% exact
large_fp32
179 MB, 262 FPS
91.70% exact

πŸ’‘ Performance Tips

1. GPU Acceleration is Essential

# CPU: ~1-2 FPS (slow!)
detector = ma_anpr_detector_v14(..., backend="cpu")

# CUDA (NVIDIA GPU): ~100+ FPS (fast!)
detector = ma_anpr_detector_v14(..., backend="cuda")

# DirectML (Windows GPU): ~50+ FPS
detector = ma_anpr_detector_v14(..., backend="directml")

Result: GPU is 50-100× faster than CPU!

2. Use Batch Processing

# Slow: Process one by one
for img in images:
    text, conf = ocr.predict(img)

# Fast: Process in batch (3-5× faster!)
results = ocr.predict(images)  # Pass list

3. Choose Resolution Wisely

  • 320p: Good quality images, controlled environment → Use 320p (2× faster)
  • 640p: Poor lighting, far distance, damaged plates → Use 640p (higher accuracy)

4. Tune Confidence Thresholds

# High precision (fewer false positives)
detector = ma_anpr_detector_v14(..., conf_thres=0.50)

# Balanced (recommended)
detector = ma_anpr_detector_v14(..., conf_thres=0.25)

# High recall (catch more plates, more false positives)
detector = ma_anpr_detector_v14(..., conf_thres=0.15)

5. Use Specific Regions

# ❌ Less accurate (universal)
ocr = ma_anpr_ocr_v14("small_fp32", "univ", ...)  # ~92% exact match

# ✅ More accurate (specific region)
ocr = ma_anpr_ocr_v14("small_fp32", "kr", ...)    # ~99% exact match!

πŸš€ Quick Decision Guide

Your Priority Detector OCR
Best Overall micro_320p_fp32 small_fp32
Fastest small_320p_fp32 small_fp32
Most Accurate large_640p_fp32 large_fp32
Smallest pico_320p_fp16 pico_fp32
Mobile micro_320p_fp16 pico_fp32
Balanced medium_320p_fp32 medium_fp32

πŸ“Š Benchmark Environment

  • GPU: NVIDIA RTX 3060 (CUDA 11.8)
  • CPU: Intel Core i7
  • Dataset: Real-world license plate images
  • Test Size: 1000+ images per region
  • Updated: December 2025

πŸŽ“ Key Takeaways

  • ✅ Two-stage pipeline: Detector → OCR
  • ✅ Mix and match models for your needs
  • ✅ 320p models: 2× faster, excellent for most uses
  • ✅ 640p models: Highest accuracy for difficult cases
  • ✅ GPU acceleration: 50-100× faster than CPU
  • ✅ Specific regions: Much better accuracy than universal
  • ✅ Batch processing: 3-5× faster for multiple images
  • ✅ Best overall: micro_320p_fp32 + small_fp32

πŸ’» Example Configuration

from marearts_anpr import ma_anpr_detector_v14, ma_anpr_ocr_v14
from marearts_anpr import marearts_anpr_from_image_file

# Initialize models (one time)
detector = ma_anpr_detector_v14(
    "micro_320p_fp32",      # 97% detection, 128 FPS
    user_name, serial_key, signature,
    backend="cuda",          # GPU acceleration
    conf_thres=0.25          # Balanced threshold
)

ocr = ma_anpr_ocr_v14(
    "small_fp32",            # 95%+ accuracy, 300 FPS
    "eup",                   # Specific region for best accuracy
    user_name, serial_key, signature
)

# Process image
result = marearts_anpr_from_image_file(detector, ocr, "plate.jpg")
print(result)

# Output:
# {
#   "results": [
#     {
#       "ocr": "AB-123-CD",
#       "ocr_conf": 98.5,
#       "ltrb": [120, 230, 380, 290],
#       "ltrb_conf": 95
#     }
#   ],
#   "ltrb_proc_sec": 0.008,  # Detection time
#   "ocr_proc_sec": 0.003     # OCR time
# }

πŸ”— Resources

  • πŸ“Š Full Benchmarks: See detailed results in GitHub docs
  • πŸ“š Model Guide: Complete model documentation
  • πŸ§ͺ Try Free: ma-anpr test-api image.jpg
  • πŸ›’ Get License: MareArts ANPR

🎯 Conclusion

MareArts ANPR V14 offers 11 detector models and 5 OCR models, giving you 55+ possible combinations! The right choice depends on your specific requirements:

  • Speed-critical? → small_320p_fp32 + small_fp32
  • Accuracy-critical? → large_640p_fp32 + large_fp32
  • Balanced? → micro_320p_fp32 + small_fp32 (recommended!)
  • Mobile? → micro_320p_fp16 + pico_fp32

Start with the recommended configuration and tune based on your results. Happy optimizing! ⚡πŸš—


Labels: ANPR, MachineLearning, ComputerVision, Performance, Benchmarks, Models, Metrics, DeepLearning, Optimization, GPU

FREE ANPR/ALPR/LPR API - Try Before You Buy (1000 Requests/Day)


🎁 FREE License Plate Recognition API - No Credit Card Required!

Want to try ANPR (Automatic Number Plate Recognition) / ALPR (Automatic License Plate Recognition) / LPR (License Plate Recognition) without buying a license? We offer a completely FREE test API with 1000 requests per day!

✨ What You Get (FREE!)

  • ✅ 1000 requests/day - Perfect for testing and evaluation
  • ✅ No credit card required
  • ✅ No registration needed
  • ✅ 5 regions supported: Korea, Europe, USA/Canada, China, Universal
  • ✅ Multiple models to test (pico to large)
  • ✅ Works instantly - just install and run!

πŸš€ Quick Start (30 Seconds)

# Install
pip install marearts-anpr

# Test immediately (NO CONFIG NEEDED!)
ma-anpr test-api your-plate.jpg --region eup

# That's it! πŸŽ‰

🌍 Supported Regions

Region Code Coverage Example
kr South Korea 123κ°€4567
eup Europe (EU standards) AB-123-CD
na USA, Canada, Mexico ABC-1234
cn China δΊ¬A·12345
univ Universal (all) Any format

πŸ’» Usage Examples

Command Line (Easiest!)

# European plates
ma-anpr test-api eu-plate.jpg --region eup

# Korean plates
ma-anpr test-api kr-plate.jpg --region kr

# US plates
ma-anpr test-api us-plate.jpg --region na

# Chinese plates
ma-anpr test-api cn-plate.jpg --region cn

# Unknown region? Use universal
ma-anpr test-api unknown-plate.jpg --region univ

Python Script

#!/usr/bin/env python3
import subprocess

def test_free_anpr(image_path, region='eup'):
    """Test free ANPR API - no credentials needed!"""
    
    cmd = f'ma-anpr test-api "{image_path}" --region {region}'
    result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
    
    if result.returncode == 0:
        print(result.stdout)
        return True
    else:
        print(f"Error: {result.stderr}")
        return False

# Test European plate
test_free_anpr("plate.jpg", "eup")

# Test Korean plate
test_free_anpr("plate2.jpg", "kr")

Test Multiple Regions

# Test same image with different regions
for region in eup kr na cn univ; do
    echo "Testing $region..."
    ma-anpr test-api plate.jpg --region $region
done

🎯 Advanced Options

Try Different Models

# List all available models
ma-anpr test-api --list-models

# Try different detector models
ma-anpr test-api plate.jpg --region eup --detector small_640p_fp32
ma-anpr test-api plate.jpg --region eup --detector medium_640p_fp32
ma-anpr test-api plate.jpg --region eup --detector large_640p_fp32

# Try different OCR models
ma-anpr test-api plate.jpg --region eup --ocr small_fp32
ma-anpr test-api plate.jpg --region eup --ocr medium_fp32
ma-anpr test-api plate.jpg --region eup --ocr large_fp32

Batch Testing

# Test all images in a folder
for img in ./plates/*.jpg; do
    echo "Processing $img..."
    ma-anpr test-api "$img" --region eup
done

πŸ“Š Sample Output

{
  "results": [
    {
      "ocr": "AB-123-CD",
      "ocr_conf": 98.5,
      "ltrb": [120, 230, 380, 290],
      "ltrb_conf": 95
    }
  ],
  "ltrb_proc_sec": 0.15,
  "ocr_proc_sec": 0.03,
  "status": "success"
}

πŸ†“ FREE vs PAID Comparison

Feature FREE Test API Paid License
Requests/Day 1000 Unlimited
Speed ~0.5s (cloud) ~0.02s (local GPU)
Internet Required Yes No (offline OK)
Configuration None One-time setup
Regions All 5 All 5
Models All All
Price $0 Contact sales

πŸŽ“ Use Cases for Free API

  • ✅ Evaluation: Try before buying a license
  • ✅ Prototyping: Build POC applications
  • ✅ Testing: Test accuracy on your specific plates
  • ✅ Education: Learn ANPR/ALPR/LPR technology
  • ✅ Small Projects: Personal projects under 1000/day
  • ✅ Region Testing: Find which region works best
  • ✅ Model Comparison: Compare different model sizes

πŸ“ˆ When to Upgrade to Paid License?

Consider upgrading when you need:

  • πŸš€ Unlimited requests (no daily limit)
  • ⚡ 10-100x faster processing (local GPU)
  • πŸ”’ Offline operation (no internet needed)
  • 🏒 Commercial deployment
  • πŸ“Ή Real-time video processing
  • 🎯 High-volume applications (>1000/day)

πŸ’‘ Pro Tips

# 1. Use specific regions for best accuracy
ma-anpr test-api plate.jpg --region eup  # ✅ Better
ma-anpr test-api plate.jpg --region univ # ⚠️ OK but less accurate

# 2. Test different models to find best speed/accuracy balance
ma-anpr test-api plate.jpg --region eup --detector small_640p_fp32   # Faster
ma-anpr test-api plate.jpg --region eup --detector large_640p_fp32   # More accurate

# 3. Check remaining quota
ma-anpr test-api --check-quota

# 4. Get help
ma-anpr test-api --help

# 5. See all options
ma-anpr test-api --list-models

πŸ” Troubleshooting

Rate limit exceeded?

# Wait until midnight UTC (resets daily)
# OR upgrade to paid license for unlimited requests

No plates detected?

# Try different detector models
ma-anpr test-api plate.jpg --region eup --detector large_640p_fp32

# Try universal region
ma-anpr test-api plate.jpg --region univ

Wrong text recognized?

# Make sure you're using correct region!
ma-anpr test-api plate.jpg --region kr   # For Korean plates
ma-anpr test-api plate.jpg --region eup  # For European plates

# Try larger OCR model
ma-anpr test-api plate.jpg --region eup --ocr large_fp32

πŸ“– Complete Example Script

#!/usr/bin/env python3
"""
Free ANPR Test Script
Test license plate recognition with different regions and models
"""
import subprocess
import json

def test_anpr_free(image_path, region='eup', detector='medium_640p_fp32', ocr='medium_fp32'):
    """Test free ANPR API"""
    
    cmd = [
        'ma-anpr', 'test-api', image_path,
        '--region', region,
        '--detector', detector,
        '--ocr', ocr
    ]
    
    result = subprocess.run(cmd, capture_output=True, text=True)
    
    if result.returncode == 0:
        try:
            data = json.loads(result.stdout)
            return data
        except:
            return result.stdout
    else:
        return {"error": result.stderr}

# Test European plate with different models
image = "eu-plate.jpg"

print("Testing different detector models...")
for detector in ['small_640p_fp32', 'medium_640p_fp32', 'large_640p_fp32']:
    result = test_anpr_free(image, 'eup', detector)
    print(f"{detector}: {result}")

print("\nTesting different regions...")
for region in ['eup', 'kr', 'na', 'univ']:
    result = test_anpr_free(image, region)
    print(f"{region}: {result}")

🎯 Real-World Example

# Parking lot monitoring (Europe)
ma-anpr test-api parking-cam.jpg --region eup

# Toll booth (USA)
ma-anpr test-api toll-booth.jpg --region na

# Security gate (Korea)
ma-anpr test-api security-cam.jpg --region kr

# Traffic enforcement (China)
ma-anpr test-api traffic.jpg --region cn

# Multi-national (airport parking)
ma-anpr test-api airport.jpg --region univ

🌟 Why Choose MareArts ANPR?

  • ✅ FREE tier available - Try before you buy!
  • ✅ State-of-the-art AI - Latest deep learning models
  • ✅ Multi-region support - Works worldwide
  • ✅ Fast processing - ~0.02s with GPU
  • ✅ Easy integration - Python, HTTP API, CLI
  • ✅ Regular updates - New models and features
  • ✅ Commercial ready - Production-grade quality

πŸš€ Get Started Now!

# Install (takes 10 seconds)
pip install marearts-anpr

# Test (takes 20 seconds)
ma-anpr test-api your-plate.jpg --region eup

# Celebrate! πŸŽ‰
# You just recognized your first license plate!

πŸ“ž Need More?

πŸ’¬ What People Are Saying

"Finally, an ANPR API I can test without entering my credit card!" - Developer

"1000 requests/day is perfect for my small parking lot project." - Small Business Owner

"Tested all 5 regions before buying. Confident in my purchase!" - System Integrator

🎁 Summary

MareArts ANPR offers a completely FREE test API with 1000 requests per day. No credit card, no registration, no strings attached. Just install and start recognizing license plates!

  • ✅ Install: pip install marearts-anpr
  • ✅ Test: ma-anpr test-api plate.jpg --region eup
  • ✅ Evaluate: Try all regions and models
  • ✅ Upgrade: When ready for unlimited use

Start your ANPR/ALPR/LPR journey today - completely FREE! πŸš—πŸ“Έ



MareArts ANPR V14 - Advanced Manual Processing & Performance Tuning

 

⚡ MareArts ANPR V14 - Advanced Manual Processing

Ready to take control? In this advanced guide, I'll show you how to manually process detections, measure performance, and optimize for your specific use case.

🎯 Why Manual Processing?

  • Full control over detection pipeline
  • Custom filtering and post-processing
  • Performance measurement and optimization
  • Integration with existing computer vision pipelines
  • Custom confidence thresholds per stage

πŸ”§ Manual Detection & OCR Pipeline

from marearts_anpr import ma_anpr_detector_v14, ma_anpr_ocr_v14
import cv2
from PIL import Image
import time

# Initialize models
detector = ma_anpr_detector_v14(
    "medium_640p_fp32",
    user_name, serial_key, signature,
    backend="cpu",
    conf_thres=0.25,
    iou_thres=0.5
)

ocr = ma_anpr_ocr_v14("medium_fp32", "eup", user_name, serial_key, signature)

# Load image
img = cv2.imread("plate.jpg")

# Step 1: Detect license plates
start = time.time()
detections = detector.detector(img)
detection_time = time.time() - start

print(f"Detection time: {detection_time:.4f}s")
print(f"Found {len(detections)} plate(s)")

# Step 2: Process each detection
results = []
ocr_time = 0

for i, box_info in enumerate(detections):
    # Get bounding box
    bbox = box_info['bbox']  # [x1, y1, x2, y2]
    score = box_info['score']  # Detection confidence
    
    # Crop plate region
    x1, y1, x2, y2 = int(bbox[0]), int(bbox[1]), int(bbox[2]), int(bbox[3])
    crop = img[y1:y2, x1:x2]
    
    if crop.size == 0:
        continue
    
    # Convert to PIL for OCR
    pil_img = Image.fromarray(crop)
    if pil_img.mode != "RGB":
        pil_img = pil_img.convert("RGB")
    
    # Run OCR
    start = time.time()
    text, confidence = ocr.predict(pil_img)
    elapsed = time.time() - start
    ocr_time += elapsed
    
    print(f"Plate {i+1}: {text} ({confidence}%) - {elapsed:.4f}s")
    
    results.append({
        "ocr": text,
        "ocr_conf": confidence,
        "bbox": [x1, y1, x2, y2],
        "det_conf": int(score * 100)
    })

print(f"\nTotal time: {detection_time + ocr_time:.4f}s")

πŸ“Š Detection Object Structure

# detector.detector(img) returns list of dictionaries:
[
    {
        'bbox': [x1, y1, x2, y2],  # Bounding box coordinates
        'score': 0.95,              # Detection confidence (0-1)
        'class': 'license_plate'    # Object class
    },
    ...
]

# ocr.predict(pil_image) returns tuple:
("ABC1234", 98.5)  # (text, confidence_percentage)

πŸš€ Backend Performance Comparison

backends = ["cpu", "cuda"]  # Add "directml" on Windows

for backend_name in backends:
    try:
        print(f"\nπŸ”§ Testing {backend_name}...")
        
        # Initialize with specific backend
        test_detector = ma_anpr_detector_v14(
            "medium_640p_fp32",
            user_name, serial_key, signature,
            backend=backend_name,
            conf_thres=0.25
        )
        
        # Measure performance
        start = time.time()
        detections = test_detector.detector(img)
        elapsed = time.time() - start
        
        print(f"Detected {len(detections)} plates in {elapsed:.4f}s")
        print(f"Speed: {1/elapsed:.1f} FPS")
        
    except Exception as e:
        print(f"⚠️ {backend_name} not available: {e}")

⚙️ Performance Results (Typical)

Backend Detection OCR Total FPS
CPU (i7) ~0.15s ~0.03s ~0.18s ~5.5
CUDA (RTX 3060) ~0.008s ~0.002s ~0.01s ~100

Result: GPU acceleration = 18x faster! πŸš€

πŸŽ›️ Custom Filtering

# Filter detections by confidence
min_detection_conf = 0.50
min_ocr_conf = 80.0

filtered_results = []

for box_info in detections:
    if box_info['score'] < min_detection_conf:
        continue  # Skip low confidence detections
    
    # Process with OCR...
    text, conf = ocr.predict(plate_crop)
    
    if conf < min_ocr_conf:
        continue  # Skip low confidence OCR
    
    filtered_results.append({
        "text": text,
        "confidence": conf,
        "bbox": bbox
    })

print(f"After filtering: {len(filtered_results)} high-confidence plates")

🎨 Custom Visualization

import cv2

# Draw boxes and text on image
for result in results:
    x1, y1, x2, y2 = result['bbox']
    text = result['ocr']
    conf = result['ocr_conf']
    
    # Draw rectangle
    cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2)
    
    # Draw text
    label = f"{text} ({conf}%)"
    cv2.putText(img, label, (x1, y1-10), 
                cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)

cv2.imwrite("result.jpg", img)

πŸ“Ή Video Processing Pipeline

import cv2

# Open video
cap = cv2.VideoCapture("traffic.mp4")

frame_count = 0
plate_history = {}

while cap.isOpened():
    ret, frame = cap.read()
    if not ret:
        break
    
    frame_count += 1
    
    # Process every N frames (skip frames for speed)
    if frame_count % 5 != 0:
        continue
    
    # Detect plates
    detections = detector.detector(frame)
    
    for det in detections:
        bbox = det['bbox']
        x1, y1, x2, y2 = int(bbox[0]), int(bbox[1]), int(bbox[2]), int(bbox[3])
        crop = frame[y1:y2, x1:x2]
        
        if crop.size == 0:
            continue
        
        # OCR
        pil_crop = Image.fromarray(cv2.cvtColor(crop, cv2.COLOR_BGR2RGB))
        text, conf = ocr.predict(pil_crop)
        
        # Track plates (simple tracking by position)
        plate_id = f"{x1//50}_{y1//50}"
        
        if plate_id not in plate_history:
            plate_history[plate_id] = []
        plate_history[plate_id].append(text)
        
        # Draw
        cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2)
        cv2.putText(frame, text, (x1, y1-10), 
                    cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
    
    cv2.imshow('ANPR', frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()

# Print detected plates
print("\nDetected plates:")
for plate_id, texts in plate_history.items():
    # Most common text for this plate
    most_common = max(set(texts), key=texts.count)
    print(f"  {most_common} (seen {len(texts)} times)")

πŸ’Ύ Batch Processing from Directory

import os
from pathlib import Path

image_dir = Path("./images")
results_all = {}

for img_path in image_dir.glob("*.jpg"):
    print(f"Processing {img_path.name}...")
    
    img = cv2.imread(str(img_path))
    detections = detector.detector(img)
    
    plates = []
    for det in detections:
        bbox = det['bbox']
        x1, y1, x2, y2 = int(bbox[0]), int(bbox[1]), int(bbox[2]), int(bbox[3])
        crop = img[y1:y2, x1:x2]
        
        if crop.size > 0:
            pil_crop = Image.fromarray(cv2.cvtColor(crop, cv2.COLOR_BGR2RGB))
            text, conf = ocr.predict(pil_crop)
            plates.append({"text": text, "conf": conf})
    
    results_all[img_path.name] = plates

# Save results
import json
with open("results.json", "w") as f:
    json.dump(results_all, f, indent=2)

print(f"\nProcessed {len(results_all)} images")

πŸŽ“ Advanced Tips

  • GPU Memory: Use cuda backend for 10-100x speedup
  • Confidence Tuning: Lower conf_thres to 0.15-0.20 for difficult images
  • IOU Threshold: Increase iou_thres to reduce duplicate detections
  • Batch Processing: Process multiple crops at once with ocr.predict([img1, img2, ...])
  • Frame Skipping: Process every Nth frame in videos for speed
  • Multi-threading: Run detector and OCR in separate threads

πŸ” Troubleshooting

No detections?

  • Lower conf_thres to 0.15
  • Try larger model (large_640p_fp32)
  • Check image quality and resolution

Wrong OCR results?

  • Verify correct region (kr, eup, na, cn)
  • Try larger OCR model (large_fp32)
  • Check plate crop quality

Slow performance?

  • Use GPU backend (cuda or directml)
  • Use smaller models (small_640p_fp32, small_fp32)
  • Skip video frames
  • Batch process multiple images

πŸ’‘ Conclusion

Manual processing gives you complete control over the ANPR pipeline. Use it for:

  • ✅ Custom filtering and validation
  • ✅ Performance optimization
  • ✅ Video stream processing
  • ✅ Integration with existing CV pipelines
  • ✅ Advanced visualization and tracking

Happy optimizing! ⚡πŸš—



MareArts ANPR V14 - Easy 3-Method Integration (File, OpenCV, PIL)


πŸš€ MareArts ANPR V14 - Getting Started in 3 Easy Ways

Welcome to MareArts ANPR V14! Today I'll show you how to process license plates using three different methods: from files, OpenCV, or PIL. Plus, the new multi-region switching feature that saves memory.

πŸ“¦ Quick Setup

pip install marearts-anpr
ma-anpr config  # Enter your credentials

🎯 Basic Usage - Three Input Methods

from marearts_anpr import ma_anpr_detector_v14, ma_anpr_ocr_v14
from marearts_anpr import marearts_anpr_from_image_file, marearts_anpr_from_cv2, marearts_anpr_from_pil
import cv2
from PIL import Image

# Initialize detector and OCR (once)
detector = ma_anpr_detector_v14(
    "medium_640p_fp32",
    user_name, serial_key, signature,
    backend="cpu",
    conf_thres=0.25
)

ocr = ma_anpr_ocr_v14("medium_fp32", "eup", user_name, serial_key, signature)

# Method 1: From file (easiest!)
result = marearts_anpr_from_image_file(detector, ocr, "plate.jpg")
print(result)

# Method 2: From OpenCV
img = cv2.imread("plate.jpg")
result = marearts_anpr_from_cv2(detector, ocr, img)
print(result)

# Method 3: From PIL
pil_img = Image.open("plate.jpg")
result = marearts_anpr_from_pil(detector, ocr, pil_img)
print(result)

🌍 NEW: Dynamic Region Switching (Saves 180MB!)

Previously, you needed separate OCR instances for each region. Now use set_region():

# Initialize once with any region
ocr = ma_anpr_ocr_v14("medium_fp32", "eup", user_name, serial_key, signature)

# Switch regions instantly!
ocr.set_region('eup')   # European plates
result = marearts_anpr_from_image_file(detector, ocr, "eu-plate.jpg")

ocr.set_region('kr')    # Korean plates  
result = marearts_anpr_from_image_file(detector, ocr, "kr-plate.jpg")

ocr.set_region('na')    # North American plates
result = marearts_anpr_from_image_file(detector, ocr, "us-plate.jpg")

ocr.set_region('cn')    # Chinese plates
ocr.set_region('univ')  # Universal

Memory savings: Single instance vs multiple = ~180MB saved per additional region!

πŸ“Š Available Regions

  • kr - Korean plates (123κ°€4567)
  • eup - European plates (EU standards)
  • na - North American plates (USA, Canada, Mexico)
  • cn - Chinese plates (δΊ¬A·12345)
  • univ - Universal (all regions, slightly lower accuracy)

🎨 Batch Processing

# Detect plates from multiple images
img1 = cv2.imread("plate1.jpg")
img2 = cv2.imread("plate2.jpg")

detections1 = detector.detector(img1)
detections2 = detector.detector(img2)

# Collect plate crops
plates = []
for det in detections1:
    bbox = det['bbox']
    crop = img1[int(bbox[1]):int(bbox[3]), int(bbox[0]):int(bbox[2])]
    plates.append(Image.fromarray(cv2.cvtColor(crop, cv2.COLOR_BGR2RGB)))

for det in detections2:
    bbox = det['bbox']
    crop = img2[int(bbox[1]):int(bbox[3]), int(bbox[0]):int(bbox[2])]
    plates.append(Image.fromarray(cv2.cvtColor(crop, cv2.COLOR_BGR2RGB)))

# Process all plates at once!
results = ocr.predict(plates)  # Pass list of images

for i, (text, conf) in enumerate(results):
    print(f"Plate {i+1}: {text} ({conf}%)")

πŸ”§ Model Options

Detector models:

  • pico_640p_fp32 - Smallest, fastest
  • micro_640p_fp32
  • small_640p_fp32
  • medium_640p_fp32 - Recommended balance
  • large_640p_fp32 - Most accurate

OCR models:

  • pico_fp32 - Fastest
  • micro_fp32
  • small_fp32
  • medium_fp32 - Recommended
  • large_fp32 - Best accuracy

Backends:

  • cpu - Works everywhere
  • cuda - NVIDIA GPU (10-100x faster!)
  • directml - Windows GPU

πŸ“ Complete Example

from marearts_anpr import ma_anpr_detector_v14, ma_anpr_ocr_v14
from marearts_anpr import marearts_anpr_from_image_file
import os

# Load credentials
user_name = os.getenv('MAREARTS_ANPR_USERNAME')
serial_key = os.getenv('MAREARTS_ANPR_SERIAL_KEY')
signature = os.getenv('MAREARTS_ANPR_SIGNATURE')

# Initialize models
detector = ma_anpr_detector_v14(
    "medium_640p_fp32",
    user_name, serial_key, signature,
    backend="cpu",
    conf_thres=0.25,
    iou_thres=0.5
)

ocr = ma_anpr_ocr_v14("medium_fp32", "eup", user_name, serial_key, signature)

# Process European plate
print("Processing European plate...")
result = marearts_anpr_from_image_file(detector, ocr, "eu-plate.jpg")
print(result)

# Switch to Korean region
ocr.set_region('kr')
print("\nProcessing Korean plate...")
result = marearts_anpr_from_image_file(detector, ocr, "kr-plate.jpg")
print(result)

πŸ’‘ Key Takeaways

  • ✅ Three input methods: file, OpenCV, PIL
  • ✅ Dynamic region switching saves memory
  • ✅ Batch processing for efficiency
  • ✅ Multiple model sizes for different needs
  • ✅ GPU acceleration available

πŸ”— Try It Free!

No license yet? Try the free API (1000 requests/day):

ma-anpr test-api your-plate.jpg --region eup

Happy coding! πŸš—πŸ“Έ


Labels:

MareArts ANPR HTTP Server Integration - Load Once, Process Fast

πŸš€ MareArts ANPR HTTP Server - Easy Integration for Any Platform

One of the biggest challenges in ANPR (Automatic Number Plate Recognition) integration is the model loading time. Loading deep learning models can take 20+ seconds, which is impractical if you reload them for every image. Today, I'm sharing our solution: a lightweight HTTP server that loads models once and processes images from memory.

πŸ“Š The Problem: Model Loading Overhead

  • Model loading: ~22 seconds (one time)
  • Image processing: ~0.03 seconds per image
  • Traditional approach: Load models for EVERY image = slow!
  • Server approach: Load models ONCE, process thousands of images = fast!

✨ The Solution: Simple HTTP Server

Our simple_server.py creates a FastAPI server that:

  1. Loads ANPR models once at startup
  2. Accepts images through 3 different methods (file upload, raw bytes, base64)
  3. Processes images directly from memory (no disk I/O)
  4. Perfect for integration with C#, Visual Studio, or any HTTP client

πŸ”§ Server Implementation

Here's the core server code:

#!/usr/bin/env python3
from fastapi import FastAPI, File, UploadFile, Request
from fastapi.responses import JSONResponse
from marearts_anpr import ma_anpr_detector_v14, ma_anpr_ocr_v14, marearts_anpr_from_cv2
import cv2
import numpy as np

# ============================================================================
# LOAD MODELS (Once at startup)
# ============================================================================

detector = ma_anpr_detector_v14(
    "medium_640p_fp32", USER, KEY, SIG,
    backend="cpu",  # or "cuda" for GPU
    conf_thres=0.20
)

ocr = ma_anpr_ocr_v14("small_fp32", "eup", USER, KEY, SIG, backend="cpu")

# ============================================================================
# CREATE SERVER
# ============================================================================

app = FastAPI(title="MareArts ANPR Server")

@app.post("/detect")
async def detect_plate_file(image: UploadFile = File(...)):
    """Method 1: Upload image file (multipart/form-data)"""
    image_bytes = await image.read()
    return process_image_bytes(image_bytes)

@app.post("/detect/binary")
async def detect_plate_binary(request: Request):
    """Method 2: Send raw image bytes"""
    image_bytes = await request.body()
    return process_image_bytes(image_bytes)

@app.post("/detect/base64")
async def detect_plate_base64(data: Base64Image):
    """Method 3: Send base64 encoded image"""
    image_bytes = base64.b64decode(data.image)
    return process_image_bytes(image_bytes)

def process_image_bytes(image_bytes):
    """Process image from bytes"""
    nparr = np.frombuffer(image_bytes, np.uint8)
    img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
    result = marearts_anpr_from_cv2(detector, ocr, img)
    return result

πŸ’» Client Examples

Python Client (test_server.py)

import requests

def test_server(image_path, server_url="http://localhost:8000"):
    # Health check
    response = requests.get(f"{server_url}/health")
    print(response.json())
    
    # Detect plates
    with open(image_path, 'rb') as f:
        files = {'image': f}
        response = requests.post(f"{server_url}/detect", files=files)
    
    result = response.json()
    if result.get('results'):
        print(f"✅ Detected {len(result['results'])} plate(s):")
        for plate in result['results']:
            print(f"  • {plate['ocr']} ({plate['ocr_conf']}%)")

cURL Command Line

# Method 1: File upload
curl -X POST http://localhost:8000/detect -F "image=@plate.jpg"

# Method 2: Binary data
curl -X POST http://localhost:8000/detect/binary --data-binary "@plate.jpg"

# Health check
curl http://localhost:8000/health

C# / Visual Studio Integration

using System.Net.Http;

// Example 1: Send raw bytes
var client = new HttpClient();
var content = new ByteArrayContent(imageBytes);
content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
var response = await client.PostAsync("http://localhost:8000/detect/binary", content);

// Example 2: Send base64 JSON
var base64Image = Convert.ToBase64String(imageBytes);
var json = JsonSerializer.Serialize(new { image = base64Image });
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await client.PostAsync("http://localhost:8000/detect/base64", content);

🎯 Usage Guide

Step 1: Install dependencies

pip install marearts-anpr fastapi uvicorn python-multipart
ma-anpr config  # Configure your credentials

Step 2: Start the server (Terminal 1)

python simple_server.py
# Models load once (~22s), then server waits for requests

Step 3: Send images (Terminal 2 or your application)

python test_server.py your_image.jpg

🌟 Key Benefits

  • Load Once, Use Forever: Models load at startup, not per request
  • Memory Processing: No disk I/O, process images from RAM
  • Multiple Input Methods: File upload, raw bytes, or base64
  • Cross-Platform: Works with Python, C#, JavaScript, or any HTTP client
  • Production Ready: Built on FastAPI with async support
  • Easy Integration: RESTful API with JSON responses

πŸ“ˆ Performance Comparison

Approach First Image Subsequent Images
Traditional (load per image) ~22 seconds ~22 seconds each
HTTP Server (load once) ~22 seconds ~0.03 seconds each

Result: 700x faster for subsequent images! πŸš€

πŸ”— Available Endpoints

  • POST /detect - Upload file (multipart/form-data)
  • POST /detect/binary - Send raw bytes (application/octet-stream)
  • POST /detect/base64 - Send base64 JSON
  • GET / - Server info
  • GET /health - Health check

πŸŽ“ When to Use This

  • ✅ Integrating ANPR into C# / Visual Studio projects
  • ✅ Building web applications with ANPR
  • ✅ Processing multiple images efficiently
  • ✅ Microservice architecture
  • ✅ Real-time video processing

πŸ“¦ Complete Example Package

All code is available in our SDK:

  • simple_server.py - HTTP server (202 lines)
  • test_server.py - Python client test (52 lines)
  • README.md - Complete documentation

Install: pip install marearts-anpr

πŸ” Configuration

The server uses environment variables for credentials:

# Configure once
ma-anpr config

# Credentials are stored in ~/.marearts/.marearts_env
# Server automatically loads from environment variables

πŸ’‘ Conclusion

This HTTP server approach makes ANPR integration incredibly simple. Whether you're building a C# desktop application, a web service, or a microservice architecture, you can now integrate license plate recognition with just a few HTTP calls. No need to worry about Python integration complexity - just send HTTP requests!

The key insight: separate model loading from image processing. Load once, process thousands of times.

Happy coding! πŸš—πŸ“Έ