cari
Rumahpembangunan bahagian belakangTutorial PythonCara Melaksanakan Pengecaman Zon Boleh Baca Mesin (MRZ) dalam Python

機械読み取り可能ゾーン (MRZ) は、現代のパスポート、ビザ、ID カードに採用されている重要な機能です。これには、名前、性別、国コード、文書番号など、文書所有者に関する重要な情報が含まれています。 MRZ の認識は、国境管理、空港のセキュリティ、ホテルのチェックイン プロセスにおいて重要な役割を果たします。このチュートリアルでは、Dynamsoft Capture Vision SDK を利用して、WindowsLinux、および macOS に MRZ 認識を実装する方法を示します。プラットフォーム。このガイドでは、SDK の強力な機能を活用し、クロスプラットフォームの MRZ 検出をシームレスかつ効率的に行うための段階的なアプローチを提供します。

macOS での Python MRZ 認識デモ

前提条件

  • Dynamsoft Capture Vision トライアル ライセンス: Dynamsoft Capture Vision SDK の 30 日間のトライアル ライセンス キーを取得します。

  • Python パッケージ: 次のコマンドを使用して、必要な Python パッケージをインストールします。

    pip install dynamsoft-capture-vision-bundle opencv-python
    

    これらのパッケージは何のためにありますか?

    • dynamsoft-capture-vision-bundle は、Python 用 Dynamsoft Capture Vision SDK です。
    • opencv-python はカメラ フレームをキャプチャし、処理された画像結果を表示します。

Dynamsoft Python Capture Vision サンプルの開始

公式 MRZ スキャナーのサンプルは、Dynamsoft Capture Vision SDK を使用して簡単な Python ベースの MRZ リーダーを短時間で作成する方法を示しています。

ソース コードを見て、その機能を分析してみましょう:

import sys
from dynamsoft_capture_vision_bundle import *
import os

class MRZResult:
    def __init__(self, item: ParsedResultItem):
        self.doc_type = item.get_code_type()
        self.raw_text=[]
        self.doc_id = None
        self.surname = None
        self.given_name = None
        self.nationality = None
        self.issuer = None
        self.gender = None
        self.date_of_birth = None
        self.date_of_expiry = None
        if self.doc_type == "MRTD_TD3_PASSPORT":
            if item.get_field_value("passportNumber") != None and item.get_field_validation_status("passportNumber") != EnumValidationStatus.VS_FAILED:
                self.doc_id = item.get_field_value("passportNumber")
            elif item.get_field_value("documentNumber") != None and item.get_field_validation_status("documentNumber") != EnumValidationStatus.VS_FAILED:
                self.doc_id = item.get_field_value("documentNumber")

        line = item.get_field_value("line1")
        if line is not None:
            if item.get_field_validation_status("line1") == EnumValidationStatus.VS_FAILED:
                line += ", Validation Failed"
            self.raw_text.append(line)
        line = item.get_field_value("line2")
        if line is not None:
            if item.get_field_validation_status("line2") == EnumValidationStatus.VS_FAILED:
                line += ", Validation Failed"
            self.raw_text.append(line)
        line = item.get_field_value("line3")
        if line is not None:
            if item.get_field_validation_status("line3") == EnumValidationStatus.VS_FAILED:
                line += ", Validation Failed"
            self.raw_text.append(line)

        if item.get_field_value("nationality") != None and item.get_field_validation_status("nationality") != EnumValidationStatus.VS_FAILED:
            self.nationality = item.get_field_value("nationality")
        if item.get_field_value("issuingState") != None and item.get_field_validation_status("issuingState") != EnumValidationStatus.VS_FAILED:
            self.issuer = item.get_field_value("issuingState")
        if item.get_field_value("dateOfBirth") != None and item.get_field_validation_status("dateOfBirth") != EnumValidationStatus.VS_FAILED:
            self.date_of_birth = item.get_field_value("dateOfBirth")
        if item.get_field_value("dateOfExpiry") != None and item.get_field_validation_status("dateOfExpiry") != EnumValidationStatus.VS_FAILED:
            self.date_of_expiry = item.get_field_value("dateOfExpiry")
        if item.get_field_value("sex") != None and item.get_field_validation_status("sex") != EnumValidationStatus.VS_FAILED:
            self.gender = item.get_field_value("sex")
        if item.get_field_value("primaryIdentifier") != None and item.get_field_validation_status("primaryIdentifier") != EnumValidationStatus.VS_FAILED:
            self.surname = item.get_field_value("primaryIdentifier")
        if item.get_field_value("secondaryIdentifier") != None and item.get_field_validation_status("secondaryIdentifier") != EnumValidationStatus.VS_FAILED:
            self.given_name = item.get_field_value("secondaryIdentifier")
    def to_string(self):
        msg = (f"Raw Text:\n")
        for index, line in enumerate(self.raw_text):
            msg += (f"\tLine {index + 1}: {line}\n")
        msg+=(f"Parsed Information:\n"
            f"\tDocumentType: {self.doc_type or ''}\n"
            f"\tDocumentID: {self.doc_id or ''}\n"
            f"\tSurname: {self.surname or ''}\n"
            f"\tGivenName: {self.given_name or ''}\n"
            f"\tNationality: {self.nationality or ''}\n"
            f"\tIssuingCountryorOrganization: {self.issuer or ''}\n"
            f"\tGender: {self.gender or ''}\n"
            f"\tDateofBirth(YYMMDD): {self.date_of_birth or ''}\n"
            f"\tExpirationDate(YYMMDD): {self.date_of_expiry or ''}\n")
        return msg
def print_results(result: ParsedResult) -> None:
    tag = result.get_original_image_tag()
    if isinstance(tag, FileImageTag):
        print("File:", tag.get_file_path())
    if result.get_error_code() != EnumErrorCode.EC_OK:
        print("Error:", result.get_error_string())        
    else:
        items = result.get_items()
        print("Parsed", len(items), "MRZ Zones.")
        for item in items:
            mrz_result = MRZResult(item)
            print(mrz_result.to_string())

if __name__ == '__main__':

    print("**********************************************************")
    print("Welcome to Dynamsoft Capture Vision - MRZ Sample")
    print("**********************************************************")

    error_code, error_message = LicenseManager.init_license("LICENSE-KEY")
    if error_code != EnumErrorCode.EC_OK and error_code != EnumErrorCode.EC_LICENSE_CACHE_USED:
        print("License initialization failed: ErrorCode:", error_code, ", ErrorString:", error_message)
    else:
        cvr_instance = CaptureVisionRouter()
        while (True):
            image_path = input(
                ">> Input your image full path:\n"
                ">> 'Enter' for sample image or 'Q'/'q' to quit\n"
            ).strip('\'"')

            if image_path.lower() == "q":
                sys.exit(0)

            if image_path == "":
                image_path = "../Images/passport-sample.jpg"

            if not os.path.exists(image_path):
                print("The image path does not exist.")
                continue
            result = cvr_instance.capture(image_path, "ReadPassportAndId")
            if result.get_error_code() != EnumErrorCode.EC_OK:
                print("Error:", result.get_error_code(), result.get_error_string())
            else:
                parsed_result = result.get_parsed_result()
                if parsed_result is None or len(parsed_result.get_items()) == 0:
                    print("No parsed results.")
                else:
                    print_results(parsed_result)
    input("Press Enter to quit...")

説明

  • LicenseManager.init_license メソッドは、有効なライセンス キーを使用して Dynamsoft Capture Vision SDK を初期化します。
  • CaptureVisionRouter クラスは、画像処理タスクを管理し、さまざまな画像処理モジュールを調整します。そのキャプチャ メソッドは入力画像を処理し、結果を返します。
  • ReadPassportAndId は、処理モードを指定する組み込みテンプレートです。 SDK は、MRZ 認識文書端検出バーコード検出などのさまざまな処理モードをサポートしています。
  • get_parsed_result メソッドは、MRZ の認識結果を辞書として取得します。 MRZResult クラスは、関連する MRZ 情報を抽出してラップします。このクラスはさまざまなアプリケーション間で再利用できるため、utils.py ファイルに移動することをお勧めします。

次のセクションでは、OpenCV を使用して MRZ 認識結果を視覚化し、検出された MRZ ゾーンをパスポート画像上に表示します。

Visualizing Machine Readable Zone Location in a Passport Image

In the code above, result is an instance of the CapturedResult class. Calling its get_recognized_text_lines_result() method retrieves a list of TextLineResultItem objects. Each TextLineResultItem object contains the coordinates of the detected text line. Use the following code snippet to extract the coordinates and draw contours on the passport image:

cv_image = cv2.imread(image_path)
line_result = result.get_recognized_text_lines_result()

items = line_result.get_items()
for item in items:
    location = item.get_location()
    x1 = location.points[0].x
    y1 = location.points[0].y
    x2 = location.points[1].x
    y2 = location.points[1].y
    x3 = location.points[2].x
    y3 = location.points[2].y
    x4 = location.points[3].x
    y4 = location.points[3].y
    del location

    cv2.drawContours(
        cv_image, [np.intp([(x1, y1), (x2, y2), (x3, y3), (x4, y4)])], 0, (0, 255, 0), 2)

cv2.imshow(
    "Original Image with Detected MRZ Zone", cv_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

How to Implement Machine Readable Zone (MRZ) Recognition in Python

Scanning and Recognizing MRZ in Real-time via Webcam

Scanning and recognizing MRZ in real-time via webcam requires capturing a continuous image stream. We can use the OpenCV library to capture frames from the webcam and process them with the Dynamsoft Capture Vision SDK. The following code snippet demonstrates how to implement real-time MRZ recognition using a webcam:

from dynamsoft_capture_vision_bundle import *
import cv2
import numpy as np
import queue
from utils import *


class FrameFetcher(ImageSourceAdapter):
    def has_next_image_to_fetch(self) -> bool:
        return True

    def add_frame(self, imageData):
        self.add_image_to_buffer(imageData)


class MyCapturedResultReceiver(CapturedResultReceiver):
    def __init__(self, result_queue):
        super().__init__()
        self.result_queue = result_queue

    def on_captured_result_received(self, captured_result):
        self.result_queue.put(captured_result)


if __name__ == '__main__':
    errorCode, errorMsg = LicenseManager.init_license(
        "LICENSE-KEY")
    if errorCode != EnumErrorCode.EC_OK and errorCode != EnumErrorCode.EC_LICENSE_CACHE_USED:
        print("License initialization failed: ErrorCode:",
              errorCode, ", ErrorString:", errorMsg)
    else:
        vc = cv2.VideoCapture(0)
        if not vc.isOpened():
            print("Error: Camera is not opened!")
            exit(1)

        cvr = CaptureVisionRouter()
        fetcher = FrameFetcher()
        cvr.set_input(fetcher)

        # Create a thread-safe queue to store captured items
        result_queue = queue.Queue()

        receiver = MyCapturedResultReceiver(result_queue)
        cvr.add_result_receiver(receiver)

        errorCode, errorMsg = cvr.start_capturing("ReadPassportAndId")

        if errorCode != EnumErrorCode.EC_OK:
            print("error:", errorMsg)

        while True:
            ret, frame = vc.read()
            if not ret:
                print("Error: Cannot read frame!")
                break

            fetcher.add_frame(convertMat2ImageData(frame))

            if not result_queue.empty():
                captured_result = result_queue.get_nowait()

                items = captured_result.get_items()
                for item in items:

                    if item.get_type() == EnumCapturedResultItemType.CRIT_TEXT_LINE:
                        text = item.get_text()
                        line_results = text.split('\n')
                        location = item.get_location()
                        x1 = location.points[0].x
                        y1 = location.points[0].y
                        x2 = location.points[1].x
                        y2 = location.points[1].y
                        x3 = location.points[2].x
                        y3 = location.points[2].y
                        x4 = location.points[3].x
                        y4 = location.points[3].y
                        cv2.drawContours(
                            frame, [np.intp([(x1, y1), (x2, y2), (x3, y3), (x4, y4)])], 0, (0, 255, 0), 2)

                        delta = y3 - y1
                        for line_result in line_results:
                            cv2.putText(
                                frame, line_result, (x1, y1), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1, cv2.LINE_AA)
                            y1 += delta

                        del location

                    elif item.get_type() == EnumCapturedResultItemType.CRIT_PARSED_RESULT:
                        mrz_result = MRZResult(item)
                        print(mrz_result.to_string())

            if cv2.waitKey(1) & 0xFF == ord('q'):
                break

            cv2.imshow('frame', frame)

        cvr.stop_capturing()
        vc.release()
        cv2.destroyAllWindows()

Explanation

  • The FrameFetcher class implements the ImageSourceAdapter interface to feed frame data into the built-in buffer.
  • The MyCapturedResultReceiver class implements the CapturedResultReceiver interface. The on_captured_result_received method runs on a native C++ worker thread, sending CapturedResult objects to the main thread where they are stored in a thread-safe queue for further use.
  • A CapturedResult contains several CapturedResultItem objects. The CRIT_TEXT_LINE type represents recognized text lines, while the CRIT_PARSED_RESULT type represents parsed MRZ data.

Running the Real-time MRZ Recognition Demo on Windows

How to Implement Machine Readable Zone (MRZ) Recognition in Python

Source Code

https://github.com/yushulx/python-mrz-scanner-sdk/tree/main/examples/official

Atas ialah kandungan terperinci Cara Melaksanakan Pengecaman Zon Boleh Baca Mesin (MRZ) dalam Python. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Cara Menggunakan Python untuk Mencari Pengagihan Zipf Fail TeksCara Menggunakan Python untuk Mencari Pengagihan Zipf Fail TeksMar 05, 2025 am 09:58 AM

Tutorial ini menunjukkan cara menggunakan Python untuk memproses konsep statistik undang -undang ZIPF dan menunjukkan kecekapan membaca dan menyusun fail teks besar Python semasa memproses undang -undang. Anda mungkin tertanya -tanya apa maksud pengedaran ZIPF istilah. Untuk memahami istilah ini, kita perlu menentukan undang -undang Zipf. Jangan risau, saya akan cuba memudahkan arahan. Undang -undang Zipf Undang -undang Zipf hanya bermaksud: Dalam korpus bahasa semulajadi yang besar, kata -kata yang paling kerap berlaku muncul kira -kira dua kali lebih kerap sebagai kata -kata kerap kedua, tiga kali sebagai kata -kata kerap ketiga, empat kali sebagai kata -kata kerap keempat, dan sebagainya. Mari kita lihat contoh. Jika anda melihat corpus coklat dalam bahasa Inggeris Amerika, anda akan melihat bahawa perkataan yang paling kerap adalah "th

Bagaimana saya menggunakan sup yang indah untuk menghuraikan html?Bagaimana saya menggunakan sup yang indah untuk menghuraikan html?Mar 10, 2025 pm 06:54 PM

Artikel ini menerangkan cara menggunakan sup yang indah, perpustakaan python, untuk menghuraikan html. Ia memperincikan kaedah biasa seperti mencari (), find_all (), pilih (), dan get_text () untuk pengekstrakan data, pengendalian struktur dan kesilapan HTML yang pelbagai, dan alternatif (sel

Penapisan gambar di pythonPenapisan gambar di pythonMar 03, 2025 am 09:44 AM

Berurusan dengan imej yang bising adalah masalah biasa, terutamanya dengan telefon bimbit atau foto kamera resolusi rendah. Tutorial ini meneroka teknik penapisan imej di Python menggunakan OpenCV untuk menangani isu ini. Penapisan Imej: Alat yang berkuasa Penapis Imej

Pengenalan kepada pengaturcaraan selari dan serentak di PythonPengenalan kepada pengaturcaraan selari dan serentak di PythonMar 03, 2025 am 10:32 AM

Python, kegemaran sains dan pemprosesan data, menawarkan ekosistem yang kaya untuk pengkomputeran berprestasi tinggi. Walau bagaimanapun, pengaturcaraan selari dalam Python memberikan cabaran yang unik. Tutorial ini meneroka cabaran -cabaran ini, memberi tumpuan kepada Interprete Global

Bagaimana untuk melakukan pembelajaran mendalam dengan Tensorflow atau Pytorch?Bagaimana untuk melakukan pembelajaran mendalam dengan Tensorflow atau Pytorch?Mar 10, 2025 pm 06:52 PM

Artikel ini membandingkan tensorflow dan pytorch untuk pembelajaran mendalam. Ia memperincikan langkah -langkah yang terlibat: penyediaan data, bangunan model, latihan, penilaian, dan penempatan. Perbezaan utama antara rangka kerja, terutamanya mengenai grap pengiraan

Cara Melaksanakan Struktur Data Anda Sendiri di PythonCara Melaksanakan Struktur Data Anda Sendiri di PythonMar 03, 2025 am 09:28 AM

Tutorial ini menunjukkan mewujudkan struktur data saluran paip tersuai di Python 3, memanfaatkan kelas dan pengendali yang berlebihan untuk fungsi yang dipertingkatkan. Fleksibiliti saluran paip terletak pada keupayaannya untuk menggunakan siri fungsi ke set data, GE

Serialization dan deserialisasi objek python: Bahagian 1Serialization dan deserialisasi objek python: Bahagian 1Mar 08, 2025 am 09:39 AM

Serialization dan deserialization objek Python adalah aspek utama dari mana-mana program bukan remeh. Jika anda menyimpan sesuatu ke fail python, anda melakukan siri objek dan deserialization jika anda membaca fail konfigurasi, atau jika anda menjawab permintaan HTTP. Dalam erti kata, siri dan deserialization adalah perkara yang paling membosankan di dunia. Siapa yang peduli dengan semua format dan protokol ini? Anda mahu berterusan atau mengalirkan beberapa objek python dan mengambilnya sepenuhnya pada masa yang akan datang. Ini adalah cara yang baik untuk melihat dunia pada tahap konseptual. Walau bagaimanapun, pada tahap praktikal, skim siri, format atau protokol yang anda pilih boleh menentukan kelajuan, keselamatan, kebebasan status penyelenggaraan, dan aspek lain dari program

Modul Matematik dalam Python: StatistikModul Matematik dalam Python: StatistikMar 09, 2025 am 11:40 AM

Modul Statistik Python menyediakan keupayaan analisis statistik data yang kuat untuk membantu kami dengan cepat memahami ciri -ciri keseluruhan data, seperti biostatistik dan analisis perniagaan. Daripada melihat titik data satu demi satu, cuma melihat statistik seperti min atau varians untuk menemui trend dan ciri dalam data asal yang mungkin diabaikan, dan membandingkan dataset besar dengan lebih mudah dan berkesan. Tutorial ini akan menjelaskan cara mengira min dan mengukur tahap penyebaran dataset. Kecuali dinyatakan sebaliknya, semua fungsi dalam modul ini menyokong pengiraan fungsi min () dan bukan hanya menjumlahkan purata. Nombor titik terapung juga boleh digunakan. Import secara rawak Statistik import dari fracti

See all articles

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Alat panas

Dreamweaver Mac版

Dreamweaver Mac版

Alat pembangunan web visual

SublimeText3 Linux versi baharu

SublimeText3 Linux versi baharu

SublimeText3 Linux versi terkini

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

SublimeText3 versi Inggeris

SublimeText3 versi Inggeris

Disyorkan: Versi Win, menyokong gesaan kod!

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

Persekitaran pembangunan bersepadu PHP yang berkuasa