Home Backend Development Python Tutorial How to Implement Machine Readable Zone (MRZ) Recognition in Python

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

Oct 18, 2024 pm 04:17 PM

機械読み取り可能ゾーン (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
    
    Copy after login

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

    • 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...")
Copy after login

説明

  • 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()
Copy after login

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()

Copy after login

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

The above is the detailed content of How to Implement Machine Readable Zone (MRZ) Recognition in Python. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Roblox: Bubble Gum Simulator Infinity - How To Get And Use Royal Keys
4 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
Nordhold: Fusion System, Explained
4 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
Mandragora: Whispers Of The Witch Tree - How To Unlock The Grappling Hook
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Hot Topics

Java Tutorial
1671
14
PHP Tutorial
1276
29
C# Tutorial
1256
24
Python vs. C  : Learning Curves and Ease of Use Python vs. C : Learning Curves and Ease of Use Apr 19, 2025 am 12:20 AM

Python is easier to learn and use, while C is more powerful but complex. 1. Python syntax is concise and suitable for beginners. Dynamic typing and automatic memory management make it easy to use, but may cause runtime errors. 2.C provides low-level control and advanced features, suitable for high-performance applications, but has a high learning threshold and requires manual memory and type safety management.

Python and Time: Making the Most of Your Study Time Python and Time: Making the Most of Your Study Time Apr 14, 2025 am 12:02 AM

To maximize the efficiency of learning Python in a limited time, you can use Python's datetime, time, and schedule modules. 1. The datetime module is used to record and plan learning time. 2. The time module helps to set study and rest time. 3. The schedule module automatically arranges weekly learning tasks.

Python vs. C  : Exploring Performance and Efficiency Python vs. C : Exploring Performance and Efficiency Apr 18, 2025 am 12:20 AM

Python is better than C in development efficiency, but C is higher in execution performance. 1. Python's concise syntax and rich libraries improve development efficiency. 2.C's compilation-type characteristics and hardware control improve execution performance. When making a choice, you need to weigh the development speed and execution efficiency based on project needs.

Learning Python: Is 2 Hours of Daily Study Sufficient? Learning Python: Is 2 Hours of Daily Study Sufficient? Apr 18, 2025 am 12:22 AM

Is it enough to learn Python for two hours a day? It depends on your goals and learning methods. 1) Develop a clear learning plan, 2) Select appropriate learning resources and methods, 3) Practice and review and consolidate hands-on practice and review and consolidate, and you can gradually master the basic knowledge and advanced functions of Python during this period.

Python vs. C  : Understanding the Key Differences Python vs. C : Understanding the Key Differences Apr 21, 2025 am 12:18 AM

Python and C each have their own advantages, and the choice should be based on project requirements. 1) Python is suitable for rapid development and data processing due to its concise syntax and dynamic typing. 2)C is suitable for high performance and system programming due to its static typing and manual memory management.

Which is part of the Python standard library: lists or arrays? Which is part of the Python standard library: lists or arrays? Apr 27, 2025 am 12:03 AM

Pythonlistsarepartofthestandardlibrary,whilearraysarenot.Listsarebuilt-in,versatile,andusedforstoringcollections,whereasarraysareprovidedbythearraymoduleandlesscommonlyusedduetolimitedfunctionality.

Python: Automation, Scripting, and Task Management Python: Automation, Scripting, and Task Management Apr 16, 2025 am 12:14 AM

Python excels in automation, scripting, and task management. 1) Automation: File backup is realized through standard libraries such as os and shutil. 2) Script writing: Use the psutil library to monitor system resources. 3) Task management: Use the schedule library to schedule tasks. Python's ease of use and rich library support makes it the preferred tool in these areas.

Python for Web Development: Key Applications Python for Web Development: Key Applications Apr 18, 2025 am 12:20 AM

Key applications of Python in web development include the use of Django and Flask frameworks, API development, data analysis and visualization, machine learning and AI, and performance optimization. 1. Django and Flask framework: Django is suitable for rapid development of complex applications, and Flask is suitable for small or highly customized projects. 2. API development: Use Flask or DjangoRESTFramework to build RESTfulAPI. 3. Data analysis and visualization: Use Python to process data and display it through the web interface. 4. Machine Learning and AI: Python is used to build intelligent web applications. 5. Performance optimization: optimized through asynchronous programming, caching and code

See all articles