Rathnavelu/indian-currency-cnn-yolo
17
๐ฎ๐ณ Indian Currency Detector (CNN + YOLO) โ Mobile Optimized
A lightweight, combined YOLOv8-nano + MobileNetV3-Small model for real-time Indian currency detection and denomination classification, optimized for mobile deployment.
๐๏ธ Architecture
Camera Frame โ [YOLOv8-nano] โ Detect & Localize Currency โ [MobileNetV3-Small] โ Classify Denomination๐ Performance
๐ฐ Supported Indian Denominations
๐ Usage
Quick Start โ Classification Only
import torch
from torchvision import models, transforms
from PIL import Image
# Load model
model = models.mobilenet_v3_small()
model.classifier = torch.nn.Sequential(
torch.nn.Linear(576, 256),
torch.nn.Hardswish(),
torch.nn.Dropout(0.3),
torch.nn.Linear(256, 7)
)
checkpoint = torch.load("mobilenetv3_currency.pth", map_location="cpu")
model.load_state_dict(checkpoint['model_state_dict'])
model.eval()
# Preprocess
transform = transforms.Compose([
transforms.Resize(256),
transforms.CenterCrop(224),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]),
])
# Predict
img = Image.open("your_currency_photo.jpg").convert("RGB")
input_tensor = transform(img).unsqueeze(0)
with torch.no_grad():
output = model(input_tensor)
class_names = ["โน10", "โน100", "โน20", "โน200", "โน2000", "โน50", "โน500"]
prediction = class_names[output.argmax(1).item()]
confidence = torch.softmax(output, 1).max().item()
print(f"Detected: {prediction} ({confidence:.1%})")YOLO Detection
from ultralytics import YOLO
model = YOLO("yolov8n_currency_best.pt")
results = model("currency_photo.jpg")
results[0].show()ONNX Inference (Mobile/Edge)
import onnxruntime as ort
import numpy as np
from PIL import Image
# CNN Classifier
session = ort.InferenceSession("mobilenetv3_currency.onnx")
img = Image.open("currency.jpg").resize((224, 224))
img_array = np.array(img).astype(np.float32) / 255.0
img_array = (img_array - [0.485, 0.456, 0.406]) / [0.229, 0.224, 0.225]
input_data = img_array.transpose(2, 0, 1)[np.newaxis, ...]
outputs = session.run(None, {"input": input_data})
class_names = ["โน10", "โน100", "โน20", "โน200", "โน2000", "โน50", "โน500"]
print(f"Predicted: {class_names[np.argmax(outputs[0])]}")๐ฑ Mobile Deployment
๐ Files
๐ฌ Training Details
- Base Models: YOLOv8-nano (COCO pretrained) + MobileNetV3-Small (ImageNet pretrained)
- Dataset: ViratGarg/currency + ViratGarg/currency2 โ 420 images, 7 balanced classes
- CNN Training: 30 epochs, AdamW (lr=1e-3), CosineAnnealing LR, label smoothing=0.1
- YOLO Training: 30 epochs, SGD (lr=0.01), mosaic augmentation, close_mosaic=10
- Augmentation: RandomResizedCrop, ColorJitter, RandomPerspective, RandomErasing, HSV jitter
- Hardware: CPU training (works on GPU too for faster training)
Training Recipe (Based on Published Research)
- YOLOBench (arxiv:2307.13901): COCO pretrain โ fine-tune strategy
- HierLight-YOLO (arxiv:2509.22365): Lightweight detection architecture
- Currency CNN paper (arxiv:2509.06331): Augmentation recipe for currency images
โ ๏ธ Limitations
- Trained on Indian currency notes only (no coins in current dataset)
- Small training set (420 images) โ accuracy may vary on edge cases
- YOLO bounding boxes are pseudo-annotations (classification โ detection conversion)
- For production use, recommend collecting more diverse training data with real bounding box annotations
๐ License
Apache 2.0
