mirror of
https://github.com/kerberos-io/openalpr-base.git
synced 2025-09-27 19:54:26 +08:00
Now with support for Python 3+
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -42,5 +42,8 @@ src.sln
|
|||||||
Debug/
|
Debug/
|
||||||
Release/
|
Release/
|
||||||
|
|
||||||
|
# JetBrains IDEA / PyCharm
|
||||||
|
.idea/
|
||||||
|
|
||||||
|
|
||||||
cmake_install.cmake
|
cmake_install.cmake
|
||||||
|
@@ -1 +1,6 @@
|
|||||||
from openalpr import Alpr
|
import sys as _sys
|
||||||
|
|
||||||
|
if _sys.version_info.major >= 3:
|
||||||
|
from .openalpr import Alpr
|
||||||
|
else:
|
||||||
|
from openalpr import Alpr
|
@@ -2,17 +2,60 @@ import ctypes
|
|||||||
import json
|
import json
|
||||||
import platform
|
import platform
|
||||||
|
|
||||||
|
# We need to do things slightly differently for Python 2 vs. 3
|
||||||
|
# ... because the way str/unicode have changed to bytes/str
|
||||||
|
if platform.python_version_tuple()[0] == '2':
|
||||||
|
# Using Python 2
|
||||||
|
bytes = str
|
||||||
|
_PYTHON_3 = False
|
||||||
|
else:
|
||||||
|
# Assume using Python 3+
|
||||||
|
unicode = str
|
||||||
|
_PYTHON_3 = True
|
||||||
|
|
||||||
|
def _convert_to_charp(string):
|
||||||
|
# Prepares function input for use in c-functions as char*
|
||||||
|
if type(string) == unicode:
|
||||||
|
return string.encode("UTF-8")
|
||||||
|
elif type(string) == bytes:
|
||||||
|
return string
|
||||||
|
else:
|
||||||
|
raise TypeError("Expected unicode string values or ascii/bytes values. Got: %r" % type(string))
|
||||||
|
|
||||||
|
def _convert_from_charp(charp):
|
||||||
|
# Prepares char* output from c-functions into Python strings
|
||||||
|
if _PYTHON_3 and type(charp) == bytes:
|
||||||
|
return charp.decode("UTF-8")
|
||||||
|
else:
|
||||||
|
return charp
|
||||||
|
|
||||||
class Alpr():
|
class Alpr():
|
||||||
def __init__(self, country, config_file, runtime_dir):
|
def __init__(self, country, config_file, runtime_dir):
|
||||||
|
"""
|
||||||
|
Initializes an OpenALPR instance in memory.
|
||||||
|
|
||||||
|
:param country: The default region for license plates. E.g., "us" or "eu"
|
||||||
|
:param config_file: The path to the OpenALPR config file
|
||||||
|
:param runtime_dir: The path to the OpenALPR runtime data directory
|
||||||
|
:return: An OpenALPR instance
|
||||||
|
"""
|
||||||
|
country = _convert_to_charp(country)
|
||||||
|
config_file = _convert_to_charp(config_file)
|
||||||
|
runtime_dir = _convert_to_charp(runtime_dir)
|
||||||
|
try:
|
||||||
# Load the .dll for Windows and the .so for Unix-based
|
# Load the .dll for Windows and the .so for Unix-based
|
||||||
if platform.system().lower().find("windows") != -1:
|
if platform.system().lower().find("windows") != -1:
|
||||||
self._openalprpy_lib = ctypes.cdll.LoadLibrary("openalprpy.dll")
|
self._openalprpy_lib = ctypes.cdll.LoadLibrary("openalprpy.dll")
|
||||||
elif platform.system().lower().find("darwin") != -1:
|
elif platform.system().lower().find("darwin") != -1:
|
||||||
self._openalprpy_lib = ctypes.cdll.LoadLibrary("libopenalprpy.dylib")
|
self._openalprpy_lib = ctypes.cdll.LoadLibrary("libopenalprpy.dylib")
|
||||||
else:
|
else:
|
||||||
self._openalprpy_lib = ctypes.cdll.LoadLibrary("libopenalprpy.so")
|
self._openalprpy_lib = ctypes.cdll.LoadLibrary("libopenalprpy.so")
|
||||||
|
except OSError as e:
|
||||||
|
nex = OSError("Unable to locate the OpenALPR library. Please make sure that OpenALPR is properly "
|
||||||
|
"installed on your system and that the libraries are in the appropriate paths.")
|
||||||
|
if _PYTHON_3:
|
||||||
|
nex.__cause__ = e;
|
||||||
|
raise nex
|
||||||
|
|
||||||
self._initialize_func = self._openalprpy_lib.initialize
|
self._initialize_func = self._openalprpy_lib.initialize
|
||||||
self._initialize_func.restype = ctypes.c_void_p
|
self._initialize_func.restype = ctypes.c_void_p
|
||||||
@@ -54,44 +97,108 @@ class Alpr():
|
|||||||
|
|
||||||
|
|
||||||
def unload(self):
|
def unload(self):
|
||||||
|
"""
|
||||||
|
Unloads OpenALPR from memory.
|
||||||
|
|
||||||
|
:return: None
|
||||||
|
"""
|
||||||
self._openalprpy_lib.dispose(self.alpr_pointer)
|
self._openalprpy_lib.dispose(self.alpr_pointer)
|
||||||
|
|
||||||
def is_loaded(self):
|
def is_loaded(self):
|
||||||
|
"""
|
||||||
|
Checks if OpenALPR is loaded.
|
||||||
|
|
||||||
|
:return: A bool representing if OpenALPR is loaded or not
|
||||||
|
"""
|
||||||
return self._is_loaded_func(self.alpr_pointer)
|
return self._is_loaded_func(self.alpr_pointer)
|
||||||
|
|
||||||
def recognize_file(self, file_path):
|
def recognize_file(self, file_path):
|
||||||
|
"""
|
||||||
|
This causes OpenALPR to attempt to recognize an image by opening a file on
|
||||||
|
disk.
|
||||||
|
|
||||||
|
:param file_path: The path to the image that will be analyzed
|
||||||
|
:return: An OpenALPR analysis in the form of a response dictionary
|
||||||
|
"""
|
||||||
|
file_path = _convert_to_charp(file_path)
|
||||||
ptr = self._recognize_file_func(self.alpr_pointer, file_path)
|
ptr = self._recognize_file_func(self.alpr_pointer, file_path)
|
||||||
json_data = ctypes.cast(ptr, ctypes.c_char_p).value
|
json_data = ctypes.cast(ptr, ctypes.c_char_p).value
|
||||||
|
json_data = _convert_from_charp(json_data)
|
||||||
response_obj = json.loads(json_data)
|
response_obj = json.loads(json_data)
|
||||||
self._free_json_mem_func(ctypes.c_void_p(ptr))
|
self._free_json_mem_func(ctypes.c_void_p(ptr))
|
||||||
|
|
||||||
return response_obj
|
return response_obj
|
||||||
|
|
||||||
def recognize_array(self, byte_array):
|
def recognize_array(self, byte_array):
|
||||||
|
"""
|
||||||
|
This causes OpenALPR to attempt to recognize an image passed in as a byte array.
|
||||||
|
|
||||||
|
:param byte_array: This should be a string (Python 2) or a bytes object (Python 3)
|
||||||
|
:return: An OpenALPR analysis in the form of a response dictionary
|
||||||
|
"""
|
||||||
|
if type(byte_array) != bytes:
|
||||||
|
raise TypeError("Expected a byte array (string in Python 2, bytes in Python 3)")
|
||||||
pb = ctypes.cast(byte_array, ctypes.POINTER(ctypes.c_ubyte))
|
pb = ctypes.cast(byte_array, ctypes.POINTER(ctypes.c_ubyte))
|
||||||
ptr = self._recognize_array_func(self.alpr_pointer, pb, len(byte_array))
|
ptr = self._recognize_array_func(self.alpr_pointer, pb, len(byte_array))
|
||||||
json_data = ctypes.cast(ptr, ctypes.c_char_p).value
|
json_data = ctypes.cast(ptr, ctypes.c_char_p).value
|
||||||
|
json_data = _convert_from_charp(json_data)
|
||||||
response_obj = json.loads(json_data)
|
response_obj = json.loads(json_data)
|
||||||
self._free_json_mem_func(ctypes.c_void_p(ptr))
|
self._free_json_mem_func(ctypes.c_void_p(ptr))
|
||||||
|
|
||||||
return response_obj
|
return response_obj
|
||||||
|
|
||||||
def get_version(self):
|
def get_version(self):
|
||||||
|
"""
|
||||||
|
This gets the version of OpenALPR
|
||||||
|
|
||||||
|
:return: Version information
|
||||||
|
"""
|
||||||
|
|
||||||
ptr = self._get_version_func(self.alpr_pointer)
|
ptr = self._get_version_func(self.alpr_pointer)
|
||||||
version_number = ctypes.cast(ptr, ctypes.c_char_p).value
|
version_number = ctypes.cast(ptr, ctypes.c_char_p).value
|
||||||
|
version_number = _convert_from_charp(version_number)
|
||||||
self._free_json_mem_func(ctypes.c_void_p(ptr))
|
self._free_json_mem_func(ctypes.c_void_p(ptr))
|
||||||
|
|
||||||
return version_number
|
return version_number
|
||||||
|
|
||||||
def set_top_n(self, topn):
|
def set_top_n(self, topn):
|
||||||
|
"""
|
||||||
|
Sets the number of returned results when analyzing an image. For example,
|
||||||
|
setting topn = 5 returns the top 5 results.
|
||||||
|
|
||||||
|
:param topn: An integer that represents the number of returned results.
|
||||||
|
:return: None
|
||||||
|
"""
|
||||||
self._set_top_n_func(self.alpr_pointer, topn)
|
self._set_top_n_func(self.alpr_pointer, topn)
|
||||||
|
|
||||||
def set_default_region(self, region):
|
def set_default_region(self, region):
|
||||||
|
"""
|
||||||
|
This sets the default region for detecting license plates. For example,
|
||||||
|
setting region to "us" for United States or "eu" for Europe.
|
||||||
|
|
||||||
|
:param region: A unicode/ascii string (Python 2/3) or bytes array (Python 3)
|
||||||
|
:return: None
|
||||||
|
"""
|
||||||
|
region = _convert_to_charp(region)
|
||||||
self._set_default_region_func(self.alpr_pointer, region)
|
self._set_default_region_func(self.alpr_pointer, region)
|
||||||
|
|
||||||
def set_detect_region(self, enabled):
|
def set_detect_region(self, enabled):
|
||||||
|
"""
|
||||||
|
This allows OpenALPR to attempt to detect the region of a license plate
|
||||||
|
automatically. By default this is disabled, but you can enable it here.
|
||||||
|
|
||||||
|
:param enabled: A boolean representing whether or not auto-detection is enabled
|
||||||
|
:return: None
|
||||||
|
"""
|
||||||
self._set_detect_region_func(self.alpr_pointer, enabled)
|
self._set_detect_region_func(self.alpr_pointer, enabled)
|
||||||
|
|
||||||
|
|
||||||
|
def __del__(self):
|
||||||
|
if self.is_loaded():
|
||||||
|
self.unload()
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __exit__(self, exc_type, exc_val, exc_tb):
|
||||||
|
if self.is_loaded():
|
||||||
|
self.unload()
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user