OpenALPR による英語ナンバープレート認識(ソースコードと実行結果)

Python開発環境,ライブラリ類

ここでは、最低限の事前準備について説明する。機械学習や深層学習を行う場合は、NVIDIA CUDA、Visual Studio、Cursorなどを追加でインストールすると便利である。これらについては別ページ https://www.kkaneko.jp/cc/dev/aiassist.htmlで詳しく解説しているので、必要に応じて参照してください。

Python 3.12 のインストール(Windows 上) [クリックして展開]

以下のいずれかの方法で Python 3.12 をインストールする。Python がインストール済みの場合、この手順は不要である。

方法1:winget によるインストール

管理者権限コマンドプロンプトで以下を実行する。管理者権限のコマンドプロンプトを起動するには、Windows キーまたはスタートメニューから「cmd」と入力し、表示された「コマンドプロンプト」を右クリックして「管理者として実行」を選択する。

winget install --scope machine --id Python.Python.3.12 -e --silent --disable-interactivity --force --accept-source-agreements --accept-package-agreements --override "/quiet InstallAllUsers=1 PrependPath=1 Include_pip=1 Include_test=0 Include_launcher=1 InstallLauncherAllUsers=1"

--scope machine を指定することで、システム全体(全ユーザー向け)にインストールされる。このオプションの実行には管理者権限が必要である。インストール完了後、コマンドプロンプトを再起動すると PATH が自動的に設定される。

方法2:インストーラーによるインストール

  1. Python 公式サイト(https://www.python.org/downloads/)にアクセスし、「Download Python 3.x.x」ボタンから Windows 用インストーラーをダウンロードする。
  2. ダウンロードしたインストーラーを実行する。
  3. 初期画面の下部に表示される「Add python.exe to PATH」に必ずチェックを入れてから「Customize installation」を選択する。このチェックを入れ忘れると、コマンドプロンプトから python コマンドを実行できない。
  4. 「Install Python 3.xx for all users」にチェックを入れ、「Install」をクリックする。

インストールの確認

コマンドプロンプトで以下を実行する。

python --version

バージョン番号(例:Python 3.12.x)が表示されればインストール成功である。「'python' は、内部コマンドまたは外部コマンドとして認識されていません。」と表示される場合は、インストールが正常に完了していない。

AIエディタ Windsurf のインストール(Windows 上) [クリックして展開]

Pythonプログラムの編集・実行には、AIエディタの利用を推奨する。ここでは、Windsurfのインストールを説明する。Windsurf がインストール済みの場合、この手順は不要である。

管理者権限コマンドプロンプトで以下を実行する。管理者権限のコマンドプロンプトを起動するには、Windows キーまたはスタートメニューから「cmd」と入力し、表示された「コマンドプロンプト」を右クリックして「管理者として実行」を選択する。

winget install --scope machine --id Codeium.Windsurf -e --silent --disable-interactivity --force --accept-source-agreements --accept-package-agreements --custom "/SP- /SUPPRESSMSGBOXES /NORESTART /CLOSEAPPLICATIONS /DIR=""C:\Program Files\Windsurf"" /MERGETASKS=!runcode,addtopath,associatewithfiles,!desktopicon"
powershell -Command "$env:Path=[System.Environment]::GetEnvironmentVariable('Path','Machine')+';'+[System.Environment]::GetEnvironmentVariable('Path','User'); windsurf --install-extension MS-CEINTL.vscode-language-pack-ja --force; windsurf --install-extension ms-python.python --force; windsurf --install-extension Codeium.windsurfPyright --force"

--scope machine を指定することで、システム全体(全ユーザー向け)にインストールされる。このオプションの実行には管理者権限が必要である。インストール完了後、コマンドプロンプトを再起動すると PATH が自動的に設定される。

関連する外部ページ

Windsurf の公式ページ: https://windsurf.com/

必要なライブラリをシステム領域にインストール

管理者権限コマンドプロンプトで以下を実行する。管理者権限のコマンドプロンプトを起動するには、Windows キーまたはスタートメニューから「cmd」と入力し、表示された「コマンドプロンプト」を右クリックして「管理者として実行」を選択する。

pip install opencv-python

OpenALPR による英語ナンバープレート認識

概要

このプログラムは、Webカメラから車両画像を取得し、OpenALPRライブラリを用いてナンバープレートの自動認識を行うシステムである。Windows環境でOpenALPR 2.3.0のバイナリを自動的にダウンロード・設定し、リアルタイムでナンバープレート認識処理を実行する。認識結果は画像上にオーバーレイ表示され、JSON形式でも出力される。

主要技術

OpenALPR (Automatic License Plate Recognition)

OpenALPRは、オープンソースの自動ナンバープレート認識ライブラリである[1]。機械学習とコンピュータビジョン技術を組み合わせ、画像からナンバープレートを検出・認識する。LBP (Local Binary Patterns) カスケード分類器による車両検出と、Tesseract OCRエンジンによる文字認識を統合している[2]。

技術的特徴

自動環境構築機能

プログラム実行時にOpenALPRバイナリの存在を確認し、未インストールの場合は自動的にダウンロード・展開を行う。LOCALAPPDATA環境変数を活用し、ユーザーごとの適切な場所に配置する。設定ファイル(openalpr.conf)とランタイムデータの自動探索を行う。

プロセス間通信による認識処理

OpenALPRの実行ファイル(alpr.exe)を子プロセスとして起動し、JSON形式で結果を取得する。環境変数(OPENALPR_CONFIG_FILE、OPENALPR_RUNTIME_DIR)を設定することで、動作環境を制御する。

実装の特色

一時ファイル管理

tempfileモジュールのTemporaryDirectoryを使用し、キャプチャ画像を一時的に保存する。コンテキストマネージャにより、処理終了後の自動削除を保証している。

認識結果の可視化

認識されたナンバープレート番号と信頼度スコアをヒョ持する。複数の候補がある場合は最も信頼度の高い結果を表示する。それと別に,JSON形式での詳細情報を出力する。

参考文献

[1] OpenALPR Technology, Inc. (2024). OpenALPR - Automatic License Plate Recognition library. GitHub Repository. https://github.com/openalpr/openalpr

[2] Smith, R. (2007). An Overview of the Tesseract OCR Engine. Proceedings of the Ninth International Conference on Document Analysis and Recognition (ICDAR 2007), 629-633. https://github.com/tesseract-ocr/tesseract

ソースコード

# OpenALPR による英語ナンバープレート認識
import os, sys, json, tempfile, zipfile, urllib.request, subprocess, time, shutil
try:
    import cv2
except Exception:
    subprocess.check_call([sys.executable, "-m", "pip", "install", "opencv-python"])
    import cv2

URL="https://github.com/openalpr/openalpr/releases/download/v2.3.0/openalpr-2.3.0-win-64bit.zip"
ROOT=os.path.join(os.environ.get("LOCALAPPDATA", tempfile.gettempdir()), "openalpr-2.3.0-win-64bit")
ALPR_EXE=None; CONFIG=None; RUNTIME=None

def ensure_openalpr():
    global ALPR_EXE, CONFIG, RUNTIME
    if not (os.path.isdir(ROOT) and any("alpr.exe" in f for _,_,f in os.walk(ROOT))):
        os.makedirs(ROOT, exist_ok=True)
        zpath=os.path.join(ROOT,"openalpr.zip")
        print("Downloading OpenALPR 2.3.0...")
        urllib.request.urlretrieve(URL, zpath)
        print("Extracting...")
        with zipfile.ZipFile(zpath) as zf: zf.extractall(ROOT)
        os.remove(zpath)
    # find alpr.exe
    found=None
    for d,_,f in os.walk(ROOT):
        if "alpr.exe" in f:
            found=os.path.join(d,"alpr.exe"); break
    if not found: raise RuntimeError("alpr.exe not found")
    ALPR_EXE=found
    base=os.path.dirname(found)
    # config file
    for c in [os.path.join(base,"openalpr.conf"),
              os.path.join(base,"etc","openalpr","openalpr.conf")]:
        if os.path.isfile(c): CONFIG=c; break
    if not CONFIG: raise RuntimeError("openalpr.conf not found")
    # runtime_data
    for r in [os.path.join(base,"runtime_data"),
              os.path.join(base,"..","share","openalpr","runtime_data")]:
        if os.path.isdir(r): RUNTIME=os.path.abspath(r); break
    if not RUNTIME: raise RuntimeError("runtime_data not found")

def capture_frame(path):
    cap=cv2.VideoCapture(0, cv2.CAP_DSHOW)
    if not cap.isOpened(): raise RuntimeError("Camera not available")
    time.sleep(0.3)
    ret,frame=cap.read(); cap.release()
    if not ret: raise RuntimeError("Failed to grab frame")
    cv2.imwrite(path, frame)
    return frame

def run_alpr(img, country="us", topn="10"):
    env=os.environ.copy()
    env["OPENALPR_CONFIG_FILE"]=CONFIG
    env["OPENALPR_RUNTIME_DIR"]=RUNTIME
    cmd=[ALPR_EXE, "-c", country, "--json", "-n", topn, img]
    r=subprocess.run(cmd, env=env, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, cwd=os.path.dirname(ALPR_EXE))
    if r.returncode!=0 and not r.stdout.strip():
        raise RuntimeError("ALPR error: "+r.stderr.strip())
    return json.loads(r.stdout or "{}")

def main():
    ensure_openalpr()
    with tempfile.TemporaryDirectory() as td:
        img=os.path.join(td,"frame.jpg")
        print("Capturing frame...")
        frame=capture_frame(img)
        print("Recognizing...")
        res=run_alpr(img)

        # 結果を表示
        if "results" in res and res["results"]:
            text=f"{res['results'][0].get('plate','')} ({res['results'][0].get('confidence',0):.1f}%)"
            cv2.putText(frame, text, (30,50), cv2.FONT_HERSHEY_SIMPLEX,1,(0,255,0),2)
        cv2.imshow("Captured Frame", frame)
        print(json.dumps(res, indent=2, ensure_ascii=False))
        cv2.waitKey(0)
        cv2.destroyAllWindows()

if __name__=="__main__":
    try:
        main()
    except Exception as e:
        print("Error:", e)
        sys.exit(1)