Képzeld el, hogy van egy benzinkutad, ahonnan időnként fizetés nélkül lelép egy-két gyökér. De jó lenne tudni a rendszámukat, nem? Vagy van egy parkolóházad, telephelyed, ahol autók, teherautók jönnek-mennek. Jó lenne egy lista, milyen járművek, pontosan mikor érkeztek, távoztak. Akár napi/heti/havi perc alapú parkolódíjat lehetne számolni sorompók nélkül is!
Természetesen megvásárolhatók ilyen profi rendszerek. Csak érdekességképpen, egy speciális rendszámfelismerő kamera ára kb. nettó 3-400 ezer forintnál kezdődik. Egy ki-beléptető kapunál kell belőle két darab. Plusz meg kell venni hozzá a specifikus szoftvert újabb sokszáz-ezer forintért. Máris milliónál tartunk és még nincs benne a számítógép, ami igyekszik rögzíteni/feldolgozni.
Ezt a feladatot meg lehet oldani sokkal gazdaságosabban is: LocalAI!
„Sima, bolti”, nem-speciális kamerákkal is kivitelezhető a dolog. Nem kell hozzá spec szoftvert sem venni, mert meg lehet íratni a kódot az AI-val. Akár a saját Local AI gépeden is, ChatGPT előfizetés nélkül. Szerintem elég menő.
Feladat: valós időben felismerni a képen felbukkanó rendszámokat és dátummal, időponttal együtt beírni egy MySQL adatbázisba.
A leolvasott rendszámok a MySQL adatbázisban:

A folyamat lépései, bedolgozók, kódok
Nem leszek túl részletes, inkább csak felsorolásszerűen adom meg a lépéseket, szőrmentiben mutatom be a felhasznált szoftvereket, folyamatokat, kódokat. Ha érdekelnek a további részletek, keress meg, szívesen segítek.
Alapvetően három részre bontható a feladat:
- objektumfelismerés (rendszámtábla felismerése)
- rendszám karakterek felismerése (OCR)
- az eredmény MySQL adatbázisba írása
1. Objektumfelismerés YOLO-val (You Only Look Once)
Az Ultralytics YOLO Vision a valós idejű objektumdetektálás legújabb fejlesztése, amely kiemelkedő pontosságot és hatékonyságot kínál különféle számítógépes objektumfelismerési feladatokhoz. Fejlett képességei révén ideális választás a rendszámfelismeréshez, mivel képes gyorsan és pontosan azonosítani és nyomon követni a járművek rendszámtábláit valós időben.Természetesen egy csomó minden másra is használható a YOLO: termék- és selejtfelismerés futószalagon, raktárban, bárhol. Tárgyak, emberek, állatok felismerése, számlálása stb., mindez valós időben, kamerák képéről.
Elég egyszerű az installálása Ubuntun:
git clone clone https://github.com/ultralytics/ultralytics.git
cd ultralytics
pip install ultralytics
Ellenőrizzük le, hogy van-e Torch és GPU (CUDA) támogatásunk:


Következő lépés kiválasztani egy YOLO modellt és betanítani, hogy ezúttal rendszámokat ismerjen fel.
A betanítást Roboflow-ról letöltött dataset segítségével végzem el. Nem kell nekem autókat fényképezni és egyenként bekeretezni a fotókon a rendszámokat, hogy ebből tanuljon a modell. Megtették ezt helyettem sokan mások, gond nélkül fel tudom használni, hiszen itt minden nyílt forráskódú.
A letöltött fényképeket meghatározott könyvtárakban helyezem el és megmutatom a YOLO modellnek a data.yaml fájlban, hol találja ezeket a betanulás során:

A modell betanítása egy szimpla parancssorból történhet. Az első tesztekhez a legújabb YOLO11 és annak legkisebb modelljét használtam: yolo11n.pt (ez a nano méretű, legkisebb modell).
yolo task=detect mode=train epochs=100 batch=16 plots=True model=yolo11n.pt data=data.yaml
100 epoch, azaz 100 lépésen keresztül tanítom a YOLO modellt az előzőleg letöltött autós képekkel. Ha megtörtént a betanítás, ideje kipróbálni! Íme, egy parancssorral már egy szimpla képen máris felismeri a rendszámot:
yolo task=detect mode=predict conf=0.25 save=True model=.pyenv/runs/detect/train2/weights/best.pt source=mza1-k.jpg
Nagyon hamar lefutott, a másodperc töredéke alatt. Kész is a kép a bekeretezett rendszámmal.


Ugyanígy parancssorból nemcsak képeken, hanem már videókon is felismeri már a betanított modell a rendszámokat. De lépjünk tovább: most még csak a betanított objektum (rendszámtábla) lett felismerve, olvassuk ki a betűket/számokat is, sőt rögzítsük egy táblázatban!
Rendszámfelismerés OCR-rel együtt, MySQL adatbázissal
A lényeg, hogy a képen (videó képkockán) felismert rendszámtábla, amely be van keretezve, na ezt a kis keretet egy kicsi képpé alakítva futtassunk rajta karakterfelismerést (OCR)!
Erre a feladatra most egy könnyű kis bedolgozót, PaddleOCR-t fogunk használni:
ocr = PaddleOCR()
Csak akkor csinálunk karakterfelismerést, ha a videón az autó rendszáma beért az általam megrajzolt kék keretbe. (Nem kell minden rendszámot felismerni, csak azokat, amiket én akarok.)
Kell egy kis szövegátalakítás a magyar rendszámok miatt, kivenni a karaktersorozat elejéről a kis H betűt és a szokásos formátumra hozni a rendszámot: ABC 123, vagy AB CD 123
Majd csatlakozunk a MySQL adatbázishoz és beírjuk az aktuális rekordot dátummal és idővel.
A teljes Python kód (LocalAI-val írattam):
import cv2
from ultralytics import YOLO
from paddleocr import PaddleOCR
import numpy as np
from server import manage_numberplate_db
import cvzone
# Initialize PaddleOCR
ocr = PaddleOCR()
cap = cv2.VideoCapture('20250130_124028.mp4')
# model = YOLO("best_float32.tflite")
model = YOLO("/home/laszlofesus/.pyenv/runs/detect/train2/weights/best.pt")
with open("coco1.txt", "r") as f:
class_names = f.read().splitlines()
plate_dict = {} # Track ID -> rendszám tárolására
# Function to perform OCR on an image array
def perform_ocr(image_array):
if image_array is None:
raise ValueError("Image is None")
# Perform OCR on the image array
results = ocr.ocr(image_array, rec=True) # rec=True enables text recognition
detected_text = []
# Process OCR results
if results[0] is not None:
for result in results[0]:
text = result[1][0]
detected_text.append(text)
# Join all detected texts into a single string
return ''.join(detected_text)
# Mouse callback function to print mouse position
def RGB(event, x, y, flags, param):
if event == cv2.EVENT_MOUSEMOVE:
point = [x, y]
print(point)
cv2.namedWindow('RGB')
cv2.setMouseCallback('RGB', RGB)
# Initialize video capture and YOLO model
count = 0
area =[(400, 200), (400, 400), (800, 400), (800, 200)] # a kék keret koordinátái
counter = []
while True:
ret, frame = cap.read()
if not ret:
break
# count += 1
# if count % 3 != 0:
# continue
frame = cv2.resize(frame, (1280, 720)) # HD felbontás, több részletet tart meg
# Run YOLOv11 tracking on the frame
results = model.track(frame, persist=True,imgsz=640) # 640 a maximum, 512-vel is jól működik, gyorsabb
# Check if there are any boxes in the results
if results[0].boxes is not None and results[0].boxes.id is not None:
boxes = results[0].boxes.xyxy.int().cpu().tolist() # Bounding boxes
class_ids = results[0].boxes.cls.int().cpu().tolist() # Class IDs
track_ids = results[0].boxes.id.int().cpu().tolist() # Track IDs
confidences = results[0].boxes.conf.cpu().tolist() # Confidence score
for box, class_id, track_id, conf in zip(boxes, class_ids, track_ids, confidences):
# c = class_names[class_id] # most nincs szükség az osztálynevekre (itt most: "numberplate")
x1, y1, x2, y2 = box
cx=int(x1+x2)//2
cy=int(y1+y2)//2
# cv2.circle(frame,(cx,cy),4,(255,0,0),-1)
# cvzone.putTextRect(frame,f'{track_id}',(x1,y1),1,1)
# cv2.rectangle(frame,(x1,y1),(x2,y2),(0,255,0),2)
result = cv2.pointPolygonTest(np.array(area, np.int32), ((cx, cy)), False)
if result >= 0:
if track_id not in counter:
counter.append(track_id) # Only add if it's a new track ID
crop = frame[y1:y2, x1:x2]
crop = cv2.resize(crop, (130, 70)) # A rendszám téglalap mérete
text = perform_ocr(crop)
print(text)
print(f"Track ID: {track_id} - Rendszám: {text}")
text = text.replace('(', '').replace(')', '').replace(',', '').replace(']', '').replace('-', ' ')
# Ha magyar rendszám, és a beolvasott szöveg "H" betűvel kezdődik és legalább 4 betűből áll az első rész
parts = text.split() # Szóközökkel felbontjuk
if len(parts) > 1 and parts[0].startswith("H") and len(parts[0]) == 4:
parts[0] = parts[0][1:] # Levágjuk az első H betűt
text = " ".join(parts) # Újra összerakjuk a rendszámot
# Csak akkor frissítsük a plate_dict-et, ha a rendszám még nincs benne!
if track_id not in plate_dict or plate_dict[track_id] != text:
plate_dict[track_id] = text # Mentsd el a rendszámot a track_id-hez!
manage_numberplate_db(text) # Writes the actual numberplate to the MySQL database
# Rendszám box rajzolása
cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2)
# Kiírás: ha van hozzátartozó rendszám, akkor azt írja ki, különben "--"
plate_text = plate_dict.get(track_id, "--")
cvzone.putTextRect(frame, plate_text, (x1, y1 - 10), 1, 1)
mycounter = len(counter) # Egyedi rendszámok számlálása és a számláló kiírása
cvzone.putTextRect(frame,f'{mycounter}',(50,60),1,1)
cv2.polylines(frame, [np.array(area, np.int32)], True, (255, 0, 0), 2)
# video/kép megjelenítése
cv2.imshow("RGB", frame)
if cv2.waitKey(1) & 0xFF == 27: # cv2.waitKey(0) - képenként, cv2.waitKey(1) - folyamatosan, Press 'Esc' to exit
break
# Close video capture and MySQL connection
cap.release()
cv2.destroyAllWindows()
Python modulok/könyvtárak amiket felhasználtunk a Python kód elején:
Könyvtár | Funkció |
---|---|
cv2 (OpenCV) | Kép/video beolvasása és előfeldolgozása |
ultralytics.YOLO | YOLO objektumdetekció (rendszámtábla felismerés) |
paddleocr.PaddleOCR | OCR-alapú szövegfelismerés (rendszám kiolvasása) |
numpy (np) | Numerikus számítások és tömbkezelés |
server.manage_numberplate_db | Adatbázis kezelés (rendszámok tárolása az adatbázisban) |
cvzone | Vizuális megjelenítés (bounding boxok, szöveg overlay) |
Kis túlzással, többi időt töltöttem ennek a cikknek a megírásával, mint a YOLO munkára fogásával és a kódolással. De akárhogy is, nagyon élveztem, szuper ez az egész!
Talán mondanom sem kell, a kódok megírásánál is nagy segítségemre volt az AI.
Zseniális a LocalAI!
AI-szervert keresel?
Speciális munkafolyamatokra szabott AI szervereket és munkaállomásokat építünk akár előtelepített Linux/AI/LLM/RAG környezettel.
Nem tudod, hol kezd? Mi segítünk!
Lépj kapcsolatba AI műszaki tanácsadóink egyikével még ma! Segítünk kiválasztani az adott feladara legalkalmasabb LLM modellt és hozzá a megfelelő hardvert.