Thêm model AI mới cho camera (không sửa code)
Camera RV1126BP chạy được model AI tùy chỉnh: vết dầu loang, khói / lửa, mũ bảo hiểm, vật cản lối đi… Mỗi model
là 2 file <id>.rknn + <id>.json. Đưa vào camera là có thêm một tính năng trên app, ngang hàng với đọc biển số,
đếm người / xe: có ô bật / tắt, giờ chạy, vùng giám sát, độ nhạy, cách báo (thông báo / gọi điện).
- Không sửa code, không build lại phần mềm camera, không khởi động lại camera.
- Chỉ model đang bật mới được nạp vào NPU; tắt trên app thì camera giải phóng ngay.
- Tối đa 8 model tùy chỉnh mỗi camera. Bật nhiều model cùng lúc thì NPU chia thời gian: xem ms/lần của từng model trên trang cấu hình camera (Trạng thái → Model AI tùy chỉnh) hoặc trên app.
Ex01 / máy train máy chủ (Quản trị → Model AI) app (chủ camera) camera
best.pt ─► make_custom_model.py ─► gói oil-1.0.tar.gz ─────► Tính năng AI → Model AI → Cài ─► tải, kiểm SHA-256,
thay file, nạp lại
bật "Vết dầu loang", vẽ vùng ─► chạy mỗi 3 giây
─► sự kiện "custom"
─► thông báo / cuộc gọi
1. Train model
Model phải là YOLOv8 / YOLO11 phát hiện khung (Ultralytics, task=detect), 1..16 lớp. Train giống model biển số
trong Ex01 (yolo detect train model=yolo11n.pt data=… imgsz=640).
Mẹo cho dữ liệu (lấy ví dụ vết dầu loang):
- Ảnh chụp từ chính camera, đúng góc lắp thật, đủ ngày / đêm / đèn, nhiều loại sàn, vết lớn / nhỏ.
- Rất nhiều ảnh "không phải dầu" (không gán nhãn): vũng nước, sàn vừa lau, bóng đổ, đèn phản chiếu, vết bẩn, giấy, túi nilon. Thiếu nhóm này thì camera báo nhầm liên tục.
- Bắt đầu bằng 1 lớp (
dầu). Muốn camera phân biệt thì thêm lớp (dầu,nước) và chỉ báo lớpdầu(--alert dầu). yolo11nđủ nhanh;yolo11schính xác hơn nhưng chậm gấp ~2,5 lần trên NPU.
2. Đóng gói cho camera — lpr_camera/tools/make_custom_model.py
Chạy trên Linux / WSL (rknn-toolkit2 chỉ có cho Linux, Python 3.11):
python3.11 -m venv rk && . rk/bin/activate
pip install rknn-toolkit2==2.3.2 onnx==1.16.1 "setuptools<82" ultralytics
python make_custom_model.py --pt runs/detect/train/weights/best.pt --id oil --name "Vết dầu loang" \
--calib datasets/oil/images/val --mode presence --confirm 30 --level alarm --version 1.0 --verify
# -> out/oil.rknn out/oil.json out/oil-1.0.tar.gz
| Tham số | Ý nghĩa |
|---|---|
--id |
mã model: a-z 0-9 _, tối đa 14 ký tự, không trùng plate / chars / object / face…. Cùng id = bản mới của model đó |
--name |
tên hiện trên app và trong thông báo ("Phát hiện Vết dầu loang tại Sàn kho") |
--calib |
thư mục 50–300 ảnh thực tế từ camera để lượng tử INT8 (càng giống thực tế càng chính xác) |
--mode presence |
vật ở cùng chỗ quá --confirm giây mới báo, báo 1 lần; còn đó thì không báo lại. Người đi qua che khuất ngắn không tính là mất. Dầu loang, vật cản, đồ bỏ quên |
--mode instant |
thấy là báo; vật còn trong khung thì không báo lại. Khói, lửa, không đội mũ |
--confirm |
presence: số giây có mặt liên tục (mặc định 30) |
--interval |
giây giữa 2 lần chạy model (mặc định presence 3, instant 1) — càng lớn càng đỡ tải NPU |
--forget |
vắng mặt bao lâu thì coi là đã hết (mặc định presence 60, instant 10) |
--cooldown |
giây tối thiểu giữa 2 lần báo của model (mặc định 60) |
--conf |
điểm tối thiểu 0..1 (mặc định 0.5; người dùng chỉnh lại được trên app) |
--level |
info thông báo thường · alarm báo ngay · call mặc định gọi điện (chủ camera vẫn tự chọn trên app) |
--alert |
chỉ báo các lớp này, VD --alert "không mũ" |
--gray |
model train trên ảnh xám (như model biển số) |
--verify |
so bản INT8 với bản gốc trên giả lập NPU; dưới 90% thì thêm ảnh hiệu chuẩn |
rknn-toolkit2 phải đúng 2.3.2 (khớp librknnrt trong firmware camera). Script tự thêm phép chuẩn hóa tọa độ
khung về 0..1 trước khi lượng tử (giống object.rknn) — bản Ultralytics xuất thẳng sang rknn sẽ không chạy đúng.
File <id>.json (sửa tay được, VD đổi tên / cách báo mà không cần train lại — gói chỉ có .json cũng cài được):
{
"name": "Vết dầu loang", "desc": "Dầu loang trên sàn kho", "version": "1.0",
"model": "oil.rknn", "classes": ["dầu"], "alert_classes": ["dầu"],
"mode": "presence", "conf": 0.5, "interval_s": 3, "confirm_s": 30, "forget_s": 60, "cooldown_s": 60,
"level": "alarm", "input": "rgb", "normalized": true
}
3. Đưa model vào camera
Từ xa (khuyên dùng): web quản trị → Quản trị → Model AI → tải lên oil-1.0.tar.gz (hoặc chọn cùng lúc
oil.rknn + oil.json). Chủ camera mở app → camera → Tính năng AI → Model AI → Cài. Camera tải gói, kiểm
SHA-256, kiểm từng file (đầu RKNN, json hợp lệ), thay vào /userdata/lpr/models/custom/ rồi nạp lại — vài giây,
không khởi động lại. Gói lỗi thì không thay file nào.
Cùng cách này cập nhật model có sẵn: gói chứa plate.rknn / chars.rknn / object.rknn sẽ thay model biển số /
người-xe (phải cùng số lớp, cùng cách xuất với bản cũ — đổi số lớp biển số thì vẫn phải build lại phần mềm).
Tay: chép oil.rknn + oil.json vào camera /userdata/lpr/models/custom/ rồi khởi động lại; hoặc đặt vào
lpr_camera/models/custom/ trước khi build.bat / make package để đóng kèm gói firmware.
4. Bật trên app
Tính năng AI → Vết dầu loang: bật, giờ chạy + ngày trong tuần, vùng giám sát (vẽ trên hình, VD chỉ mặt sàn; bỏ trống = toàn ảnh), độ nhạy, thời gian xác nhận, chống báo lặp. Gửi thử tạo sự kiện mẫu để thử thông báo / cuộc gọi. Cảnh báo: mỗi model một dòng riêng (đẩy thông báo / gọi điện).
5. Sự kiện gửi về
Loại custom, đi cùng đường với xâm nhập / khuôn mặt (báo ngay qua WebSocket, bản kèm ảnh toàn cảnh + ảnh cắt vùng
phát hiện qua /api/device/events):
{"type":"custom","summary":"Phát hiện Vết dầu loang tại Sàn kho (đã 31 giây)",
"data":{"model":"oil","model_name":"Vết dầu loang","class":"dầu","class_index":0,"score":0.83,
"box":[0.40,0.70,0.60,0.80],"duration_s":31,"mode":"presence","level":"alarm","zone":"Sàn kho"}}
Xem trên app / web (Sự kiện) và API công khai GET /api/v1/events?type=custom như các sự kiện AI khác.
6. Khi nào vẫn phải sửa code
- Model không phải YOLO detect: phân vùng (seg), phân loại ảnh, nhận dạng khuôn mặt, OCR…
- Cần logic mới: đo diện tích vết loang, tốc độ xe, kết hợp 2 model ("người" + "không mũ")…
- Đổi số lớp / ngưỡng của model biển số (
model_config.h).