Skip to content

Commit 396580b

Browse files
update to v2.4.20
1 parent 3e77548 commit 396580b

File tree

11 files changed

+1374
-2
lines changed

11 files changed

+1374
-2
lines changed

LICENSE.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
License Notice
2+
3+
This folder contains code samples ("Sample Code") for use with Dynamsoft Capture Vision, a commercial software development kit licensed by Dynamsoft. The Sample Code may be modified and included in your end user software under the terms of the Dynamsoft Software License Agreement   https://www.dynamsoft.com/company/license-agreement/ ("Commercial License"). Except as expressly stated in the Commercial License, no other rights are granted in the Sample Code. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4+
5+
Copyright © 2003–2024 Dynamsoft. All rights reserved.

README.md

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,61 @@
1-
# capture-vision-python-samples
2-
Samples for Dynamsoft Capture Vision Python Edition
1+
# Dynamsoft Capture Vision Samples for Python edition
2+
3+
[![Current version number](https://img.shields.io/pypi/v/dynamsoft_capture_vision_bundle?color=orange)](https://pypi.org/project/dynamsoft_capture_vision_bundle/)
4+
[![Supported Python versions](https://img.shields.io/badge/python-3.8%20%7C%203.9%20%7C%203.10%20%7C%203.11%20%7C%203.12-blue)](https://www.python.org/downloads/)
5+
[![PyPI downloads](https://img.shields.io/pypi/dm/dynamsoft_capture_vision_bundle)](https://pypistats.org/packages/dynamsoft_capture_vision_bundle)
6+
7+
![Dynamsoft](https://dynamsoft.github.io/styleguide/assets/images/icons/dynamsoft_logos/dynamsoft_logo_original.png "Dynamsoft")
8+
9+
## Overview
10+
11+
This repository contains multiple samples that demonstrate how to use the [Dynamsoft Capture Vision](https://www.dynamsoft.com/capture-vision/docs/core/introduction/?lang=python) Python Edition.
12+
13+
## Requirements
14+
15+
### Supported Platforms
16+
- Windows x64
17+
- Linux (x64, ARM64)
18+
- macOS (10.15+)
19+
20+
### Supported Python Versions
21+
22+
- Python 3.12
23+
- Python 3.11
24+
- Python 3.10
25+
- Python 3.9
26+
- Python 3.8
27+
28+
## Installation
29+
30+
```
31+
pip install dynamsoft_capture_vision_bundle
32+
```
33+
34+
or
35+
36+
```
37+
pip3 install dynamsoft_capture_vision_bundle
38+
```
39+
40+
## Samples
41+
42+
| Sample Name | Description |
43+
| ----------- | ----------- |
44+
|[`MRZScanner`](Samples/mrz_scanner.py) | Capture and extract user's information from machine-readable travel documents with Dynamsoft Capture Vision SDK. |
45+
|[`DriverLicenseScanner`](Samples/driver_license_scanner.py) | Capture and extract user's information from driver license/ID with Dynamsoft Capture Vision SDK. |
46+
|[`VINScanner`](Samples/vin_scanner.py) | Capture and extract vehicle's information from Vehicle Identification Number (VIN) with Dynamsoft Capture Vision SDK. |
47+
|[`DocumentScanner`](Samples/document_scanner.py) | The simplest way to detect and normalize a document from an image and save the result as a new image. |
48+
49+
## Documentation
50+
51+
https://www.dynamsoft.com/capture-vision/docs/server/programming/python/?ver=latest&utm_source=samples
52+
53+
## License
54+
55+
The library requires a license to work, you use the API `LicenseManager.init_license` to initialize license key and activate the SDK.
56+
57+
These samples use a free public trial license which require network connection to function. You can request a 30-day free trial license via the <a href="https://www.dynamsoft.com/customer/license/trialLicense?product=dcv&utm_source=github&package=python" target="_blank">Request a Trial License</a> link which works offline.
58+
59+
## Contact Us
60+
61+
https://www.dynamsoft.com/company/contact/

Samples/document_scanner.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
from dynamsoft_capture_vision_bundle import *
2+
import os
3+
import sys
4+
if __name__ == '__main__':
5+
# Initialize license.
6+
# You can request and extend a trial license from https://www.dynamsoft.com/customer/license/trialLicense?product=dcv&utm_source=samples&package=python
7+
# The string 'DLS2eyJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSJ9' here is a free public trial license. Note that network connection is required for this license to work.
8+
errorCode, errorMsg = LicenseManager.init_license("DLS2eyJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSJ9")
9+
if errorCode != EnumErrorCode.EC_OK and errorCode != EnumErrorCode.EC_LICENSE_CACHE_USED:
10+
print("License initialization failed: ErrorCode:", errorCode, ", ErrorString:", errorMsg)
11+
else:
12+
cvr = CaptureVisionRouter()
13+
while (True):
14+
image_path = input(
15+
">> Input your image full path:\n"
16+
">> 'Enter' for sample image or 'Q'/'q' to quit\n"
17+
).strip('\'"')
18+
19+
if image_path.lower() == "q":
20+
sys.exit(0)
21+
22+
if image_path == "":
23+
image_path = "../Images/document-sample.jpg"
24+
25+
if not os.path.exists(image_path):
26+
print("The image path does not exist.")
27+
continue
28+
result = cvr.capture(image_path, EnumPresetTemplate.PT_DETECT_AND_NORMALIZE_DOCUMENT.value)
29+
if result.get_error_code() != EnumErrorCode.EC_OK:
30+
print("Error:", result.get_error_code(), result.get_error_string())
31+
normalized_images_result = result.get_normalized_images_result()
32+
if normalized_images_result is None or len(normalized_images_result.get_items()) == 0:
33+
print("No normalized documents.")
34+
else:
35+
items = normalized_images_result.get_items()
36+
print("Normalized", len(items), "documents.")
37+
for index,item in enumerate(normalized_images_result.get_items()):
38+
out_path = "normalizedResult_" + str(index) + ".png"
39+
image_manager = ImageManager()
40+
image = item.get_image_data()
41+
if image != None:
42+
errorCode, errorMsg = image_manager.save_to_file(image, out_path)
43+
if errorCode == 0:
44+
print("Document " + str(index) + " file: " + out_path)
45+
input("Press Enter to quit...")

Samples/driver_license_scanner.py

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
import sys
2+
from dynamsoft_capture_vision_bundle import *
3+
import os
4+
5+
class DriverLicenseResult:
6+
7+
def __init__(self, item: ParsedResultItem):
8+
self.license_number = None
9+
self.version_number = None
10+
self.vehicle_class = None
11+
self.last_name = None
12+
self.given_name = None
13+
self.gender = None
14+
self.birth_date = None
15+
self.issued_date = None
16+
self.expiration_date = None
17+
self.full_name = None
18+
self.code_type = item.get_code_type()
19+
if self.code_type != "AAMVA_DL_ID" and self.code_type != "AAMVA_DL_ID_WITH_MAG_STRIPE" and self.code_type != "SOUTH_AFRICA_DL":
20+
return
21+
if item.get_field_value("licenseNumber") != None and item.get_field_validation_status("licenseNumber") != EnumValidationStatus.VS_FAILED:
22+
self.license_number = item.get_field_value("licenseNumber")
23+
24+
if item.get_field_value("AAMVAVersionNumber") != None and item.get_field_validation_status("AAMVAVersionNumber") != EnumValidationStatus.VS_FAILED:
25+
self.version_number = item.get_field_value("AAMVAVersionNumber")
26+
27+
if item.get_field_value("vehicleClass") != None and item.get_field_validation_status("vehicleClass") != EnumValidationStatus.VS_FAILED:
28+
self.vehicle_class = item.get_field_value("vehicleClass")
29+
30+
if item.get_field_value("lastName") != None and item.get_field_validation_status("lastName") != EnumValidationStatus.VS_FAILED:
31+
self.last_name = item.get_field_value("lastName")
32+
33+
if item.get_field_value("surName") != None and item.get_field_validation_status("surName") != EnumValidationStatus.VS_FAILED:
34+
self.last_name = item.get_field_value("surName")
35+
36+
if item.get_field_value("givenName") != None and item.get_field_validation_status("givenName") != EnumValidationStatus.VS_FAILED:
37+
self.given_name = item.get_field_value("givenName")
38+
39+
if item.get_field_value("fullName") != None and item.get_field_validation_status("fullName") != EnumValidationStatus.VS_FAILED:
40+
self.full_name = item.get_field_value("fullName")
41+
42+
if item.get_field_value("sex") != None and item.get_field_validation_status("sex") != EnumValidationStatus.VS_FAILED:
43+
self.gender = item.get_field_value("sex")
44+
45+
if item.get_field_value("gender") != None and item.get_field_validation_status("gender") != EnumValidationStatus.VS_FAILED:
46+
self.gender = item.get_field_value("gender")
47+
48+
if item.get_field_value("birthDate") != None and item.get_field_validation_status("birthDate") != EnumValidationStatus.VS_FAILED:
49+
self.birth_date = item.get_field_value("birthDate")
50+
51+
if item.get_field_value("issuedDate") != None and item.get_field_validation_status("issuedDate") != EnumValidationStatus.VS_FAILED:
52+
self.issued_date = item.get_field_value("issuedDate")
53+
54+
if item.get_field_value("expirationDate") != None and item.get_field_validation_status("expirationDate") != EnumValidationStatus.VS_FAILED:
55+
self.expiration_date = item.get_field_value("expirationDate")
56+
57+
if self.full_name is None:
58+
self.full_name = (self.last_name or "") +((' ' + self.given_name) if self.last_name and self.given_name else (self.given_name or ''))
59+
60+
def to_string(self):
61+
return (f"Parsed Information:\n"
62+
f"\tCode Type: {self.code_type or ''}\n"
63+
f"\tLicense Number: {self.license_number or ''}\n"
64+
f"\tVehicle Class: {self.vehicle_class or ''}\n"
65+
f"\tLast Name: {self.last_name or ''}\n"
66+
f"\tGiven Name: {self.given_name or ''}\n"
67+
f"\tFull Name: {self.full_name or ''}\n"
68+
f"\tGender: {self.gender or ''}\n"
69+
f"\tDate of Birth: {self.birth_date or ''}\n"
70+
f"\tIssued Date: {self.issued_date or ''}\n"
71+
f"\tExpiration Date: {self.expiration_date or ''}\n")
72+
73+
74+
def print_results(result: ParsedResult) -> None:
75+
tag = result.get_original_image_tag()
76+
if isinstance(tag, FileImageTag):
77+
print("File:", tag.get_file_path())
78+
if result.get_error_code() != EnumErrorCode.EC_OK:
79+
print("Error:", result.get_error_string())
80+
else:
81+
items = result.get_items()
82+
print("Parsed", len(items), "Driver License(s).")
83+
for item in items:
84+
dlResult = DriverLicenseResult(item)
85+
print(dlResult.to_string())
86+
87+
if __name__ == '__main__':
88+
89+
print("**********************************************************")
90+
print("Welcome to Dynamsoft Capture Vision - DriverLicense Sample")
91+
print("**********************************************************")
92+
93+
# Initialize license.
94+
# You can request and extend a trial license from https://www.dynamsoft.com/customer/license/trialLicense?product=dcv&utm_source=samples&package=python
95+
# The string 'DLS2eyJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSJ9' here is a free public trial license. Note that network connection is required for this license to work.
96+
error_code, error_message = LicenseManager.init_license("DLS2eyJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSJ9")
97+
if error_code != EnumErrorCode.EC_OK and error_code != EnumErrorCode.EC_LICENSE_CACHE_USED:
98+
print("License initialization failed: ErrorCode:", error_code, ", ErrorString:", error_message)
99+
else:
100+
cvr_instance = CaptureVisionRouter()
101+
while (True):
102+
image_path = input(
103+
">> Input your image full path:\n"
104+
">> 'Enter' for sample image or 'Q'/'q' to quit\n"
105+
).strip('\'"')
106+
107+
if image_path.lower() == "q":
108+
sys.exit(0)
109+
110+
if image_path == "":
111+
image_path = "../Images/driver-license-sample.jpg"
112+
113+
if not os.path.exists(image_path):
114+
print("The image path does not exist.")
115+
continue
116+
result = cvr_instance.capture(image_path, "ReadDriversLicense")
117+
if result.get_error_code() != EnumErrorCode.EC_OK:
118+
print("Error:", result.get_error_code(), result.get_error_string())
119+
else:
120+
parsed_result = result.get_parsed_result()
121+
if parsed_result is None or len(parsed_result.get_items()) == 0:
122+
print("No parsed results.")
123+
else:
124+
print_results(parsed_result)
125+
input("Press Enter to quit...")

Samples/mrz_scanner.py

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
2+
import sys
3+
from dynamsoft_capture_vision_bundle import *
4+
import os
5+
6+
class MRZResult:
7+
def __init__(self, item: ParsedResultItem):
8+
self.doc_type = item.get_code_type()
9+
self.raw_text=[]
10+
self.doc_id = None
11+
self.surname = None
12+
self.given_name = None
13+
self.nationality = None
14+
self.issuer = None
15+
self.gender = None
16+
self.date_of_birth = None
17+
self.date_of_expiry = None
18+
if self.doc_type == "MRTD_TD3_PASSPORT":
19+
if item.get_field_value("passportNumber") != None and item.get_field_validation_status("passportNumber") != EnumValidationStatus.VS_FAILED:
20+
self.doc_id = item.get_field_value("passportNumber")
21+
elif item.get_field_value("documentNumber") != None and item.get_field_validation_status("documentNumber") != EnumValidationStatus.VS_FAILED:
22+
self.doc_id = item.get_field_value("documentNumber")
23+
24+
line = item.get_field_value("line1")
25+
if line is not None:
26+
if item.get_field_validation_status("line1") == EnumValidationStatus.VS_FAILED:
27+
line += ", Validation Failed"
28+
self.raw_text.append(line)
29+
line = item.get_field_value("line2")
30+
if line is not None:
31+
if item.get_field_validation_status("line2") == EnumValidationStatus.VS_FAILED:
32+
line += ", Validation Failed"
33+
self.raw_text.append(line)
34+
line = item.get_field_value("line3")
35+
if line is not None:
36+
if item.get_field_validation_status("line3") == EnumValidationStatus.VS_FAILED:
37+
line += ", Validation Failed"
38+
self.raw_text.append(line)
39+
40+
if item.get_field_value("nationality") != None and item.get_field_validation_status("nationality") != EnumValidationStatus.VS_FAILED:
41+
self.nationality = item.get_field_value("nationality")
42+
if item.get_field_value("issuingState") != None and item.get_field_validation_status("issuingState") != EnumValidationStatus.VS_FAILED:
43+
self.issuer = item.get_field_value("issuingState")
44+
if item.get_field_value("dateOfBirth") != None and item.get_field_validation_status("dateOfBirth") != EnumValidationStatus.VS_FAILED:
45+
self.date_of_birth = item.get_field_value("dateOfBirth")
46+
if item.get_field_value("dateOfExpiry") != None and item.get_field_validation_status("dateOfExpiry") != EnumValidationStatus.VS_FAILED:
47+
self.date_of_expiry = item.get_field_value("dateOfExpiry")
48+
if item.get_field_value("sex") != None and item.get_field_validation_status("sex") != EnumValidationStatus.VS_FAILED:
49+
self.gender = item.get_field_value("sex")
50+
if item.get_field_value("primaryIdentifier") != None and item.get_field_validation_status("primaryIdentifier") != EnumValidationStatus.VS_FAILED:
51+
self.surname = item.get_field_value("primaryIdentifier")
52+
if item.get_field_value("secondaryIdentifier") != None and item.get_field_validation_status("secondaryIdentifier") != EnumValidationStatus.VS_FAILED:
53+
self.given_name = item.get_field_value("secondaryIdentifier")
54+
def to_string(self):
55+
msg = (f"Raw Text:\n")
56+
for index, line in enumerate(self.raw_text):
57+
msg += (f"\tLine {index + 1}: {line}\n")
58+
msg+=(f"Parsed Information:\n"
59+
f"\tDocumentType: {self.doc_type or ''}\n"
60+
f"\tDocumentID: {self.doc_id or ''}\n"
61+
f"\tSurname: {self.surname or ''}\n"
62+
f"\tGivenName: {self.given_name or ''}\n"
63+
f"\tNationality: {self.nationality or ''}\n"
64+
f"\tIssuingCountryorOrganization: {self.issuer or ''}\n"
65+
f"\tGender: {self.gender or ''}\n"
66+
f"\tDateofBirth(YYMMDD): {self.date_of_birth or ''}\n"
67+
f"\tExpirationDate(YYMMDD): {self.date_of_expiry or ''}\n")
68+
return msg
69+
def print_results(result: ParsedResult) -> None:
70+
tag = result.get_original_image_tag()
71+
if isinstance(tag, FileImageTag):
72+
print("File:", tag.get_file_path())
73+
if result.get_error_code() != EnumErrorCode.EC_OK:
74+
print("Error:", result.get_error_string())
75+
else:
76+
items = result.get_items()
77+
print("Parsed", len(items), "MRZ Zones.")
78+
for item in items:
79+
mrz_result = MRZResult(item)
80+
print(mrz_result.to_string())
81+
82+
if __name__ == '__main__':
83+
84+
print("**********************************************************")
85+
print("Welcome to Dynamsoft Capture Vision - MRZ Sample")
86+
print("**********************************************************")
87+
88+
# Initialize license.
89+
# You can request and extend a trial license from https://www.dynamsoft.com/customer/license/trialLicense?product=dcv&utm_source=samples&package=python
90+
# The string 'DLS2eyJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSJ9' here is a free public trial license. Note that network connection is required for this license to work.
91+
error_code, error_message = LicenseManager.init_license("DLS2eyJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSJ9")
92+
if error_code != EnumErrorCode.EC_OK and error_code != EnumErrorCode.EC_LICENSE_CACHE_USED:
93+
print("License initialization failed: ErrorCode:", error_code, ", ErrorString:", error_message)
94+
else:
95+
cvr_instance = CaptureVisionRouter()
96+
while (True):
97+
image_path = input(
98+
">> Input your image full path:\n"
99+
">> 'Enter' for sample image or 'Q'/'q' to quit\n"
100+
).strip('\'"')
101+
102+
if image_path.lower() == "q":
103+
sys.exit(0)
104+
105+
if image_path == "":
106+
image_path = "../Images/passport-sample.jpg"
107+
108+
if not os.path.exists(image_path):
109+
print("The image path does not exist.")
110+
continue
111+
result = cvr_instance.capture(image_path, "ReadPassportAndId")
112+
if result.get_error_code() != EnumErrorCode.EC_OK:
113+
print("Error:", result.get_error_code(), result.get_error_string())
114+
else:
115+
parsed_result = result.get_parsed_result()
116+
if parsed_result is None or len(parsed_result.get_items()) == 0:
117+
print("No parsed results.")
118+
else:
119+
print_results(parsed_result)
120+
input("Press Enter to quit...")

0 commit comments

Comments
 (0)