mirror of
https://github.com/PaddlePaddle/FastDeploy.git
synced 2025-10-06 00:57:33 +08:00
Modify file structure to separate python and cpp code (#223)
Modify code structure
This commit is contained in:
28
python/fastdeploy/__init__.py
Normal file
28
python/fastdeploy/__init__.py
Normal file
@@ -0,0 +1,28 @@
|
||||
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
from __future__ import absolute_import
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
|
||||
from .c_lib_wrap import (Frontend, Backend, FDDataType, TensorInfo, Device,
|
||||
is_built_with_gpu, is_built_with_ort,
|
||||
is_built_with_paddle, is_built_with_trt,
|
||||
get_default_cuda_directory)
|
||||
from .runtime import Runtime, RuntimeOption
|
||||
from .model import FastDeployModel
|
||||
from . import c_lib_wrap as C
|
||||
from . import vision
|
||||
from . import text
|
||||
from .download import download, download_and_decompress
|
180
python/fastdeploy/c_lib_wrap.py.in
Normal file
180
python/fastdeploy/c_lib_wrap.py.in
Normal file
@@ -0,0 +1,180 @@
|
||||
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
from __future__ import absolute_import
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
|
||||
|
||||
def is_built_with_gpu() -> bool:
|
||||
return True if "@WITH_GPU@" == "ON" else False
|
||||
|
||||
|
||||
def is_built_with_ort() -> bool:
|
||||
return True if "@ENABLE_ORT_BACKEND@" == "ON" else False
|
||||
|
||||
|
||||
def is_built_with_trt() -> bool:
|
||||
return True if "@ENABLE_TRT_BACKEND@" == "ON" else False
|
||||
|
||||
|
||||
def is_built_with_paddle() -> bool:
|
||||
return True if "@ENABLE_PADDLE_BACKEND@" == "ON" else False
|
||||
|
||||
def is_built_with_openvino() ->bool:
|
||||
return True if "@ENABLE_OPENVINO_BACKEND@" == "ON" else False
|
||||
|
||||
|
||||
def get_default_cuda_directory() -> str:
|
||||
if not is_built_with_gpu():
|
||||
return ""
|
||||
return r"@CUDA_DIRECTORY@".strip()
|
||||
|
||||
|
||||
def get_default_cuda_major_version() -> str:
|
||||
if not is_built_with_gpu():
|
||||
return ""
|
||||
# TODO(qiuyanjun): get cuda version from cmake.
|
||||
return "11"
|
||||
|
||||
|
||||
def find_cudart(search_dir: str) -> bool:
|
||||
if search_dir is None:
|
||||
print("[FastDeploy][ERROR]: search_dir can not be NoneTpye.")
|
||||
return False
|
||||
# TODO(qiuyanjun): add Linux cudart *.so check
|
||||
cudart_lib_name = f"cudart64_{get_default_cuda_major_version()}0.dll"
|
||||
cudart_lib_path = os.path.join(search_dir, cudart_lib_name)
|
||||
return os.path.exists(cudart_lib_path)
|
||||
|
||||
|
||||
def find_cudart_from_sys() -> bool:
|
||||
# TODO(qiuyanjun): add Linux system paths
|
||||
sys_paths = os.environ["path"].strip().split(";")
|
||||
for sys_path in sys_paths:
|
||||
if find_cudart(sys_path):
|
||||
print(f"[FastDeploy][INFO]: Successfully found CUDA ToolKit from system PATH env -> {sys_path}")
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def add_system_search_paths():
|
||||
# TODO(qiuyanjun): add Linux system paths
|
||||
sys_paths = os.environ["path"].strip().split(";")
|
||||
for sys_path in sys_paths:
|
||||
if os.path.exists(sys_path) and sys.version_info[:2] >= (3, 8):
|
||||
try:
|
||||
os.add_dll_directory(sys_path)
|
||||
except:
|
||||
continue
|
||||
|
||||
|
||||
def add_dll_search_dir(dir_path):
|
||||
os.environ["path"] = dir_path + ";" + os.environ["path"]
|
||||
sys.path.insert(0, dir_path)
|
||||
if sys.version_info[:2] >= (3, 8):
|
||||
os.add_dll_directory(dir_path)
|
||||
|
||||
|
||||
def add_custom_cuda_path():
|
||||
if is_built_with_gpu():
|
||||
# if FastDeploy built with gpu and want to run
|
||||
# in windows, we need to add CUDA_DIRECTORY into
|
||||
# dll search paths to make sure FastDeploy.dll
|
||||
# can link cudart correctly. we search the
|
||||
# default path firstly and try to add into
|
||||
# paths. User should set it manually if the
|
||||
# cuda toolkit is not locate in the default
|
||||
# path we assume.
|
||||
base_url = "https://github.com/PaddlePaddle/FastDeploy/blob/"
|
||||
default_cuda_dir = get_default_cuda_directory()
|
||||
default_cuda_version = get_default_cuda_major_version() # 11
|
||||
cuda_shared_lib_dir = os.path.join(default_cuda_dir, "bin")
|
||||
custom_cuda_envs = ["CUDA_DIRECTORY", "CUDA_HOME", "CUDA_ROOT", "CUDA_PATH"]
|
||||
custom_cuda_dir = "NOTFOUNDED"
|
||||
if not os.path.exists(cuda_shared_lib_dir):
|
||||
# try to get cuda directory from user's local env
|
||||
for custom_env in custom_cuda_envs:
|
||||
custom_cuda_dir = os.getenv(custom_env, "NOTFOUNDED")
|
||||
custom_cuda_dir = custom_cuda_dir.strip().split(";")[0]
|
||||
if os.path.exists(custom_cuda_dir) and custom_cuda_dir != "NOTFOUNDED":
|
||||
break
|
||||
if not os.path.exists(custom_cuda_dir) or custom_cuda_dir == "NOTFOUNDED":
|
||||
logging.warnings.warn(f"\n--- FastDeploy was built with gpu, \
|
||||
\n--- but the default cuda directory does not exists. \
|
||||
\n--- Please setup one of {custom_cuda_envs} manually, \
|
||||
\n--- this path should look like: {default_cuda_dir}. \
|
||||
\n--- Check FAQ: {base_url + 'develop/docs/FAQ.md'}")
|
||||
return
|
||||
# path to cuda dlls
|
||||
cuda_shared_lib_dir = os.path.join(custom_cuda_dir, "bin")
|
||||
add_dll_search_dir(cuda_shared_lib_dir)
|
||||
# try pre find cudart with major version, e.g 11.x/10.x
|
||||
if not find_cudart(cuda_shared_lib_dir):
|
||||
custom_cuda_version = os.path.basename(custom_cuda_dir)
|
||||
logging.warnings.warn(
|
||||
f"\n--- FastDeploy was built with CUDA major version {default_cuda_version}, \
|
||||
\n--- but found custom CUDA version {custom_cuda_version} at {custom_cuda_dir} \
|
||||
\n--- Please setup one of {custom_cuda_envs} manually, \
|
||||
\n--- this path should look like: {default_cuda_dir}. \
|
||||
\n--- Check FAQ: {base_url + 'develop/docs/FAQ.md'}")
|
||||
return
|
||||
print(f"[FastDeploy][INFO]: Successfully found CUDA ToolKit from -> {cuda_shared_lib_dir}")
|
||||
|
||||
|
||||
if os.name == "nt":
|
||||
# cuda/cudnn libs
|
||||
if is_built_with_gpu():
|
||||
add_system_search_paths()
|
||||
if not find_cudart_from_sys():
|
||||
add_custom_cuda_path()
|
||||
|
||||
current_path = os.path.abspath(__file__)
|
||||
dirname = os.path.dirname(current_path)
|
||||
third_libs_dir = os.path.join(dirname, "libs")
|
||||
add_dll_search_dir(third_libs_dir)
|
||||
for root, dirs, filenames in os.walk(third_libs_dir):
|
||||
for d in dirs:
|
||||
if d == "lib" or d == "bin":
|
||||
add_dll_search_dir(os.path.join(dirname, root, d))
|
||||
|
||||
|
||||
try:
|
||||
from .libs.@PY_LIBRARY_NAME@ import *
|
||||
except:
|
||||
raise RuntimeError("FastDeploy initalized failed!")
|
||||
|
||||
|
||||
def TensorInfoStr(tensor_info):
|
||||
message = "TensorInfo(name : '{}', dtype : '{}', shape : '{}')".format(
|
||||
tensor_info.name, tensor_info.dtype, tensor_info.shape)
|
||||
return message
|
||||
|
||||
|
||||
def RuntimeOptionStr(runtime_option):
|
||||
attrs = dir(runtime_option)
|
||||
message = "RuntimeOption(\n"
|
||||
for attr in attrs:
|
||||
if attr.startswith("__"):
|
||||
continue
|
||||
if hasattr(getattr(runtime_option, attr), "__call__"):
|
||||
continue
|
||||
message += " {} : {}\t\n".format(attr, getattr(runtime_option, attr))
|
||||
message.strip("\n")
|
||||
message += ")"
|
||||
return message
|
||||
|
||||
|
||||
TensorInfo.__repr__ = TensorInfoStr
|
||||
RuntimeOption.__repr__ = RuntimeOptionStr
|
187
python/fastdeploy/download.py
Normal file
187
python/fastdeploy/download.py
Normal file
@@ -0,0 +1,187 @@
|
||||
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import os
|
||||
import os.path as osp
|
||||
import shutil
|
||||
import requests
|
||||
import time
|
||||
import zipfile
|
||||
import tarfile
|
||||
import hashlib
|
||||
import tqdm
|
||||
import logging
|
||||
|
||||
DOWNLOAD_RETRY_LIMIT = 3
|
||||
|
||||
|
||||
def md5check(fullname, md5sum=None):
|
||||
if md5sum is None:
|
||||
return True
|
||||
|
||||
logging.info("File {} md5 checking...".format(fullname))
|
||||
md5 = hashlib.md5()
|
||||
with open(fullname, 'rb') as f:
|
||||
for chunk in iter(lambda: f.read(4096), b""):
|
||||
md5.update(chunk)
|
||||
calc_md5sum = md5.hexdigest()
|
||||
|
||||
if calc_md5sum != md5sum:
|
||||
logging.info("File {} md5 check failed, {}(calc) != "
|
||||
"{}(base)".format(fullname, calc_md5sum, md5sum))
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def move_and_merge_tree(src, dst):
|
||||
"""
|
||||
Move src directory to dst, if dst is already exists,
|
||||
merge src to dst
|
||||
"""
|
||||
if not osp.exists(dst):
|
||||
shutil.move(src, dst)
|
||||
else:
|
||||
if not osp.isdir(src):
|
||||
shutil.move(src, dst)
|
||||
return
|
||||
for fp in os.listdir(src):
|
||||
src_fp = osp.join(src, fp)
|
||||
dst_fp = osp.join(dst, fp)
|
||||
if osp.isdir(src_fp):
|
||||
if osp.isdir(dst_fp):
|
||||
move_and_merge_tree(src_fp, dst_fp)
|
||||
else:
|
||||
shutil.move(src_fp, dst_fp)
|
||||
elif osp.isfile(src_fp) and \
|
||||
not osp.isfile(dst_fp):
|
||||
shutil.move(src_fp, dst_fp)
|
||||
|
||||
|
||||
def download(url, path, rename=None, md5sum=None, show_progress=False):
|
||||
"""
|
||||
Download from url, save to path.
|
||||
url (str): download url
|
||||
path (str): download to given path
|
||||
"""
|
||||
if not osp.exists(path):
|
||||
os.makedirs(path)
|
||||
|
||||
fname = osp.split(url)[-1]
|
||||
fullname = osp.join(path, fname)
|
||||
if rename is not None:
|
||||
fullname = osp.join(path, rename)
|
||||
retry_cnt = 0
|
||||
while not (osp.exists(fullname) and md5check(fullname, md5sum)):
|
||||
if retry_cnt < DOWNLOAD_RETRY_LIMIT:
|
||||
retry_cnt += 1
|
||||
else:
|
||||
logging.debug("{} download failed.".format(fname))
|
||||
raise RuntimeError("Download from {} failed. "
|
||||
"Retry limit reached".format(url))
|
||||
|
||||
logging.info("Downloading {} from {}".format(fname, url))
|
||||
|
||||
req = requests.get(url, stream=True)
|
||||
if req.status_code != 200:
|
||||
raise RuntimeError("Downloading from {} failed with code "
|
||||
"{}!".format(url, req.status_code))
|
||||
|
||||
# For protecting download interupted, download to
|
||||
# tmp_fullname firstly, move tmp_fullname to fullname
|
||||
# after download finished
|
||||
tmp_fullname = fullname + "_tmp"
|
||||
total_size = req.headers.get('content-length')
|
||||
with open(tmp_fullname, 'wb') as f:
|
||||
if total_size and show_progress:
|
||||
for chunk in tqdm.tqdm(
|
||||
req.iter_content(chunk_size=1024),
|
||||
total=(int(total_size) + 1023) // 1024,
|
||||
unit='KB'):
|
||||
f.write(chunk)
|
||||
else:
|
||||
for chunk in req.iter_content(chunk_size=1024):
|
||||
if chunk:
|
||||
f.write(chunk)
|
||||
shutil.move(tmp_fullname, fullname)
|
||||
logging.debug("{} download completed.".format(fname))
|
||||
|
||||
return fullname
|
||||
|
||||
|
||||
def decompress(fname):
|
||||
"""
|
||||
Decompress for zip and tar file
|
||||
"""
|
||||
logging.info("Decompressing {}...".format(fname))
|
||||
|
||||
# For protecting decompressing interupted,
|
||||
# decompress to fpath_tmp directory firstly, if decompress
|
||||
# successed, move decompress files to fpath and delete
|
||||
# fpath_tmp and remove download compress file.
|
||||
fpath = osp.split(fname)[0]
|
||||
fpath_tmp = osp.join(fpath, 'tmp')
|
||||
if osp.isdir(fpath_tmp):
|
||||
shutil.rmtree(fpath_tmp)
|
||||
os.makedirs(fpath_tmp)
|
||||
|
||||
if fname.find('.tar') >= 0 or fname.find('.tgz') >= 0:
|
||||
with tarfile.open(fname) as tf:
|
||||
tf.extractall(path=fpath_tmp)
|
||||
elif fname.find('.zip') >= 0:
|
||||
with zipfile.ZipFile(fname) as zf:
|
||||
zf.extractall(path=fpath_tmp)
|
||||
else:
|
||||
raise TypeError("Unsupport compress file type {}".format(fname))
|
||||
|
||||
for f in os.listdir(fpath_tmp):
|
||||
src_dir = osp.join(fpath_tmp, f)
|
||||
dst_dir = osp.join(fpath, f)
|
||||
move_and_merge_tree(src_dir, dst_dir)
|
||||
|
||||
shutil.rmtree(fpath_tmp)
|
||||
logging.debug("{} decompressed.".format(fname))
|
||||
return dst_dir
|
||||
|
||||
|
||||
def url2dir(url, path, rename=None):
|
||||
full_name = download(url, path, rename, show_progress=True)
|
||||
print("File is donwloaded, now extracting...")
|
||||
if url.count(".tgz") > 0 or url.count(".tar") > 0 or url.count("zip") > 0:
|
||||
return decompress(full_name)
|
||||
|
||||
|
||||
def download_and_decompress(url, path='.', rename=None):
|
||||
fname = osp.split(url)[-1]
|
||||
fullname = osp.join(path, fname)
|
||||
# if url.endswith(('tgz', 'tar.gz', 'tar', 'zip')):
|
||||
# fullname = osp.join(path, fname.split('.')[0])
|
||||
nranks = 0
|
||||
if nranks <= 1:
|
||||
dst_dir = url2dir(url, path, rename)
|
||||
if dst_dir is not None:
|
||||
fullname = dst_dir
|
||||
else:
|
||||
lock_path = fullname + '.lock'
|
||||
if not os.path.exists(fullname):
|
||||
with open(lock_path, 'w'):
|
||||
os.utime(lock_path, None)
|
||||
if local_rank == 0:
|
||||
dst_dir = url2dir(url, path, rename)
|
||||
if dst_dir is not None:
|
||||
fullname = dst_dir
|
||||
os.remove(lock_path)
|
||||
else:
|
||||
while os.path.exists(lock_path):
|
||||
time.sleep(1)
|
||||
return
|
0
python/fastdeploy/libs/__init__.py
Normal file
0
python/fastdeploy/libs/__init__.py
Normal file
65
python/fastdeploy/model.py
Normal file
65
python/fastdeploy/model.py
Normal file
@@ -0,0 +1,65 @@
|
||||
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
from __future__ import absolute_import
|
||||
import logging
|
||||
from . import c_lib_wrap as C
|
||||
|
||||
|
||||
class FastDeployModel:
|
||||
def __init__(self, option):
|
||||
self._model = None
|
||||
if option is None:
|
||||
self._runtime_option = C.RuntimeOption()
|
||||
else:
|
||||
self._runtime_option = option._option
|
||||
|
||||
def model_name(self):
|
||||
return self._model.model_name()
|
||||
|
||||
def num_inputs(self):
|
||||
return self._model.num_inputs()
|
||||
|
||||
def num_outputs(self):
|
||||
return self._model.num_outputs()
|
||||
|
||||
def get_input_info(self, index):
|
||||
assert index < self.num_inputs(
|
||||
), "The index:{} must be less than number of inputs:{}.".format(
|
||||
index, self.num_inputs())
|
||||
return self._model.get_input_info(index)
|
||||
|
||||
def get_output_info(self, index):
|
||||
assert index < self.num_outputs(
|
||||
), "The index:{} must be less than number of outputs:{}.".format(
|
||||
index, self.num_outputs())
|
||||
return self._model.get_output_info(index)
|
||||
|
||||
def enable_record_time_of_runtime(self):
|
||||
self._model.enable_record_time_of_runtime()
|
||||
|
||||
def disable_record_time_of_runtime(self):
|
||||
self._model.disable_record_time_of_runtime()
|
||||
|
||||
def print_statis_info_of_runtime(self):
|
||||
return self._model.print_statis_info_of_runtime()
|
||||
|
||||
@property
|
||||
def runtime_option(self):
|
||||
return self._model.runtime_option if self._model is not None else None
|
||||
|
||||
@property
|
||||
def initialized(self):
|
||||
if self._model is None:
|
||||
return False
|
||||
return self._model.initialized()
|
131
python/fastdeploy/runtime.py
Normal file
131
python/fastdeploy/runtime.py
Normal file
@@ -0,0 +1,131 @@
|
||||
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
from __future__ import absolute_import
|
||||
import logging
|
||||
from . import c_lib_wrap as C
|
||||
|
||||
|
||||
class Runtime:
|
||||
def __init__(self, runtime_option):
|
||||
self._runtime = C.Runtime()
|
||||
assert self._runtime.init(
|
||||
runtime_option._option), "Initialize Runtime Failed!"
|
||||
|
||||
def infer(self, data):
|
||||
assert isinstance(data, dict), "The input data should be type of dict."
|
||||
return self._runtime.infer(data)
|
||||
|
||||
def num_inputs(self):
|
||||
return self._runtime.num_inputs()
|
||||
|
||||
def num_outputs(self):
|
||||
return self._runtime.num_outputs()
|
||||
|
||||
def get_input_info(self, index):
|
||||
assert isinstance(
|
||||
index, int), "The input parameter index should be type of int."
|
||||
assert index < self.num_inputs(
|
||||
), "The input parameter index:{} should less than number of inputs:{}.".format(
|
||||
index, self.num_inputs)
|
||||
return self._runtime.get_input_info(index)
|
||||
|
||||
def get_output_info(self, index):
|
||||
assert isinstance(
|
||||
index, int), "The input parameter index should be type of int."
|
||||
assert index < self.num_outputs(
|
||||
), "The input parameter index:{} should less than number of outputs:{}.".format(
|
||||
index, self.num_outputs)
|
||||
return self._runtime.get_output_info(index)
|
||||
|
||||
|
||||
class RuntimeOption:
|
||||
def __init__(self):
|
||||
self._option = C.RuntimeOption()
|
||||
|
||||
def set_model_path(self, model_path, params_path="",
|
||||
model_format="paddle"):
|
||||
return self._option.set_model_path(model_path, params_path,
|
||||
model_format)
|
||||
|
||||
def use_gpu(self, device_id=0):
|
||||
return self._option.use_gpu(device_id)
|
||||
|
||||
def use_cpu(self):
|
||||
return self._option.use_cpu()
|
||||
|
||||
def set_cpu_thread_num(self, thread_num=-1):
|
||||
return self._option.set_cpu_thread_num(thread_num)
|
||||
|
||||
def use_paddle_backend(self):
|
||||
return self._option.use_paddle_backend()
|
||||
|
||||
def use_ort_backend(self):
|
||||
return self._option.use_ort_backend()
|
||||
|
||||
def use_trt_backend(self):
|
||||
return self._option.use_trt_backend()
|
||||
|
||||
def use_openvino_backend(self):
|
||||
return self._option.use_openvino_backend()
|
||||
|
||||
def enable_paddle_mkldnn(self):
|
||||
return self._option.enable_paddle_mkldnn()
|
||||
|
||||
def disable_paddle_mkldnn(self):
|
||||
return self._option.disable_paddle_mkldnn()
|
||||
|
||||
def enable_paddle_log_info(self):
|
||||
return self._option.enable_paddle_log_info()
|
||||
|
||||
def disable_paddle_log_info(self):
|
||||
return self._option.disable_paddle_log_info()
|
||||
|
||||
def set_paddle_mkldnn_cache_size(self, cache_size):
|
||||
return self._option.set_paddle_mkldnn_cache_size(cache_size)
|
||||
|
||||
def set_trt_input_shape(self,
|
||||
tensor_name,
|
||||
min_shape,
|
||||
opt_shape=None,
|
||||
max_shape=None):
|
||||
if opt_shape is None and max_shape is None:
|
||||
opt_shape = min_shape
|
||||
max_shape = min_shape
|
||||
else:
|
||||
assert opt_shape is not None and max_shape is not None, "Set min_shape only, or set min_shape, opt_shape, max_shape both."
|
||||
return self._option.set_trt_input_shape(tensor_name, min_shape,
|
||||
opt_shape, max_shape)
|
||||
|
||||
def set_trt_cache_file(self, cache_file_path):
|
||||
return self._option.set_trt_cache_file(cache_file_path)
|
||||
|
||||
def enable_trt_fp16(self):
|
||||
return self._option.enable_trt_fp16()
|
||||
|
||||
def disable_trt_fp16(self):
|
||||
return self._option.disable_trt_fp16()
|
||||
|
||||
def __repr__(self):
|
||||
attrs = dir(self._option)
|
||||
message = "RuntimeOption(\n"
|
||||
for attr in attrs:
|
||||
if attr.startswith("__"):
|
||||
continue
|
||||
if hasattr(getattr(self._option, attr), "__call__"):
|
||||
continue
|
||||
message += " {} : {}\t\n".format(attr,
|
||||
getattr(self._option, attr))
|
||||
message.strip("\n")
|
||||
message += ")"
|
||||
return message
|
16
python/fastdeploy/text/__init__.py
Normal file
16
python/fastdeploy/text/__init__.py
Normal file
@@ -0,0 +1,16 @@
|
||||
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
from __future__ import absolute_import
|
||||
|
||||
from . import uie
|
73
python/fastdeploy/text/uie/__init__.py
Normal file
73
python/fastdeploy/text/uie/__init__.py
Normal file
@@ -0,0 +1,73 @@
|
||||
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
import logging
|
||||
from ... import Frontend
|
||||
from ... import RuntimeOption
|
||||
from ... import c_lib_wrap as C
|
||||
|
||||
|
||||
class SchemaNode(object):
|
||||
def __init__(self, name, children=[]):
|
||||
schema_node_children = []
|
||||
for child in children:
|
||||
if isinstance(child, str):
|
||||
schema_node_children += [C.text.SchemaNode(child, [])]
|
||||
elif isinstance(child, dict):
|
||||
for key, val in child.item():
|
||||
schema_node_child = SchemaNode(key, val)
|
||||
schema_node_children += [schema_node_child._schema_node]
|
||||
else:
|
||||
assert "The type of child of SchemaNode should be str or dict."
|
||||
self._schema_node = C.text.SchemaNode(name, schema_node_children)
|
||||
self._schema_node_children = schema_node_children
|
||||
|
||||
|
||||
class UIEModel(object):
|
||||
def __init__(self,
|
||||
model_file,
|
||||
params_file,
|
||||
vocab_file,
|
||||
position_prob=0.5,
|
||||
max_length=128,
|
||||
schema=[],
|
||||
runtime_option=RuntimeOption(),
|
||||
model_format=Frontend.PADDLE):
|
||||
if isinstance(schema, list):
|
||||
schema = SchemaNode("", schema)._schema_node_children
|
||||
elif isinstance(schema, dict):
|
||||
schema_tmp = []
|
||||
for key, val in schema.items():
|
||||
schema_tmp += [SchemaNode(key, val)._schema_node]
|
||||
schema = schema_tmp
|
||||
else:
|
||||
assert "The type of schema should be list or dict."
|
||||
self._model = C.text.UIEModel(model_file, params_file, vocab_file,
|
||||
position_prob, max_length, schema,
|
||||
runtime_option._option, model_format)
|
||||
|
||||
def set_schema(self, schema):
|
||||
if isinstance(schema, list):
|
||||
schema = SchemaNode("", schema)._schema_node_children
|
||||
elif isinstance(schema, dict):
|
||||
schema_tmp = []
|
||||
for key, val in schema.items():
|
||||
schema_tmp += [SchemaNode(key, val)._schema_node]
|
||||
schema = schema_tmp
|
||||
self._model.set_schema(schema)
|
||||
|
||||
def predict(self, texts):
|
||||
return self._model.predict(texts)
|
25
python/fastdeploy/vision/__init__.py
Normal file
25
python/fastdeploy/vision/__init__.py
Normal file
@@ -0,0 +1,25 @@
|
||||
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
from __future__ import absolute_import
|
||||
|
||||
from . import detection
|
||||
from . import classification
|
||||
from . import segmentation
|
||||
|
||||
from . import matting
|
||||
from . import facedet
|
||||
from . import faceid
|
||||
from . import ocr
|
||||
from . import evaluation
|
||||
from .visualize import *
|
30
python/fastdeploy/vision/classification/__init__.py
Normal file
30
python/fastdeploy/vision/classification/__init__.py
Normal file
@@ -0,0 +1,30 @@
|
||||
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
from __future__ import absolute_import
|
||||
|
||||
from .ppcls import PaddleClasModel
|
||||
|
||||
PPLCNet = PaddleClasModel
|
||||
PPLCNetv2 = PaddleClasModel
|
||||
EfficientNet = PaddleClasModel
|
||||
GhostNet = PaddleClasModel
|
||||
MobileNetv1 = PaddleClasModel
|
||||
MobileNetv2 = PaddleClasModel
|
||||
MobileNetv3 = PaddleClasModel
|
||||
ShuffleNetv2 = PaddleClasModel
|
||||
SqueezeNet = PaddleClasModel
|
||||
Inceptionv3 = PaddleClasModel
|
||||
PPHGNet = PaddleClasModel
|
||||
ResNet50vd = PaddleClasModel
|
||||
SwinTransformer = PaddleClasModel
|
37
python/fastdeploy/vision/classification/ppcls/__init__.py
Normal file
37
python/fastdeploy/vision/classification/ppcls/__init__.py
Normal file
@@ -0,0 +1,37 @@
|
||||
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import
|
||||
import logging
|
||||
from .... import FastDeployModel, Frontend
|
||||
from .... import c_lib_wrap as C
|
||||
|
||||
|
||||
class PaddleClasModel(FastDeployModel):
|
||||
def __init__(self,
|
||||
model_file,
|
||||
params_file,
|
||||
config_file,
|
||||
runtime_option=None,
|
||||
model_format=Frontend.PADDLE):
|
||||
super(PaddleClasModel, self).__init__(runtime_option)
|
||||
|
||||
assert model_format == Frontend.PADDLE, "PaddleClasModel only support model format of Frontend.Paddle now."
|
||||
self._model = C.vision.classification.PaddleClasModel(
|
||||
model_file, params_file, config_file, self._runtime_option,
|
||||
model_format)
|
||||
assert self.initialized, "PaddleClas model initialize failed."
|
||||
|
||||
def predict(self, input_image, topk=1):
|
||||
return self._model.predict(input_image, topk)
|
26
python/fastdeploy/vision/detection/__init__.py
Normal file
26
python/fastdeploy/vision/detection/__init__.py
Normal file
@@ -0,0 +1,26 @@
|
||||
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import
|
||||
from .contrib.yolov7 import YOLOv7
|
||||
from .contrib.yolor import YOLOR
|
||||
from .contrib.scaled_yolov4 import ScaledYOLOv4
|
||||
from .contrib.nanodet_plus import NanoDetPlus
|
||||
from .contrib.yolox import YOLOX
|
||||
from .contrib.yolov5 import YOLOv5
|
||||
from .contrib.yolov5lite import YOLOv5Lite
|
||||
from .contrib.yolov6 import YOLOv6
|
||||
from .contrib.yolov7end2end_trt import YOLOv7End2EndTRT
|
||||
from .contrib.yolov7end2end_ort import YOLOv7End2EndORT
|
||||
from .ppdet import PPYOLOE, PPYOLO, PPYOLOv2, PaddleYOLOX, PicoDet, FasterRCNN, YOLOv3, MaskRCNN
|
15
python/fastdeploy/vision/detection/contrib/__init__.py
Normal file
15
python/fastdeploy/vision/detection/contrib/__init__.py
Normal file
@@ -0,0 +1,15 @@
|
||||
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import
|
105
python/fastdeploy/vision/detection/contrib/nanodet_plus.py
Normal file
105
python/fastdeploy/vision/detection/contrib/nanodet_plus.py
Normal file
@@ -0,0 +1,105 @@
|
||||
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import
|
||||
import logging
|
||||
from .... import FastDeployModel, Frontend
|
||||
from .... import c_lib_wrap as C
|
||||
|
||||
|
||||
class NanoDetPlus(FastDeployModel):
|
||||
def __init__(self,
|
||||
model_file,
|
||||
params_file="",
|
||||
runtime_option=None,
|
||||
model_format=Frontend.ONNX):
|
||||
# 调用基函数进行backend_option的初始化
|
||||
# 初始化后的option保存在self._runtime_option
|
||||
super(NanoDetPlus, self).__init__(runtime_option)
|
||||
|
||||
self._model = C.vision.detection.NanoDetPlus(
|
||||
model_file, params_file, self._runtime_option, model_format)
|
||||
# 通过self.initialized判断整个模型的初始化是否成功
|
||||
assert self.initialized, "NanoDetPlus initialize failed."
|
||||
|
||||
def predict(self, input_image, conf_threshold=0.25, nms_iou_threshold=0.5):
|
||||
return self._model.predict(input_image, conf_threshold,
|
||||
nms_iou_threshold)
|
||||
|
||||
# 一些跟NanoDetPlus模型有关的属性封装
|
||||
# 多数是预处理相关,可通过修改如model.size = [416, 416]改变预处理时resize的大小(前提是模型支持)
|
||||
@property
|
||||
def size(self):
|
||||
return self._model.size
|
||||
|
||||
@property
|
||||
def padding_value(self):
|
||||
return self._model.padding_value
|
||||
|
||||
@property
|
||||
def keep_ratio(self):
|
||||
return self._model.keep_ratio
|
||||
|
||||
@property
|
||||
def downsample_strides(self):
|
||||
return self._model.downsample_strides
|
||||
|
||||
@property
|
||||
def max_wh(self):
|
||||
return self._model.max_wh
|
||||
|
||||
@property
|
||||
def reg_max(self):
|
||||
return self._model.reg_max
|
||||
|
||||
@size.setter
|
||||
def size(self, wh):
|
||||
assert isinstance(wh, (list, tuple)),\
|
||||
"The value to set `size` must be type of tuple or list."
|
||||
assert len(wh) == 2,\
|
||||
"The value to set `size` must contatins 2 elements means [width, height], but now it contains {} elements.".format(
|
||||
len(wh))
|
||||
self._model.size = wh
|
||||
|
||||
@padding_value.setter
|
||||
def padding_value(self, value):
|
||||
assert isinstance(
|
||||
value,
|
||||
list), "The value to set `padding_value` must be type of list."
|
||||
self._model.padding_value = value
|
||||
|
||||
@keep_ratio.setter
|
||||
def keep_ratio(self, value):
|
||||
assert isinstance(
|
||||
value, bool), "The value to set `keep_ratio` must be type of bool."
|
||||
self._model.keep_ratio = value
|
||||
|
||||
@downsample_strides.setter
|
||||
def downsample_strides(self, value):
|
||||
assert isinstance(
|
||||
value,
|
||||
list), "The value to set `downsample_strides` must be type of list."
|
||||
self._model.downsample_strides = value
|
||||
|
||||
@max_wh.setter
|
||||
def max_wh(self, value):
|
||||
assert isinstance(
|
||||
value, float), "The value to set `max_wh` must be type of float."
|
||||
self._model.max_wh = value
|
||||
|
||||
@reg_max.setter
|
||||
def reg_max(self, value):
|
||||
assert isinstance(
|
||||
value, int), "The value to set `reg_max` must be type of int."
|
||||
self._model.reg_max = value
|
116
python/fastdeploy/vision/detection/contrib/scaled_yolov4.py
Normal file
116
python/fastdeploy/vision/detection/contrib/scaled_yolov4.py
Normal file
@@ -0,0 +1,116 @@
|
||||
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import
|
||||
import logging
|
||||
from .... import FastDeployModel, Frontend
|
||||
from .... import c_lib_wrap as C
|
||||
|
||||
|
||||
class ScaledYOLOv4(FastDeployModel):
|
||||
def __init__(self,
|
||||
model_file,
|
||||
params_file="",
|
||||
runtime_option=None,
|
||||
model_format=Frontend.ONNX):
|
||||
# 调用基函数进行backend_option的初始化
|
||||
# 初始化后的option保存在self._runtime_option
|
||||
super(ScaledYOLOv4, self).__init__(runtime_option)
|
||||
|
||||
self._model = C.vision.detection.ScaledYOLOv4(
|
||||
model_file, params_file, self._runtime_option, model_format)
|
||||
# 通过self.initialized判断整个模型的初始化是否成功
|
||||
assert self.initialized, "ScaledYOLOv4 initialize failed."
|
||||
|
||||
def predict(self, input_image, conf_threshold=0.25, nms_iou_threshold=0.5):
|
||||
return self._model.predict(input_image, conf_threshold,
|
||||
nms_iou_threshold)
|
||||
|
||||
# 一些跟ScaledYOLOv4模型有关的属性封装
|
||||
# 多数是预处理相关,可通过修改如model.size = [1280, 1280]改变预处理时resize的大小(前提是模型支持)
|
||||
@property
|
||||
def size(self):
|
||||
return self._model.size
|
||||
|
||||
@property
|
||||
def padding_value(self):
|
||||
return self._model.padding_value
|
||||
|
||||
@property
|
||||
def is_no_pad(self):
|
||||
return self._model.is_no_pad
|
||||
|
||||
@property
|
||||
def is_mini_pad(self):
|
||||
return self._model.is_mini_pad
|
||||
|
||||
@property
|
||||
def is_scale_up(self):
|
||||
return self._model.is_scale_up
|
||||
|
||||
@property
|
||||
def stride(self):
|
||||
return self._model.stride
|
||||
|
||||
@property
|
||||
def max_wh(self):
|
||||
return self._model.max_wh
|
||||
|
||||
@size.setter
|
||||
def size(self, wh):
|
||||
assert isinstance(wh, (list, tuple)),\
|
||||
"The value to set `size` must be type of tuple or list."
|
||||
assert len(wh) == 2,\
|
||||
"The value to set `size` must contatins 2 elements means [width, height], but now it contains {} elements.".format(
|
||||
len(wh))
|
||||
self._model.size = wh
|
||||
|
||||
@padding_value.setter
|
||||
def padding_value(self, value):
|
||||
assert isinstance(
|
||||
value,
|
||||
list), "The value to set `padding_value` must be type of list."
|
||||
self._model.padding_value = value
|
||||
|
||||
@is_no_pad.setter
|
||||
def is_no_pad(self, value):
|
||||
assert isinstance(
|
||||
value, bool), "The value to set `is_no_pad` must be type of bool."
|
||||
self._model.is_no_pad = value
|
||||
|
||||
@is_mini_pad.setter
|
||||
def is_mini_pad(self, value):
|
||||
assert isinstance(
|
||||
value,
|
||||
bool), "The value to set `is_mini_pad` must be type of bool."
|
||||
self._model.is_mini_pad = value
|
||||
|
||||
@is_scale_up.setter
|
||||
def is_scale_up(self, value):
|
||||
assert isinstance(
|
||||
value,
|
||||
bool), "The value to set `is_scale_up` must be type of bool."
|
||||
self._model.is_scale_up = value
|
||||
|
||||
@stride.setter
|
||||
def stride(self, value):
|
||||
assert isinstance(
|
||||
value, int), "The value to set `stride` must be type of int."
|
||||
self._model.stride = value
|
||||
|
||||
@max_wh.setter
|
||||
def max_wh(self, value):
|
||||
assert isinstance(
|
||||
value, float), "The value to set `max_wh` must be type of float."
|
||||
self._model.max_wh = value
|
116
python/fastdeploy/vision/detection/contrib/yolor.py
Normal file
116
python/fastdeploy/vision/detection/contrib/yolor.py
Normal file
@@ -0,0 +1,116 @@
|
||||
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import
|
||||
import logging
|
||||
from .... import FastDeployModel, Frontend
|
||||
from .... import c_lib_wrap as C
|
||||
|
||||
|
||||
class YOLOR(FastDeployModel):
|
||||
def __init__(self,
|
||||
model_file,
|
||||
params_file="",
|
||||
runtime_option=None,
|
||||
model_format=Frontend.ONNX):
|
||||
# 调用基函数进行backend_option的初始化
|
||||
# 初始化后的option保存在self._runtime_option
|
||||
super(YOLOR, self).__init__(runtime_option)
|
||||
|
||||
self._model = C.vision.detection.YOLOR(
|
||||
model_file, params_file, self._runtime_option, model_format)
|
||||
# 通过self.initialized判断整个模型的初始化是否成功
|
||||
assert self.initialized, "YOLOR initialize failed."
|
||||
|
||||
def predict(self, input_image, conf_threshold=0.25, nms_iou_threshold=0.5):
|
||||
return self._model.predict(input_image, conf_threshold,
|
||||
nms_iou_threshold)
|
||||
|
||||
# 一些跟YOLOR模型有关的属性封装
|
||||
# 多数是预处理相关,可通过修改如model.size = [1280, 1280]改变预处理时resize的大小(前提是模型支持)
|
||||
@property
|
||||
def size(self):
|
||||
return self._model.size
|
||||
|
||||
@property
|
||||
def padding_value(self):
|
||||
return self._model.padding_value
|
||||
|
||||
@property
|
||||
def is_no_pad(self):
|
||||
return self._model.is_no_pad
|
||||
|
||||
@property
|
||||
def is_mini_pad(self):
|
||||
return self._model.is_mini_pad
|
||||
|
||||
@property
|
||||
def is_scale_up(self):
|
||||
return self._model.is_scale_up
|
||||
|
||||
@property
|
||||
def stride(self):
|
||||
return self._model.stride
|
||||
|
||||
@property
|
||||
def max_wh(self):
|
||||
return self._model.max_wh
|
||||
|
||||
@size.setter
|
||||
def size(self, wh):
|
||||
assert isinstance(wh, (list, tuple)),\
|
||||
"The value to set `size` must be type of tuple or list."
|
||||
assert len(wh) == 2,\
|
||||
"The value to set `size` must contatins 2 elements means [width, height], but now it contains {} elements.".format(
|
||||
len(wh))
|
||||
self._model.size = wh
|
||||
|
||||
@padding_value.setter
|
||||
def padding_value(self, value):
|
||||
assert isinstance(
|
||||
value,
|
||||
list), "The value to set `padding_value` must be type of list."
|
||||
self._model.padding_value = value
|
||||
|
||||
@is_no_pad.setter
|
||||
def is_no_pad(self, value):
|
||||
assert isinstance(
|
||||
value, bool), "The value to set `is_no_pad` must be type of bool."
|
||||
self._model.is_no_pad = value
|
||||
|
||||
@is_mini_pad.setter
|
||||
def is_mini_pad(self, value):
|
||||
assert isinstance(
|
||||
value,
|
||||
bool), "The value to set `is_mini_pad` must be type of bool."
|
||||
self._model.is_mini_pad = value
|
||||
|
||||
@is_scale_up.setter
|
||||
def is_scale_up(self, value):
|
||||
assert isinstance(
|
||||
value,
|
||||
bool), "The value to set `is_scale_up` must be type of bool."
|
||||
self._model.is_scale_up = value
|
||||
|
||||
@stride.setter
|
||||
def stride(self, value):
|
||||
assert isinstance(
|
||||
value, int), "The value to set `stride` must be type of int."
|
||||
self._model.stride = value
|
||||
|
||||
@max_wh.setter
|
||||
def max_wh(self, value):
|
||||
assert isinstance(
|
||||
value, float), "The value to set `max_wh` must be type of float."
|
||||
self._model.max_wh = value
|
127
python/fastdeploy/vision/detection/contrib/yolov5.py
Normal file
127
python/fastdeploy/vision/detection/contrib/yolov5.py
Normal file
@@ -0,0 +1,127 @@
|
||||
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import
|
||||
import logging
|
||||
from .... import FastDeployModel, Frontend
|
||||
from .... import c_lib_wrap as C
|
||||
|
||||
|
||||
class YOLOv5(FastDeployModel):
|
||||
def __init__(self,
|
||||
model_file,
|
||||
params_file="",
|
||||
runtime_option=None,
|
||||
model_format=Frontend.ONNX):
|
||||
# 调用基函数进行backend_option的初始化
|
||||
# 初始化后的option保存在self._runtime_option
|
||||
super(YOLOv5, self).__init__(runtime_option)
|
||||
|
||||
self._model = C.vision.detection.YOLOv5(
|
||||
model_file, params_file, self._runtime_option, model_format)
|
||||
# 通过self.initialized判断整个模型的初始化是否成功
|
||||
assert self.initialized, "YOLOv5 initialize failed."
|
||||
|
||||
def predict(self, input_image, conf_threshold=0.25, nms_iou_threshold=0.5):
|
||||
return self._model.predict(input_image, conf_threshold,
|
||||
nms_iou_threshold)
|
||||
|
||||
# 一些跟YOLOv5模型有关的属性封装
|
||||
# 多数是预处理相关,可通过修改如model.size = [1280, 1280]改变预处理时resize的大小(前提是模型支持)
|
||||
@property
|
||||
def size(self):
|
||||
return self._model.size
|
||||
|
||||
@property
|
||||
def padding_value(self):
|
||||
return self._model.padding_value
|
||||
|
||||
@property
|
||||
def is_no_pad(self):
|
||||
return self._model.is_no_pad
|
||||
|
||||
@property
|
||||
def is_mini_pad(self):
|
||||
return self._model.is_mini_pad
|
||||
|
||||
@property
|
||||
def is_scale_up(self):
|
||||
return self._model.is_scale_up
|
||||
|
||||
@property
|
||||
def stride(self):
|
||||
return self._model.stride
|
||||
|
||||
@property
|
||||
def max_wh(self):
|
||||
return self._model.max_wh
|
||||
|
||||
@property
|
||||
def multi_label(self):
|
||||
return self._model.multi_label
|
||||
|
||||
@size.setter
|
||||
def size(self, wh):
|
||||
assert isinstance(wh, (list, tuple)),\
|
||||
"The value to set `size` must be type of tuple or list."
|
||||
assert len(wh) == 2,\
|
||||
"The value to set `size` must contatins 2 elements means [width, height], but now it contains {} elements.".format(
|
||||
len(wh))
|
||||
self._model.size = wh
|
||||
|
||||
@padding_value.setter
|
||||
def padding_value(self, value):
|
||||
assert isinstance(
|
||||
value,
|
||||
list), "The value to set `padding_value` must be type of list."
|
||||
self._model.padding_value = value
|
||||
|
||||
@is_no_pad.setter
|
||||
def is_no_pad(self, value):
|
||||
assert isinstance(
|
||||
value, bool), "The value to set `is_no_pad` must be type of bool."
|
||||
self._model.is_no_pad = value
|
||||
|
||||
@is_mini_pad.setter
|
||||
def is_mini_pad(self, value):
|
||||
assert isinstance(
|
||||
value,
|
||||
bool), "The value to set `is_mini_pad` must be type of bool."
|
||||
self._model.is_mini_pad = value
|
||||
|
||||
@is_scale_up.setter
|
||||
def is_scale_up(self, value):
|
||||
assert isinstance(
|
||||
value,
|
||||
bool), "The value to set `is_scale_up` must be type of bool."
|
||||
self._model.is_scale_up = value
|
||||
|
||||
@stride.setter
|
||||
def stride(self, value):
|
||||
assert isinstance(
|
||||
value, int), "The value to set `stride` must be type of int."
|
||||
self._model.stride = value
|
||||
|
||||
@max_wh.setter
|
||||
def max_wh(self, value):
|
||||
assert isinstance(
|
||||
value, float), "The value to set `max_wh` must be type of float."
|
||||
self._model.max_wh = value
|
||||
|
||||
@multi_label.setter
|
||||
def multi_label(self, value):
|
||||
assert isinstance(
|
||||
value,
|
||||
bool), "The value to set `multi_label` must be type of bool."
|
||||
self._model.multi_label = value
|
139
python/fastdeploy/vision/detection/contrib/yolov5lite.py
Normal file
139
python/fastdeploy/vision/detection/contrib/yolov5lite.py
Normal file
@@ -0,0 +1,139 @@
|
||||
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import
|
||||
import logging
|
||||
from .... import FastDeployModel, Frontend
|
||||
from .... import c_lib_wrap as C
|
||||
|
||||
|
||||
class YOLOv5Lite(FastDeployModel):
|
||||
def __init__(self,
|
||||
model_file,
|
||||
params_file="",
|
||||
runtime_option=None,
|
||||
model_format=Frontend.ONNX):
|
||||
# 调用基函数进行backend_option的初始化
|
||||
# 初始化后的option保存在self._runtime_option
|
||||
super(YOLOv5Lite, self).__init__(runtime_option)
|
||||
|
||||
self._model = C.vision.detection.YOLOv5Lite(
|
||||
model_file, params_file, self._runtime_option, model_format)
|
||||
# 通过self.initialized判断整个模型的初始化是否成功
|
||||
assert self.initialized, "YOLOv5Lite initialize failed."
|
||||
|
||||
def predict(self, input_image, conf_threshold=0.25, nms_iou_threshold=0.5):
|
||||
return self._model.predict(input_image, conf_threshold,
|
||||
nms_iou_threshold)
|
||||
|
||||
# 一些跟YOLOv5Lite模型有关的属性封装
|
||||
# 多数是预处理相关,可通过修改如model.size = [1280, 1280]改变预处理时resize的大小(前提是模型支持)
|
||||
@property
|
||||
def size(self):
|
||||
return self._model.size
|
||||
|
||||
@property
|
||||
def padding_value(self):
|
||||
return self._model.padding_value
|
||||
|
||||
@property
|
||||
def is_no_pad(self):
|
||||
return self._model.is_no_pad
|
||||
|
||||
@property
|
||||
def is_mini_pad(self):
|
||||
return self._model.is_mini_pad
|
||||
|
||||
@property
|
||||
def is_scale_up(self):
|
||||
return self._model.is_scale_up
|
||||
|
||||
@property
|
||||
def stride(self):
|
||||
return self._model.stride
|
||||
|
||||
@property
|
||||
def max_wh(self):
|
||||
return self._model.max_wh
|
||||
|
||||
@property
|
||||
def is_decode_exported(self):
|
||||
return self._model.is_decode_exported
|
||||
|
||||
@property
|
||||
def anchor_config(self):
|
||||
return self._model.anchor_config
|
||||
|
||||
@size.setter
|
||||
def size(self, wh):
|
||||
assert isinstance(wh, (list, tuple)),\
|
||||
"The value to set `size` must be type of tuple or list."
|
||||
assert len(wh) == 2,\
|
||||
"The value to set `size` must contatins 2 elements means [width, height], but now it contains {} elements.".format(
|
||||
len(wh))
|
||||
self._model.size = wh
|
||||
|
||||
@padding_value.setter
|
||||
def padding_value(self, value):
|
||||
assert isinstance(
|
||||
value,
|
||||
list), "The value to set `padding_value` must be type of list."
|
||||
self._model.padding_value = value
|
||||
|
||||
@is_no_pad.setter
|
||||
def is_no_pad(self, value):
|
||||
assert isinstance(
|
||||
value, bool), "The value to set `is_no_pad` must be type of bool."
|
||||
self._model.is_no_pad = value
|
||||
|
||||
@is_mini_pad.setter
|
||||
def is_mini_pad(self, value):
|
||||
assert isinstance(
|
||||
value,
|
||||
bool), "The value to set `is_mini_pad` must be type of bool."
|
||||
self._model.is_mini_pad = value
|
||||
|
||||
@is_scale_up.setter
|
||||
def is_scale_up(self, value):
|
||||
assert isinstance(
|
||||
value,
|
||||
bool), "The value to set `is_scale_up` must be type of bool."
|
||||
self._model.is_scale_up = value
|
||||
|
||||
@stride.setter
|
||||
def stride(self, value):
|
||||
assert isinstance(
|
||||
value, int), "The value to set `stride` must be type of int."
|
||||
self._model.stride = value
|
||||
|
||||
@max_wh.setter
|
||||
def max_wh(self, value):
|
||||
assert isinstance(
|
||||
value, float), "The value to set `max_wh` must be type of float."
|
||||
self._model.max_wh = value
|
||||
|
||||
@is_decode_exported.setter
|
||||
def is_decode_exported(self, value):
|
||||
assert isinstance(
|
||||
value,
|
||||
bool), "The value to set `is_decode_exported` must be type of bool."
|
||||
self._model.is_decode_exported = value
|
||||
|
||||
@anchor_config.setter
|
||||
def anchor_config(self, anchor_config_val):
|
||||
assert isinstance(anchor_config_val, list),\
|
||||
"The value to set `anchor_config` must be type of tuple or list."
|
||||
assert isinstance(anchor_config_val[0], list),\
|
||||
"The value to set `anchor_config` must be 2-dimensions tuple or list"
|
||||
self._model.anchor_config = anchor_config_val
|
116
python/fastdeploy/vision/detection/contrib/yolov6.py
Normal file
116
python/fastdeploy/vision/detection/contrib/yolov6.py
Normal file
@@ -0,0 +1,116 @@
|
||||
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import
|
||||
import logging
|
||||
from .... import FastDeployModel, Frontend
|
||||
from .... import c_lib_wrap as C
|
||||
|
||||
|
||||
class YOLOv6(FastDeployModel):
|
||||
def __init__(self,
|
||||
model_file,
|
||||
params_file="",
|
||||
runtime_option=None,
|
||||
model_format=Frontend.ONNX):
|
||||
# 调用基函数进行backend_option的初始化
|
||||
# 初始化后的option保存在self._runtime_option
|
||||
super(YOLOv6, self).__init__(runtime_option)
|
||||
|
||||
self._model = C.vision.detection.YOLOv6(
|
||||
model_file, params_file, self._runtime_option, model_format)
|
||||
# 通过self.initialized判断整个模型的初始化是否成功
|
||||
assert self.initialized, "YOLOv6 initialize failed."
|
||||
|
||||
def predict(self, input_image, conf_threshold=0.25, nms_iou_threshold=0.5):
|
||||
return self._model.predict(input_image, conf_threshold,
|
||||
nms_iou_threshold)
|
||||
|
||||
# 一些跟YOLOv6模型有关的属性封装
|
||||
# 多数是预处理相关,可通过修改如model.size = [1280, 1280]改变预处理时resize的大小(前提是模型支持)
|
||||
@property
|
||||
def size(self):
|
||||
return self._model.size
|
||||
|
||||
@property
|
||||
def padding_value(self):
|
||||
return self._model.padding_value
|
||||
|
||||
@property
|
||||
def is_no_pad(self):
|
||||
return self._model.is_no_pad
|
||||
|
||||
@property
|
||||
def is_mini_pad(self):
|
||||
return self._model.is_mini_pad
|
||||
|
||||
@property
|
||||
def is_scale_up(self):
|
||||
return self._model.is_scale_up
|
||||
|
||||
@property
|
||||
def stride(self):
|
||||
return self._model.stride
|
||||
|
||||
@property
|
||||
def max_wh(self):
|
||||
return self._model.max_wh
|
||||
|
||||
@size.setter
|
||||
def size(self, wh):
|
||||
assert isinstance(wh, (list, tuple)),\
|
||||
"The value to set `size` must be type of tuple or list."
|
||||
assert len(wh) == 2,\
|
||||
"The value to set `size` must contatins 2 elements means [width, height], but now it contains {} elements.".format(
|
||||
len(wh))
|
||||
self._model.size = wh
|
||||
|
||||
@padding_value.setter
|
||||
def padding_value(self, value):
|
||||
assert isinstance(
|
||||
value,
|
||||
list), "The value to set `padding_value` must be type of list."
|
||||
self._model.padding_value = value
|
||||
|
||||
@is_no_pad.setter
|
||||
def is_no_pad(self, value):
|
||||
assert isinstance(
|
||||
value, bool), "The value to set `is_no_pad` must be type of bool."
|
||||
self._model.is_no_pad = value
|
||||
|
||||
@is_mini_pad.setter
|
||||
def is_mini_pad(self, value):
|
||||
assert isinstance(
|
||||
value,
|
||||
bool), "The value to set `is_mini_pad` must be type of bool."
|
||||
self._model.is_mini_pad = value
|
||||
|
||||
@is_scale_up.setter
|
||||
def is_scale_up(self, value):
|
||||
assert isinstance(
|
||||
value,
|
||||
bool), "The value to set `is_scale_up` must be type of bool."
|
||||
self._model.is_scale_up = value
|
||||
|
||||
@stride.setter
|
||||
def stride(self, value):
|
||||
assert isinstance(
|
||||
value, int), "The value to set `stride` must be type of int."
|
||||
self._model.stride = value
|
||||
|
||||
@max_wh.setter
|
||||
def max_wh(self, value):
|
||||
assert isinstance(
|
||||
value, float), "The value to set `max_wh` must be type of float."
|
||||
self._model.max_wh = value
|
116
python/fastdeploy/vision/detection/contrib/yolov7.py
Normal file
116
python/fastdeploy/vision/detection/contrib/yolov7.py
Normal file
@@ -0,0 +1,116 @@
|
||||
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import
|
||||
import logging
|
||||
from .... import FastDeployModel, Frontend
|
||||
from .... import c_lib_wrap as C
|
||||
|
||||
|
||||
class YOLOv7(FastDeployModel):
|
||||
def __init__(self,
|
||||
model_file,
|
||||
params_file="",
|
||||
runtime_option=None,
|
||||
model_format=Frontend.ONNX):
|
||||
# 调用基函数进行backend_option的初始化
|
||||
# 初始化后的option保存在self._runtime_option
|
||||
super(YOLOv7, self).__init__(runtime_option)
|
||||
|
||||
self._model = C.vision.detection.YOLOv7(
|
||||
model_file, params_file, self._runtime_option, model_format)
|
||||
# 通过self.initialized判断整个模型的初始化是否成功
|
||||
assert self.initialized, "YOLOv7 initialize failed."
|
||||
|
||||
def predict(self, input_image, conf_threshold=0.25, nms_iou_threshold=0.5):
|
||||
return self._model.predict(input_image, conf_threshold,
|
||||
nms_iou_threshold)
|
||||
|
||||
# 一些跟YOLOv7模型有关的属性封装
|
||||
# 多数是预处理相关,可通过修改如model.size = [1280, 1280]改变预处理时resize的大小(前提是模型支持)
|
||||
@property
|
||||
def size(self):
|
||||
return self._model.size
|
||||
|
||||
@property
|
||||
def padding_value(self):
|
||||
return self._model.padding_value
|
||||
|
||||
@property
|
||||
def is_no_pad(self):
|
||||
return self._model.is_no_pad
|
||||
|
||||
@property
|
||||
def is_mini_pad(self):
|
||||
return self._model.is_mini_pad
|
||||
|
||||
@property
|
||||
def is_scale_up(self):
|
||||
return self._model.is_scale_up
|
||||
|
||||
@property
|
||||
def stride(self):
|
||||
return self._model.stride
|
||||
|
||||
@property
|
||||
def max_wh(self):
|
||||
return self._model.max_wh
|
||||
|
||||
@size.setter
|
||||
def size(self, wh):
|
||||
assert isinstance(wh, (list, tuple)),\
|
||||
"The value to set `size` must be type of tuple or list."
|
||||
assert len(wh) == 2,\
|
||||
"The value to set `size` must contatins 2 elements means [width, height], but now it contains {} elements.".format(
|
||||
len(wh))
|
||||
self._model.size = wh
|
||||
|
||||
@padding_value.setter
|
||||
def padding_value(self, value):
|
||||
assert isinstance(
|
||||
value,
|
||||
list), "The value to set `padding_value` must be type of list."
|
||||
self._model.padding_value = value
|
||||
|
||||
@is_no_pad.setter
|
||||
def is_no_pad(self, value):
|
||||
assert isinstance(
|
||||
value, bool), "The value to set `is_no_pad` must be type of bool."
|
||||
self._model.is_no_pad = value
|
||||
|
||||
@is_mini_pad.setter
|
||||
def is_mini_pad(self, value):
|
||||
assert isinstance(
|
||||
value,
|
||||
bool), "The value to set `is_mini_pad` must be type of bool."
|
||||
self._model.is_mini_pad = value
|
||||
|
||||
@is_scale_up.setter
|
||||
def is_scale_up(self, value):
|
||||
assert isinstance(
|
||||
value,
|
||||
bool), "The value to set `is_scale_up` must be type of bool."
|
||||
self._model.is_scale_up = value
|
||||
|
||||
@stride.setter
|
||||
def stride(self, value):
|
||||
assert isinstance(
|
||||
value, int), "The value to set `stride` must be type of int."
|
||||
self._model.stride = value
|
||||
|
||||
@max_wh.setter
|
||||
def max_wh(self, value):
|
||||
assert isinstance(
|
||||
value, float), "The value to set `max_wh` must be type of float."
|
||||
self._model.max_wh = value
|
105
python/fastdeploy/vision/detection/contrib/yolov7end2end_ort.py
Normal file
105
python/fastdeploy/vision/detection/contrib/yolov7end2end_ort.py
Normal file
@@ -0,0 +1,105 @@
|
||||
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import
|
||||
import logging
|
||||
from .... import FastDeployModel, Frontend
|
||||
from .... import c_lib_wrap as C
|
||||
|
||||
|
||||
class YOLOv7End2EndORT(FastDeployModel):
|
||||
def __init__(self,
|
||||
model_file,
|
||||
params_file="",
|
||||
runtime_option=None,
|
||||
model_format=Frontend.ONNX):
|
||||
# 调用基函数进行backend_option的初始化
|
||||
# 初始化后的option保存在self._runtime_option
|
||||
super(YOLOv7End2EndORT, self).__init__(runtime_option)
|
||||
|
||||
self._model = C.vision.detection.YOLOv7End2EndORT(
|
||||
model_file, params_file, self._runtime_option, model_format)
|
||||
# 通过self.initialized判断整个模型的初始化是否成功
|
||||
assert self.initialized, "YOLOv7End2End initialize failed."
|
||||
|
||||
def predict(self, input_image, conf_threshold=0.25):
|
||||
return self._model.predict(input_image, conf_threshold)
|
||||
|
||||
# 一些跟模型有关的属性封装
|
||||
# 多数是预处理相关,可通过修改如model.size = [1280, 1280]改变预处理时resize的大小(前提是模型支持)
|
||||
@property
|
||||
def size(self):
|
||||
return self._model.size
|
||||
|
||||
@property
|
||||
def padding_value(self):
|
||||
return self._model.padding_value
|
||||
|
||||
@property
|
||||
def is_no_pad(self):
|
||||
return self._model.is_no_pad
|
||||
|
||||
@property
|
||||
def is_mini_pad(self):
|
||||
return self._model.is_mini_pad
|
||||
|
||||
@property
|
||||
def is_scale_up(self):
|
||||
return self._model.is_scale_up
|
||||
|
||||
@property
|
||||
def stride(self):
|
||||
return self._model.stride
|
||||
|
||||
@size.setter
|
||||
def size(self, wh):
|
||||
assert isinstance(wh, (list, tuple)),\
|
||||
"The value to set `size` must be type of tuple or list."
|
||||
assert len(wh) == 2,\
|
||||
"The value to set `size` must contatins 2 elements means [width, height], but now it contains {} elements.".format(
|
||||
len(wh))
|
||||
self._model.size = wh
|
||||
|
||||
@padding_value.setter
|
||||
def padding_value(self, value):
|
||||
assert isinstance(
|
||||
value,
|
||||
list), "The value to set `padding_value` must be type of list."
|
||||
self._model.padding_value = value
|
||||
|
||||
@is_no_pad.setter
|
||||
def is_no_pad(self, value):
|
||||
assert isinstance(
|
||||
value, bool), "The value to set `is_no_pad` must be type of bool."
|
||||
self._model.is_no_pad = value
|
||||
|
||||
@is_mini_pad.setter
|
||||
def is_mini_pad(self, value):
|
||||
assert isinstance(
|
||||
value,
|
||||
bool), "The value to set `is_mini_pad` must be type of bool."
|
||||
self._model.is_mini_pad = value
|
||||
|
||||
@is_scale_up.setter
|
||||
def is_scale_up(self, value):
|
||||
assert isinstance(
|
||||
value,
|
||||
bool), "The value to set `is_scale_up` must be type of bool."
|
||||
self._model.is_scale_up = value
|
||||
|
||||
@stride.setter
|
||||
def stride(self, value):
|
||||
assert isinstance(
|
||||
value, int), "The value to set `stride` must be type of int."
|
||||
self._model.stride = value
|
105
python/fastdeploy/vision/detection/contrib/yolov7end2end_trt.py
Normal file
105
python/fastdeploy/vision/detection/contrib/yolov7end2end_trt.py
Normal file
@@ -0,0 +1,105 @@
|
||||
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import
|
||||
import logging
|
||||
from .... import FastDeployModel, Frontend
|
||||
from .... import c_lib_wrap as C
|
||||
|
||||
|
||||
class YOLOv7End2EndTRT(FastDeployModel):
|
||||
def __init__(self,
|
||||
model_file,
|
||||
params_file="",
|
||||
runtime_option=None,
|
||||
model_format=Frontend.ONNX):
|
||||
# 调用基函数进行backend_option的初始化
|
||||
# 初始化后的option保存在self._runtime_option
|
||||
super(YOLOv7End2EndTRT, self).__init__(runtime_option)
|
||||
|
||||
self._model = C.vision.detection.YOLOv7End2EndTRT(
|
||||
model_file, params_file, self._runtime_option, model_format)
|
||||
# 通过self.initialized判断整个模型的初始化是否成功
|
||||
assert self.initialized, "YOLOv7End2EndTRT initialize failed."
|
||||
|
||||
def predict(self, input_image, conf_threshold=0.25):
|
||||
return self._model.predict(input_image, conf_threshold)
|
||||
|
||||
# 一些跟模型有关的属性封装
|
||||
# 多数是预处理相关,可通过修改如model.size = [1280, 1280]改变预处理时resize的大小(前提是模型支持)
|
||||
@property
|
||||
def size(self):
|
||||
return self._model.size
|
||||
|
||||
@property
|
||||
def padding_value(self):
|
||||
return self._model.padding_value
|
||||
|
||||
@property
|
||||
def is_no_pad(self):
|
||||
return self._model.is_no_pad
|
||||
|
||||
@property
|
||||
def is_mini_pad(self):
|
||||
return self._model.is_mini_pad
|
||||
|
||||
@property
|
||||
def is_scale_up(self):
|
||||
return self._model.is_scale_up
|
||||
|
||||
@property
|
||||
def stride(self):
|
||||
return self._model.stride
|
||||
|
||||
@size.setter
|
||||
def size(self, wh):
|
||||
assert isinstance(wh, (list, tuple)),\
|
||||
"The value to set `size` must be type of tuple or list."
|
||||
assert len(wh) == 2,\
|
||||
"The value to set `size` must contatins 2 elements means [width, height], but now it contains {} elements.".format(
|
||||
len(wh))
|
||||
self._model.size = wh
|
||||
|
||||
@padding_value.setter
|
||||
def padding_value(self, value):
|
||||
assert isinstance(
|
||||
value,
|
||||
list), "The value to set `padding_value` must be type of list."
|
||||
self._model.padding_value = value
|
||||
|
||||
@is_no_pad.setter
|
||||
def is_no_pad(self, value):
|
||||
assert isinstance(
|
||||
value, bool), "The value to set `is_no_pad` must be type of bool."
|
||||
self._model.is_no_pad = value
|
||||
|
||||
@is_mini_pad.setter
|
||||
def is_mini_pad(self, value):
|
||||
assert isinstance(
|
||||
value,
|
||||
bool), "The value to set `is_mini_pad` must be type of bool."
|
||||
self._model.is_mini_pad = value
|
||||
|
||||
@is_scale_up.setter
|
||||
def is_scale_up(self, value):
|
||||
assert isinstance(
|
||||
value,
|
||||
bool), "The value to set `is_scale_up` must be type of bool."
|
||||
self._model.is_scale_up = value
|
||||
|
||||
@stride.setter
|
||||
def stride(self, value):
|
||||
assert isinstance(
|
||||
value, int), "The value to set `stride` must be type of int."
|
||||
self._model.stride = value
|
96
python/fastdeploy/vision/detection/contrib/yolox.py
Normal file
96
python/fastdeploy/vision/detection/contrib/yolox.py
Normal file
@@ -0,0 +1,96 @@
|
||||
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import
|
||||
import logging
|
||||
from .... import FastDeployModel, Frontend
|
||||
from .... import c_lib_wrap as C
|
||||
|
||||
|
||||
class YOLOX(FastDeployModel):
|
||||
def __init__(self,
|
||||
model_file,
|
||||
params_file="",
|
||||
runtime_option=None,
|
||||
model_format=Frontend.ONNX):
|
||||
# 调用基函数进行backend_option的初始化
|
||||
# 初始化后的option保存在self._runtime_option
|
||||
super(YOLOX, self).__init__(runtime_option)
|
||||
|
||||
self._model = C.vision.detection.YOLOX(
|
||||
model_file, params_file, self._runtime_option, model_format)
|
||||
# 通过self.initialized判断整个模型的初始化是否成功
|
||||
assert self.initialized, "YOLOX initialize failed."
|
||||
|
||||
def predict(self, input_image, conf_threshold=0.25, nms_iou_threshold=0.5):
|
||||
return self._model.predict(input_image, conf_threshold,
|
||||
nms_iou_threshold)
|
||||
|
||||
# 一些跟YOLOX模型有关的属性封装
|
||||
# 多数是预处理相关,可通过修改如model.size = [1280, 1280]改变预处理时resize的大小(前提是模型支持)
|
||||
@property
|
||||
def size(self):
|
||||
return self._model.size
|
||||
|
||||
@property
|
||||
def padding_value(self):
|
||||
return self._model.padding_value
|
||||
|
||||
@property
|
||||
def is_decode_exported(self):
|
||||
return self._model.is_decode_exported
|
||||
|
||||
@property
|
||||
def downsample_strides(self):
|
||||
return self._model.downsample_strides
|
||||
|
||||
@property
|
||||
def max_wh(self):
|
||||
return self._model.max_wh
|
||||
|
||||
@size.setter
|
||||
def size(self, wh):
|
||||
assert isinstance(wh, (list, tuple)),\
|
||||
"The value to set `size` must be type of tuple or list."
|
||||
assert len(wh) == 2,\
|
||||
"The value to set `size` must contatins 2 elements means [width, height], but now it contains {} elements.".format(
|
||||
len(wh))
|
||||
self._model.size = wh
|
||||
|
||||
@padding_value.setter
|
||||
def padding_value(self, value):
|
||||
assert isinstance(
|
||||
value,
|
||||
list), "The value to set `padding_value` must be type of list."
|
||||
self._model.padding_value = value
|
||||
|
||||
@is_decode_exported.setter
|
||||
def is_decode_exported(self, value):
|
||||
assert isinstance(
|
||||
value,
|
||||
bool), "The value to set `is_decode_exported` must be type of bool."
|
||||
self._model.is_decode_exported = value
|
||||
|
||||
@downsample_strides.setter
|
||||
def downsample_strides(self, value):
|
||||
assert isinstance(
|
||||
value,
|
||||
list), "The value to set `downsample_strides` must be type of list."
|
||||
self._model.downsample_strides = value
|
||||
|
||||
@max_wh.setter
|
||||
def max_wh(self, value):
|
||||
assert isinstance(
|
||||
value, float), "The value to set `max_wh` must be type of float."
|
||||
self._model.max_wh = value
|
154
python/fastdeploy/vision/detection/ppdet/__init__.py
Normal file
154
python/fastdeploy/vision/detection/ppdet/__init__.py
Normal file
@@ -0,0 +1,154 @@
|
||||
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import
|
||||
import logging
|
||||
from .... import FastDeployModel, Frontend
|
||||
from .... import c_lib_wrap as C
|
||||
|
||||
|
||||
class PPYOLOE(FastDeployModel):
|
||||
def __init__(self,
|
||||
model_file,
|
||||
params_file,
|
||||
config_file,
|
||||
runtime_option=None,
|
||||
model_format=Frontend.PADDLE):
|
||||
super(PPYOLOE, self).__init__(runtime_option)
|
||||
|
||||
assert model_format == Frontend.PADDLE, "PPYOLOE model only support model format of Frontend.Paddle now."
|
||||
self._model = C.vision.detection.PPYOLOE(
|
||||
model_file, params_file, config_file, self._runtime_option,
|
||||
model_format)
|
||||
assert self.initialized, "PPYOLOE model initialize failed."
|
||||
|
||||
def predict(self, input_image):
|
||||
assert input_image is not None, "The input image data is None."
|
||||
return self._model.predict(input_image)
|
||||
|
||||
|
||||
class PPYOLO(PPYOLOE):
|
||||
def __init__(self,
|
||||
model_file,
|
||||
params_file,
|
||||
config_file,
|
||||
runtime_option=None,
|
||||
model_format=Frontend.PADDLE):
|
||||
super(PPYOLOE, self).__init__(runtime_option)
|
||||
|
||||
assert model_format == Frontend.PADDLE, "PPYOLO model only support model format of Frontend.Paddle now."
|
||||
self._model = C.vision.detection.PPYOLO(
|
||||
model_file, params_file, config_file, self._runtime_option,
|
||||
model_format)
|
||||
assert self.initialized, "PPYOLO model initialize failed."
|
||||
|
||||
|
||||
class PPYOLOv2(PPYOLOE):
|
||||
def __init__(self,
|
||||
model_file,
|
||||
params_file,
|
||||
config_file,
|
||||
runtime_option=None,
|
||||
model_format=Frontend.PADDLE):
|
||||
super(PPYOLOE, self).__init__(runtime_option)
|
||||
|
||||
assert model_format == Frontend.PADDLE, "PPYOLOv2 model only support model format of Frontend.Paddle now."
|
||||
self._model = C.vision.detection.PPYOLOv2(
|
||||
model_file, params_file, config_file, self._runtime_option,
|
||||
model_format)
|
||||
assert self.initialized, "PPYOLOv2 model initialize failed."
|
||||
|
||||
|
||||
class PaddleYOLOX(PPYOLOE):
|
||||
def __init__(self,
|
||||
model_file,
|
||||
params_file,
|
||||
config_file,
|
||||
runtime_option=None,
|
||||
model_format=Frontend.PADDLE):
|
||||
super(PPYOLOE, self).__init__(runtime_option)
|
||||
|
||||
assert model_format == Frontend.PADDLE, "PaddleYOLOX model only support model format of Frontend.Paddle now."
|
||||
self._model = C.vision.detection.PaddleYOLOX(
|
||||
model_file, params_file, config_file, self._runtime_option,
|
||||
model_format)
|
||||
assert self.initialized, "PaddleYOLOX model initialize failed."
|
||||
|
||||
|
||||
class PicoDet(PPYOLOE):
|
||||
def __init__(self,
|
||||
model_file,
|
||||
params_file,
|
||||
config_file,
|
||||
runtime_option=None,
|
||||
model_format=Frontend.PADDLE):
|
||||
super(PPYOLOE, self).__init__(runtime_option)
|
||||
|
||||
assert model_format == Frontend.PADDLE, "PicoDet model only support model format of Frontend.Paddle now."
|
||||
self._model = C.vision.detection.PicoDet(
|
||||
model_file, params_file, config_file, self._runtime_option,
|
||||
model_format)
|
||||
assert self.initialized, "PicoDet model initialize failed."
|
||||
|
||||
|
||||
class FasterRCNN(PPYOLOE):
|
||||
def __init__(self,
|
||||
model_file,
|
||||
params_file,
|
||||
config_file,
|
||||
runtime_option=None,
|
||||
model_format=Frontend.PADDLE):
|
||||
super(PPYOLOE, self).__init__(runtime_option)
|
||||
|
||||
assert model_format == Frontend.PADDLE, "FasterRCNN model only support model format of Frontend.Paddle now."
|
||||
self._model = C.vision.detection.FasterRCNN(
|
||||
model_file, params_file, config_file, self._runtime_option,
|
||||
model_format)
|
||||
assert self.initialized, "FasterRCNN model initialize failed."
|
||||
|
||||
|
||||
class YOLOv3(PPYOLOE):
|
||||
def __init__(self,
|
||||
model_file,
|
||||
params_file,
|
||||
config_file,
|
||||
runtime_option=None,
|
||||
model_format=Frontend.PADDLE):
|
||||
super(PPYOLOE, self).__init__(runtime_option)
|
||||
|
||||
assert model_format == Frontend.PADDLE, "YOLOv3 model only support model format of Frontend.Paddle now."
|
||||
self._model = C.vision.detection.YOLOv3(
|
||||
model_file, params_file, config_file, self._runtime_option,
|
||||
model_format)
|
||||
assert self.initialized, "YOLOv3 model initialize failed."
|
||||
|
||||
|
||||
class MaskRCNN(FastDeployModel):
|
||||
def __init__(self,
|
||||
model_file,
|
||||
params_file,
|
||||
config_file,
|
||||
runtime_option=None,
|
||||
model_format=Frontend.PADDLE):
|
||||
super(MaskRCNN, self).__init__(runtime_option)
|
||||
|
||||
assert model_format == Frontend.PADDLE, "MaskRCNN model only support model format of Frontend.Paddle now."
|
||||
self._model = C.vision.detection.MaskRCNN(
|
||||
model_file, params_file, config_file, self._runtime_option,
|
||||
model_format)
|
||||
assert self.initialized, "MaskRCNN model initialize failed."
|
||||
|
||||
def predict(self, input_image):
|
||||
assert input_image is not None, "The input image data is None."
|
||||
return self._model.predict(input_image)
|
17
python/fastdeploy/vision/evaluation/__init__.py
Normal file
17
python/fastdeploy/vision/evaluation/__init__.py
Normal file
@@ -0,0 +1,17 @@
|
||||
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
from __future__ import absolute_import
|
||||
from .classify import eval_classify
|
||||
from .detection import eval_detection
|
||||
from .segmentation import eval_segmentation
|
82
python/fastdeploy/vision/evaluation/classify.py
Normal file
82
python/fastdeploy/vision/evaluation/classify.py
Normal file
@@ -0,0 +1,82 @@
|
||||
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
import numpy as np
|
||||
import os
|
||||
import re
|
||||
import time
|
||||
import collections
|
||||
|
||||
|
||||
def topk_accuracy(topk_list, label_list):
|
||||
match_array = np.logical_or.reduce(topk_list == label_list, axis=1)
|
||||
topk_acc_score = match_array.sum() / match_array.shape[0]
|
||||
return topk_acc_score
|
||||
|
||||
|
||||
def eval_classify(model, image_file_path, label_file_path, topk=5):
|
||||
from tqdm import trange
|
||||
import cv2
|
||||
import math
|
||||
|
||||
result_list = []
|
||||
label_list = []
|
||||
image_label_dict = {}
|
||||
assert os.path.isdir(
|
||||
image_file_path), "The image_file_path:{} is not a directory.".format(
|
||||
image_file_path)
|
||||
assert os.path.isfile(
|
||||
label_file_path), "The label_file_path:{} is not a file.".format(
|
||||
label_file_path)
|
||||
assert isinstance(topk, int), "The tok:{} is not int type".format(topk)
|
||||
|
||||
with open(label_file_path, 'r') as file:
|
||||
lines = file.readlines()
|
||||
for line in lines:
|
||||
items = line.strip().split()
|
||||
image_name = items[0]
|
||||
label = items[1]
|
||||
image_label_dict[image_name] = int(label)
|
||||
images_num = len(image_label_dict)
|
||||
twenty_percent_images_num = math.ceil(images_num * 0.2)
|
||||
start_time = 0
|
||||
end_time = 0
|
||||
average_inference_time = 0
|
||||
scores = collections.OrderedDict()
|
||||
for (image, label), i in zip(image_label_dict.items(),
|
||||
trange(
|
||||
images_num, desc='Inference Progress')):
|
||||
if i == twenty_percent_images_num:
|
||||
start_time = time.time()
|
||||
|
||||
label_list.append([label])
|
||||
image_path = os.path.join(image_file_path, image)
|
||||
im = cv2.imread(image_path)
|
||||
result = model.predict(im, topk)
|
||||
result_list.append(result.label_ids)
|
||||
if i == images_num - 1:
|
||||
end_time = time.time()
|
||||
average_inference_time = round(
|
||||
(end_time - start_time) / (images_num - twenty_percent_images_num), 4)
|
||||
topk_acc_score = topk_accuracy(np.array(result_list), np.array(label_list))
|
||||
if topk == 1:
|
||||
scores.update({'topk1': topk_acc_score})
|
||||
scores.update({
|
||||
'topk1_average_inference_time(s)': average_inference_time
|
||||
})
|
||||
elif topk == 5:
|
||||
scores.update({'topk5': topk_acc_score})
|
||||
scores.update({
|
||||
'topk5_average_inference_time(s)': average_inference_time
|
||||
})
|
||||
return scores
|
86
python/fastdeploy/vision/evaluation/detection.py
Normal file
86
python/fastdeploy/vision/evaluation/detection.py
Normal file
@@ -0,0 +1,86 @@
|
||||
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import numpy as np
|
||||
import copy
|
||||
import collections
|
||||
import math
|
||||
|
||||
|
||||
def eval_detection(model,
|
||||
data_dir,
|
||||
ann_file,
|
||||
conf_threshold=None,
|
||||
nms_iou_threshold=None,
|
||||
plot=False):
|
||||
from .utils import CocoDetection
|
||||
from .utils import COCOMetric
|
||||
import cv2
|
||||
from tqdm import trange
|
||||
import time
|
||||
|
||||
if conf_threshold is not None or nms_iou_threshold is not None:
|
||||
assert conf_threshold is not None and nms_iou_threshold is not None, "The conf_threshold and nms_iou_threshold should be setted at the same time"
|
||||
assert isinstance(conf_threshold, (
|
||||
float,
|
||||
int)), "The conf_threshold:{} need to be int or float".format(
|
||||
conf_threshold)
|
||||
assert isinstance(nms_iou_threshold, (
|
||||
float,
|
||||
int)), "The nms_iou_threshold:{} need to be int or float".format(
|
||||
nms_iou_threshold)
|
||||
eval_dataset = CocoDetection(
|
||||
data_dir=data_dir, ann_file=ann_file, shuffle=False)
|
||||
all_image_info = eval_dataset.file_list
|
||||
image_num = eval_dataset.num_samples
|
||||
eval_dataset.data_fields = {
|
||||
'im_id', 'image_shape', 'image', 'gt_bbox', 'gt_class', 'is_crowd'
|
||||
}
|
||||
eval_metric = COCOMetric(
|
||||
coco_gt=copy.deepcopy(eval_dataset.coco_gt), classwise=False)
|
||||
scores = collections.OrderedDict()
|
||||
twenty_percent_image_num = math.ceil(image_num * 0.2)
|
||||
start_time = 0
|
||||
end_time = 0
|
||||
average_inference_time = 0
|
||||
for image_info, i in zip(all_image_info,
|
||||
trange(
|
||||
image_num, desc="Inference Progress")):
|
||||
if i == twenty_percent_image_num:
|
||||
start_time = time.time()
|
||||
im = cv2.imread(image_info["image"])
|
||||
im_id = image_info["im_id"]
|
||||
if conf_threshold is None and nms_iou_threshold is None:
|
||||
result = model.predict(im.copy())
|
||||
else:
|
||||
result = model.predict(im, conf_threshold, nms_iou_threshold)
|
||||
pred = {
|
||||
'bbox':
|
||||
[[c] + [s] + b
|
||||
for b, s, c in zip(result.boxes, result.scores, result.label_ids)
|
||||
],
|
||||
'bbox_num': len(result.boxes),
|
||||
'im_id': im_id
|
||||
}
|
||||
eval_metric.update(im_id, pred)
|
||||
if i == image_num - 1:
|
||||
end_time = time.time()
|
||||
average_inference_time = round(
|
||||
(end_time - start_time) / (image_num - twenty_percent_image_num), 4)
|
||||
eval_metric.accumulate()
|
||||
eval_details = eval_metric.details
|
||||
scores.update(eval_metric.get())
|
||||
scores.update({'average_inference_time(s)': average_inference_time})
|
||||
eval_metric.reset()
|
||||
return scores
|
78
python/fastdeploy/vision/evaluation/segmentation.py
Normal file
78
python/fastdeploy/vision/evaluation/segmentation.py
Normal file
@@ -0,0 +1,78 @@
|
||||
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from tqdm import trange
|
||||
import numpy as np
|
||||
import collections
|
||||
import os
|
||||
import math
|
||||
import time
|
||||
|
||||
|
||||
def eval_segmentation(model, data_dir):
|
||||
import cv2
|
||||
from .utils import Cityscapes
|
||||
from .utils import f1_score, calculate_area, mean_iou, accuracy, kappa
|
||||
assert os.path.isdir(
|
||||
data_dir), "The image_file_path:{} is not a directory.".format(
|
||||
data_dir)
|
||||
eval_dataset = Cityscapes(dataset_root=data_dir, mode="val")
|
||||
file_list = eval_dataset.file_list
|
||||
image_num = eval_dataset.num_samples
|
||||
num_classes = eval_dataset.num_classes
|
||||
intersect_area_all = 0
|
||||
pred_area_all = 0
|
||||
label_area_all = 0
|
||||
conf_mat_all = []
|
||||
twenty_percent_image_num = math.ceil(image_num * 0.2)
|
||||
start_time = 0
|
||||
end_time = 0
|
||||
average_inference_time = 0
|
||||
for image_label_path, i in zip(file_list,
|
||||
trange(
|
||||
image_num, desc="Inference Progress")):
|
||||
if i == twenty_percent_image_num:
|
||||
start_time = time.time()
|
||||
im = cv2.imread(image_label_path[0])
|
||||
label = cv2.imread(image_label_path[1], cv2.IMREAD_GRAYSCALE)
|
||||
result = model.predict(im)
|
||||
if i == image_num - 1:
|
||||
end_time = time.time()
|
||||
average_inference_time = round(
|
||||
(end_time - start_time) / (image_num - twenty_percent_image_num),
|
||||
4)
|
||||
pred = np.array(result.label_map).reshape(result.shape[0],
|
||||
result.shape[1])
|
||||
intersect_area, pred_area, label_area = calculate_area(pred, label,
|
||||
num_classes)
|
||||
intersect_area_all = intersect_area_all + intersect_area
|
||||
pred_area_all = pred_area_all + pred_area
|
||||
label_area_all = label_area_all + label_area
|
||||
|
||||
class_iou, miou = mean_iou(intersect_area_all, pred_area_all,
|
||||
label_area_all)
|
||||
class_acc, oacc = accuracy(intersect_area_all, pred_area_all)
|
||||
kappa_res = kappa(intersect_area_all, pred_area_all, label_area_all)
|
||||
category_f1score = f1_score(intersect_area_all, pred_area_all,
|
||||
label_area_all)
|
||||
|
||||
eval_metrics = collections.OrderedDict(
|
||||
zip([
|
||||
'miou', 'category_iou', 'oacc', 'category_acc', 'kappa',
|
||||
'category_F1-score', 'average_inference_time(s)'
|
||||
], [
|
||||
miou, class_iou, oacc, class_acc, kappa_res, category_f1score,
|
||||
average_inference_time
|
||||
]))
|
||||
return eval_metrics
|
23
python/fastdeploy/vision/evaluation/utils/__init__.py
Normal file
23
python/fastdeploy/vision/evaluation/utils/__init__.py
Normal file
@@ -0,0 +1,23 @@
|
||||
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from . import fd_logging
|
||||
from .util import *
|
||||
from .coco_metrics import *
|
||||
from .seg_metrics import *
|
||||
from .json_results import *
|
||||
from .map_utils import *
|
||||
from .coco_utils import *
|
||||
from .coco import *
|
||||
from .cityscapes import *
|
74
python/fastdeploy/vision/evaluation/utils/cityscapes.py
Normal file
74
python/fastdeploy/vision/evaluation/utils/cityscapes.py
Normal file
@@ -0,0 +1,74 @@
|
||||
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import os
|
||||
import glob
|
||||
from . import fd_logging as logging
|
||||
|
||||
#import fd_logging as logging
|
||||
|
||||
|
||||
class Cityscapes(object):
|
||||
"""
|
||||
Cityscapes dataset `https://www.cityscapes-dataset.com/`.
|
||||
The folder structure is as follow:
|
||||
|
||||
cityscapes
|
||||
|
|
||||
|--leftImg8bit
|
||||
| |--train
|
||||
| |--val
|
||||
| |--test
|
||||
|
|
||||
|--gtFine
|
||||
| |--train
|
||||
| |--val
|
||||
| |--test
|
||||
|
||||
Args:
|
||||
dataset_root (str): Cityscapes dataset directory.
|
||||
"""
|
||||
NUM_CLASSES = 19
|
||||
|
||||
def __init__(self, dataset_root, mode):
|
||||
self.dataset_root = dataset_root
|
||||
self.file_list = list()
|
||||
mode = mode.lower()
|
||||
self.mode = mode
|
||||
self.num_classes = self.NUM_CLASSES
|
||||
self.ignore_index = 255
|
||||
|
||||
img_dir = os.path.join(self.dataset_root, 'leftImg8bit')
|
||||
label_dir = os.path.join(self.dataset_root, 'gtFine')
|
||||
if self.dataset_root is None or not os.path.isdir(
|
||||
self.dataset_root) or not os.path.isdir(
|
||||
img_dir) or not os.path.isdir(label_dir):
|
||||
raise ValueError(
|
||||
"The dataset is not Found or the folder structure is nonconfoumance."
|
||||
)
|
||||
|
||||
label_files = sorted(
|
||||
glob.glob(
|
||||
os.path.join(label_dir, mode, '*',
|
||||
'*_gtFine_labelTrainIds.png')))
|
||||
img_files = sorted(
|
||||
glob.glob(os.path.join(img_dir, mode, '*', '*_leftImg8bit.png')))
|
||||
|
||||
self.file_list = [
|
||||
[img_path, label_path]
|
||||
for img_path, label_path in zip(img_files, label_files)
|
||||
]
|
||||
|
||||
self.num_samples = len(self.file_list)
|
||||
logging.info("{} samples in file {}".format(self.num_samples, img_dir))
|
178
python/fastdeploy/vision/evaluation/utils/coco.py
Normal file
178
python/fastdeploy/vision/evaluation/utils/coco.py
Normal file
@@ -0,0 +1,178 @@
|
||||
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import
|
||||
import copy
|
||||
import os.path as osp
|
||||
import sys
|
||||
import numpy as np
|
||||
from . import fd_logging as logging
|
||||
from .util import is_pic, get_num_workers
|
||||
|
||||
|
||||
class CocoDetection(object):
|
||||
"""读取MSCOCO格式的检测数据集,并对样本进行相应的处理,该格式的数据集同样可以应用到实例分割模型的训练中。
|
||||
|
||||
Args:
|
||||
data_dir (str): 数据集所在的目录路径。
|
||||
ann_file (str): 数据集的标注文件,为一个独立的json格式文件。
|
||||
num_workers (int|str): 数据集中样本在预处理过程中的线程或进程数。默认为'auto'。当设为'auto'时,根据
|
||||
系统的实际CPU核数设置`num_workers`: 如果CPU核数的一半大于8,则`num_workers`为8,否则为CPU核数的一半。
|
||||
shuffle (bool): 是否需要对数据集中样本打乱顺序。默认为False。
|
||||
allow_empty (bool): 是否加载负样本。默认为False。
|
||||
empty_ratio (float): 用于指定负样本占总样本数的比例。如果小于0或大于等于1,则保留全部的负样本。默认为1。
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
data_dir,
|
||||
ann_file,
|
||||
num_workers='auto',
|
||||
shuffle=False,
|
||||
allow_empty=False,
|
||||
empty_ratio=1.):
|
||||
|
||||
from pycocotools.coco import COCO
|
||||
self.data_dir = data_dir
|
||||
self.data_fields = None
|
||||
self.num_max_boxes = 1000
|
||||
self.num_workers = get_num_workers(num_workers)
|
||||
self.shuffle = shuffle
|
||||
self.allow_empty = allow_empty
|
||||
self.empty_ratio = empty_ratio
|
||||
self.file_list = list()
|
||||
neg_file_list = list()
|
||||
self.labels = list()
|
||||
|
||||
coco = COCO(ann_file)
|
||||
self.coco_gt = coco
|
||||
img_ids = sorted(coco.getImgIds())
|
||||
cat_ids = coco.getCatIds()
|
||||
catid2clsid = dict({catid: i for i, catid in enumerate(cat_ids)})
|
||||
cname2clsid = dict({
|
||||
coco.loadCats(catid)[0]['name']: clsid
|
||||
for catid, clsid in catid2clsid.items()
|
||||
})
|
||||
for label, cid in sorted(cname2clsid.items(), key=lambda d: d[1]):
|
||||
self.labels.append(label)
|
||||
logging.info("Starting to read file list from dataset...")
|
||||
|
||||
ct = 0
|
||||
for img_id in img_ids:
|
||||
is_empty = False
|
||||
img_anno = coco.loadImgs(img_id)[0]
|
||||
im_fname = osp.join(data_dir, img_anno['file_name'])
|
||||
if not is_pic(im_fname):
|
||||
continue
|
||||
im_w = float(img_anno['width'])
|
||||
im_h = float(img_anno['height'])
|
||||
ins_anno_ids = coco.getAnnIds(imgIds=img_id, iscrowd=False)
|
||||
instances = coco.loadAnns(ins_anno_ids)
|
||||
|
||||
bboxes = []
|
||||
for inst in instances:
|
||||
x, y, box_w, box_h = inst['bbox']
|
||||
x1 = max(0, x)
|
||||
y1 = max(0, y)
|
||||
x2 = min(im_w - 1, x1 + max(0, box_w))
|
||||
y2 = min(im_h - 1, y1 + max(0, box_h))
|
||||
if inst['area'] > 0 and x2 >= x1 and y2 >= y1:
|
||||
inst['clean_bbox'] = [x1, y1, x2, y2]
|
||||
bboxes.append(inst)
|
||||
else:
|
||||
logging.warning(
|
||||
"Found an invalid bbox in annotations: "
|
||||
"im_id: {}, area: {} x1: {}, y1: {}, x2: {}, y2: {}."
|
||||
.format(img_id, float(inst['area']), x1, y1, x2, y2))
|
||||
num_bbox = len(bboxes)
|
||||
if num_bbox == 0 and not self.allow_empty:
|
||||
continue
|
||||
elif num_bbox == 0:
|
||||
is_empty = True
|
||||
|
||||
gt_bbox = np.zeros((num_bbox, 4), dtype=np.float32)
|
||||
gt_class = np.zeros((num_bbox, 1), dtype=np.int32)
|
||||
gt_score = np.ones((num_bbox, 1), dtype=np.float32)
|
||||
is_crowd = np.zeros((num_bbox, 1), dtype=np.int32)
|
||||
difficult = np.zeros((num_bbox, 1), dtype=np.int32)
|
||||
gt_poly = [None] * num_bbox
|
||||
|
||||
has_segmentation = False
|
||||
for i, box in reversed(list(enumerate(bboxes))):
|
||||
catid = box['category_id']
|
||||
gt_class[i][0] = catid2clsid[catid]
|
||||
gt_bbox[i, :] = box['clean_bbox']
|
||||
is_crowd[i][0] = box['iscrowd']
|
||||
if 'segmentation' in box and box['iscrowd'] == 1:
|
||||
gt_poly[i] = [[0.0, 0.0, 0.0, 0.0, 0.0, 0.0]]
|
||||
elif 'segmentation' in box and box['segmentation']:
|
||||
if not np.array(
|
||||
box['segmentation'],
|
||||
dtype=object).size > 0 and not self.allow_empty:
|
||||
gt_poly.pop(i)
|
||||
is_crowd = np.delete(is_crowd, i)
|
||||
gt_class = np.delete(gt_class, i)
|
||||
gt_bbox = np.delete(gt_bbox, i)
|
||||
else:
|
||||
gt_poly[i] = box['segmentation']
|
||||
has_segmentation = True
|
||||
if has_segmentation and not any(gt_poly) and not self.allow_empty:
|
||||
continue
|
||||
|
||||
im_info = {
|
||||
'im_id': np.array([img_id]).astype('int32'),
|
||||
'image_shape': np.array([im_h, im_w]).astype('int32'),
|
||||
}
|
||||
label_info = {
|
||||
'is_crowd': is_crowd,
|
||||
'gt_class': gt_class,
|
||||
'gt_bbox': gt_bbox,
|
||||
'gt_score': gt_score,
|
||||
'gt_poly': gt_poly,
|
||||
'difficult': difficult
|
||||
}
|
||||
|
||||
if is_empty:
|
||||
neg_file_list.append({
|
||||
'image': im_fname,
|
||||
**
|
||||
im_info,
|
||||
**
|
||||
label_info
|
||||
})
|
||||
else:
|
||||
self.file_list.append({
|
||||
'image': im_fname,
|
||||
**
|
||||
im_info,
|
||||
**
|
||||
label_info
|
||||
})
|
||||
ct += 1
|
||||
|
||||
self.num_max_boxes = max(self.num_max_boxes, len(instances))
|
||||
|
||||
if not ct:
|
||||
logging.error(
|
||||
"No coco record found in %s' % (ann_file)", exit=True)
|
||||
self.pos_num = len(self.file_list)
|
||||
if self.allow_empty and neg_file_list:
|
||||
self.file_list += self._sample_empty(neg_file_list)
|
||||
logging.info(
|
||||
"{} samples in file {}, including {} positive samples and {} negative samples.".
|
||||
format(
|
||||
len(self.file_list), ann_file, self.pos_num,
|
||||
len(self.file_list) - self.pos_num))
|
||||
self.num_samples = len(self.file_list)
|
||||
|
||||
self._epoch = 0
|
89
python/fastdeploy/vision/evaluation/utils/coco_metrics.py
Normal file
89
python/fastdeploy/vision/evaluation/utils/coco_metrics.py
Normal file
@@ -0,0 +1,89 @@
|
||||
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
import copy
|
||||
import sys
|
||||
from collections import OrderedDict
|
||||
from .coco_utils import get_infer_results, cocoapi_eval
|
||||
|
||||
|
||||
class COCOMetric(object):
|
||||
def __init__(self, coco_gt, **kwargs):
|
||||
self.clsid2catid = {
|
||||
i: cat['id']
|
||||
for i, cat in enumerate(coco_gt.loadCats(coco_gt.getCatIds()))
|
||||
}
|
||||
self.coco_gt = coco_gt
|
||||
self.classwise = kwargs.get('classwise', False)
|
||||
self.bias = 0
|
||||
self.reset()
|
||||
|
||||
def reset(self):
|
||||
# only bbox and mask evaluation support currently
|
||||
self.details = {
|
||||
'gt': copy.deepcopy(self.coco_gt.dataset),
|
||||
'bbox': [],
|
||||
'mask': []
|
||||
}
|
||||
self.eval_stats = {}
|
||||
|
||||
def update(self, im_id, outputs):
|
||||
outs = {}
|
||||
# outputs Tensor -> numpy.ndarray
|
||||
for k, v in outputs.items():
|
||||
outs[k] = v
|
||||
|
||||
outs['im_id'] = im_id
|
||||
infer_results = get_infer_results(
|
||||
outs, self.clsid2catid, bias=self.bias)
|
||||
self.details['bbox'] += infer_results[
|
||||
'bbox'] if 'bbox' in infer_results else []
|
||||
self.details['mask'] += infer_results[
|
||||
'mask'] if 'mask' in infer_results else []
|
||||
|
||||
def accumulate(self):
|
||||
if len(self.details['bbox']) > 0:
|
||||
bbox_stats = cocoapi_eval(
|
||||
copy.deepcopy(self.details['bbox']),
|
||||
'bbox',
|
||||
coco_gt=self.coco_gt,
|
||||
classwise=self.classwise)
|
||||
self.eval_stats['bbox'] = bbox_stats
|
||||
sys.stdout.flush()
|
||||
|
||||
if len(self.details['mask']) > 0:
|
||||
seg_stats = cocoapi_eval(
|
||||
copy.deepcopy(self.details['mask']),
|
||||
'segm',
|
||||
coco_gt=self.coco_gt,
|
||||
classwise=self.classwise)
|
||||
self.eval_stats['mask'] = seg_stats
|
||||
sys.stdout.flush()
|
||||
|
||||
def log(self):
|
||||
pass
|
||||
|
||||
def get(self):
|
||||
if 'bbox' not in self.eval_stats:
|
||||
return {'bbox_mmap': 0.}
|
||||
if 'mask' in self.eval_stats:
|
||||
return OrderedDict(
|
||||
zip(['bbox_mmap', 'segm_mmap'],
|
||||
[self.eval_stats['bbox'][0], self.eval_stats['mask'][0]]))
|
||||
else:
|
||||
return {'bbox_mmap': self.eval_stats['bbox'][0]}
|
218
python/fastdeploy/vision/evaluation/utils/coco_utils.py
Normal file
218
python/fastdeploy/vision/evaluation/utils/coco_utils.py
Normal file
@@ -0,0 +1,218 @@
|
||||
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
import sys
|
||||
import numpy as np
|
||||
from .map_utils import draw_pr_curve
|
||||
from .json_results import get_det_res, get_det_poly_res, get_seg_res, get_solov2_segm_res
|
||||
from . import fd_logging as logging
|
||||
import copy
|
||||
|
||||
|
||||
def loadRes(coco_obj, anns):
|
||||
"""
|
||||
Load result file and return a result api object.
|
||||
:param resFile (str) : file name of result file
|
||||
:return: res (obj) : result api object
|
||||
"""
|
||||
|
||||
# This function has the same functionality as pycocotools.COCO.loadRes,
|
||||
# except that the input anns is list of results rather than a json file.
|
||||
# Refer to
|
||||
# https://github.com/cocodataset/cocoapi/blob/8c9bcc3cf640524c4c20a9c40e89cb6a2f2fa0e9/PythonAPI/pycocotools/coco.py#L305,
|
||||
|
||||
# matplotlib.use() must be called *before* pylab, matplotlib.pyplot,
|
||||
# or matplotlib.backends is imported for the first time
|
||||
# pycocotools import matplotlib
|
||||
import matplotlib
|
||||
matplotlib.use('Agg')
|
||||
from pycocotools.coco import COCO
|
||||
import pycocotools.mask as maskUtils
|
||||
import time
|
||||
res = COCO()
|
||||
res.dataset['images'] = [img for img in coco_obj.dataset['images']]
|
||||
|
||||
tic = time.time()
|
||||
assert type(anns) == list, 'results in not an array of objects'
|
||||
annsImgIds = [ann['image_id'] for ann in anns]
|
||||
assert set(annsImgIds) == (set(annsImgIds) & set(coco_obj.getImgIds())), \
|
||||
'Results do not correspond to current coco set'
|
||||
if 'caption' in anns[0]:
|
||||
imgIds = set([img['id'] for img in res.dataset['images']]) & set(
|
||||
[ann['image_id'] for ann in anns])
|
||||
res.dataset['images'] = [
|
||||
img for img in res.dataset['images'] if img['id'] in imgIds
|
||||
]
|
||||
for id, ann in enumerate(anns):
|
||||
ann['id'] = id + 1
|
||||
elif 'bbox' in anns[0] and not anns[0]['bbox'] == []:
|
||||
res.dataset['categories'] = copy.deepcopy(coco_obj.dataset[
|
||||
'categories'])
|
||||
for id, ann in enumerate(anns):
|
||||
bb = ann['bbox']
|
||||
x1, x2, y1, y2 = [bb[0], bb[0] + bb[2], bb[1], bb[1] + bb[3]]
|
||||
if not 'segmentation' in ann:
|
||||
ann['segmentation'] = [[x1, y1, x1, y2, x2, y2, x2, y1]]
|
||||
ann['area'] = bb[2] * bb[3]
|
||||
ann['id'] = id + 1
|
||||
ann['iscrowd'] = 0
|
||||
elif 'segmentation' in anns[0]:
|
||||
res.dataset['categories'] = copy.deepcopy(coco_obj.dataset[
|
||||
'categories'])
|
||||
for id, ann in enumerate(anns):
|
||||
# now only support compressed RLE format as segmentation results
|
||||
ann['area'] = maskUtils.area(ann['segmentation'])
|
||||
if not 'bbox' in ann:
|
||||
ann['bbox'] = maskUtils.toBbox(ann['segmentation'])
|
||||
ann['id'] = id + 1
|
||||
ann['iscrowd'] = 0
|
||||
elif 'keypoints' in anns[0]:
|
||||
res.dataset['categories'] = copy.deepcopy(coco_obj.dataset[
|
||||
'categories'])
|
||||
for id, ann in enumerate(anns):
|
||||
s = ann['keypoints']
|
||||
x = s[0::3]
|
||||
y = s[1::3]
|
||||
x0, x1, y0, y1 = np.min(x), np.max(x), np.min(y), np.max(y)
|
||||
ann['area'] = (x1 - x0) * (y1 - y0)
|
||||
ann['id'] = id + 1
|
||||
ann['bbox'] = [x0, y0, x1 - x0, y1 - y0]
|
||||
|
||||
res.dataset['annotations'] = anns
|
||||
res.createIndex()
|
||||
return res
|
||||
|
||||
|
||||
def get_infer_results(outs, catid, bias=0):
|
||||
"""
|
||||
Get result at the stage of inference.
|
||||
The output format is dictionary containing bbox or mask result.
|
||||
|
||||
For example, bbox result is a list and each element contains
|
||||
image_id, category_id, bbox and score.
|
||||
"""
|
||||
if outs is None or len(outs) == 0:
|
||||
raise ValueError(
|
||||
'The number of valid detection result if zero. Please use reasonable model and check input data.'
|
||||
)
|
||||
|
||||
im_id = outs['im_id']
|
||||
|
||||
infer_res = {}
|
||||
if 'bbox' in outs:
|
||||
if len(outs['bbox']) > 0 and len(outs['bbox'][0]) > 6:
|
||||
infer_res['bbox'] = get_det_poly_res(
|
||||
outs['bbox'], outs['bbox_num'], im_id, catid, bias=bias)
|
||||
else:
|
||||
infer_res['bbox'] = get_det_res(
|
||||
outs['bbox'], outs['bbox_num'], im_id, catid, bias=bias)
|
||||
|
||||
if 'mask' in outs:
|
||||
# mask post process
|
||||
infer_res['mask'] = get_seg_res(outs['mask'], outs['bbox'],
|
||||
outs['bbox_num'], im_id, catid)
|
||||
|
||||
if 'segm' in outs:
|
||||
infer_res['segm'] = get_solov2_segm_res(outs, im_id, catid)
|
||||
|
||||
return infer_res
|
||||
|
||||
|
||||
def cocoapi_eval(anns,
|
||||
style,
|
||||
coco_gt=None,
|
||||
anno_file=None,
|
||||
max_dets=(100, 300, 1000),
|
||||
classwise=False):
|
||||
"""
|
||||
Args:
|
||||
anns: Evaluation result.
|
||||
style (str): COCOeval style, can be `bbox` , `segm` and `proposal`.
|
||||
coco_gt (str): Whether to load COCOAPI through anno_file,
|
||||
eg: coco_gt = COCO(anno_file)
|
||||
anno_file (str): COCO annotations file.
|
||||
max_dets (tuple): COCO evaluation maxDets.
|
||||
classwise (bool): Whether per-category AP and draw P-R Curve or not.
|
||||
"""
|
||||
assert coco_gt is not None or anno_file is not None
|
||||
from pycocotools.coco import COCO
|
||||
from pycocotools.cocoeval import COCOeval
|
||||
|
||||
if coco_gt is None:
|
||||
coco_gt = COCO(anno_file)
|
||||
logging.info("Start evaluate...")
|
||||
coco_dt = loadRes(coco_gt, anns)
|
||||
if style == 'proposal':
|
||||
coco_eval = COCOeval(coco_gt, coco_dt, 'bbox')
|
||||
coco_eval.params.useCats = 0
|
||||
coco_eval.params.maxDets = list(max_dets)
|
||||
else:
|
||||
coco_eval = COCOeval(coco_gt, coco_dt, style)
|
||||
coco_eval.evaluate()
|
||||
coco_eval.accumulate()
|
||||
coco_eval.summarize()
|
||||
if classwise:
|
||||
# Compute per-category AP and PR curve
|
||||
try:
|
||||
from terminaltables import AsciiTable
|
||||
except Exception as e:
|
||||
logging.error(
|
||||
'terminaltables not found, plaese install terminaltables. '
|
||||
'for example: `pip install terminaltables`.')
|
||||
raise e
|
||||
precisions = coco_eval.eval['precision']
|
||||
cat_ids = coco_gt.getCatIds()
|
||||
# precision: (iou, recall, cls, area range, max dets)
|
||||
assert len(cat_ids) == precisions.shape[2]
|
||||
results_per_category = []
|
||||
for idx, catId in enumerate(cat_ids):
|
||||
# area range index 0: all area ranges
|
||||
# max dets index -1: typically 100 per image
|
||||
nm = coco_gt.loadCats(catId)[0]
|
||||
precision = precisions[:, :, idx, 0, -1]
|
||||
precision = precision[precision > -1]
|
||||
if precision.size:
|
||||
ap = np.mean(precision)
|
||||
else:
|
||||
ap = float('nan')
|
||||
results_per_category.append(
|
||||
(str(nm["name"]), '{:0.3f}'.format(float(ap))))
|
||||
pr_array = precisions[0, :, idx, 0, 2]
|
||||
recall_array = np.arange(0.0, 1.01, 0.01)
|
||||
draw_pr_curve(
|
||||
pr_array,
|
||||
recall_array,
|
||||
out_dir=style + '_pr_curve',
|
||||
file_name='{}_precision_recall_curve.jpg'.format(nm["name"]))
|
||||
|
||||
num_columns = min(6, len(results_per_category) * 2)
|
||||
|
||||
import itertools
|
||||
results_flatten = list(itertools.chain(*results_per_category))
|
||||
headers = ['category', 'AP'] * (num_columns // 2)
|
||||
results_2d = itertools.zip_longest(
|
||||
* [results_flatten[i::num_columns] for i in range(num_columns)])
|
||||
table_data = [headers]
|
||||
table_data += [result for result in results_2d]
|
||||
table = AsciiTable(table_data)
|
||||
logging.info('Per-category of {} AP: \n{}'.format(style, table.table))
|
||||
logging.info("per-category PR curve has output to {} folder.".format(
|
||||
style + '_pr_curve'))
|
||||
# flush coco evaluation result
|
||||
sys.stdout.flush()
|
||||
return coco_eval.stats
|
53
python/fastdeploy/vision/evaluation/utils/fd_logging.py
Normal file
53
python/fastdeploy/vision/evaluation/utils/fd_logging.py
Normal file
@@ -0,0 +1,53 @@
|
||||
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import time
|
||||
import os
|
||||
import sys
|
||||
import colorama
|
||||
from colorama import init
|
||||
|
||||
init(autoreset=True)
|
||||
levels = {0: 'ERROR', 1: 'WARNING', 2: 'INFO', 3: 'DEBUG'}
|
||||
|
||||
|
||||
def log(level=2, message="", use_color=False):
|
||||
current_time = time.time()
|
||||
time_array = time.localtime(current_time)
|
||||
current_time = time.strftime("%Y-%m-%d %H:%M:%S", time_array)
|
||||
if use_color:
|
||||
print("\033[1;31;40m{} [{}]\t{}\033[0m".format(current_time, levels[
|
||||
level], message).encode("utf-8").decode("latin1"))
|
||||
else:
|
||||
print("{} [{}]\t{}".format(current_time, levels[level], message)
|
||||
.encode("utf-8").decode("latin1"))
|
||||
sys.stdout.flush()
|
||||
|
||||
|
||||
def debug(message="", use_color=False):
|
||||
log(level=3, message=message, use_color=use_color)
|
||||
|
||||
|
||||
def info(message="", use_color=False):
|
||||
log(level=2, message=message, use_color=use_color)
|
||||
|
||||
|
||||
def warning(message="", use_color=True):
|
||||
log(level=1, message=message, use_color=use_color)
|
||||
|
||||
|
||||
def error(message="", use_color=True, exit=True):
|
||||
log(level=0, message=message, use_color=use_color)
|
||||
if exit:
|
||||
sys.exit(-1)
|
156
python/fastdeploy/vision/evaluation/utils/json_results.py
Normal file
156
python/fastdeploy/vision/evaluation/utils/json_results.py
Normal file
@@ -0,0 +1,156 @@
|
||||
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import six
|
||||
import numpy as np
|
||||
|
||||
|
||||
def get_det_res(bboxes, bbox_nums, image_id, label_to_cat_id_map, bias=0):
|
||||
det_res = []
|
||||
for i in range(bbox_nums):
|
||||
cur_image_id = int(image_id)
|
||||
dt = bboxes[i]
|
||||
num_id, score, xmin, ymin, xmax, ymax = dt
|
||||
if int(num_id) < 0:
|
||||
continue
|
||||
category_id = label_to_cat_id_map[int(num_id)]
|
||||
w = xmax - xmin + bias
|
||||
h = ymax - ymin + bias
|
||||
bbox = [xmin, ymin, w, h]
|
||||
dt_res = {
|
||||
'image_id': cur_image_id,
|
||||
'category_id': category_id,
|
||||
'bbox': bbox,
|
||||
'score': score
|
||||
}
|
||||
det_res.append(dt_res)
|
||||
return det_res
|
||||
|
||||
|
||||
def get_det_poly_res(bboxes, bbox_nums, image_id, label_to_cat_id_map, bias=0):
|
||||
det_res = []
|
||||
k = 0
|
||||
for i in range(len(bbox_nums)):
|
||||
cur_image_id = int(image_id[i][0])
|
||||
det_nums = bbox_nums[i]
|
||||
for j in range(det_nums):
|
||||
dt = bboxes[k]
|
||||
k = k + 1
|
||||
num_id, score, x1, y1, x2, y2, x3, y3, x4, y4 = dt.tolist()
|
||||
if int(num_id) < 0:
|
||||
continue
|
||||
category_id = label_to_cat_id_map[int(num_id)]
|
||||
rbox = [x1, y1, x2, y2, x3, y3, x4, y4]
|
||||
dt_res = {
|
||||
'image_id': cur_image_id,
|
||||
'category_id': category_id,
|
||||
'bbox': rbox,
|
||||
'score': score
|
||||
}
|
||||
det_res.append(dt_res)
|
||||
return det_res
|
||||
|
||||
|
||||
def strip_mask(mask):
|
||||
row = mask[0, 0, :]
|
||||
col = mask[0, :, 0]
|
||||
im_h = len(col) - np.count_nonzero(col == -1)
|
||||
im_w = len(row) - np.count_nonzero(row == -1)
|
||||
return mask[:, :im_h, :im_w]
|
||||
|
||||
|
||||
def get_seg_res(masks, bboxes, mask_nums, image_id, label_to_cat_id_map):
|
||||
import pycocotools.mask as mask_util
|
||||
seg_res = []
|
||||
k = 0
|
||||
for i in range(len(mask_nums)):
|
||||
cur_image_id = int(image_id[i][0])
|
||||
det_nums = mask_nums[i]
|
||||
mask_i = masks[k:k + det_nums]
|
||||
mask_i = strip_mask(mask_i)
|
||||
for j in range(det_nums):
|
||||
mask = mask_i[j].astype(np.uint8)
|
||||
score = float(bboxes[k][1])
|
||||
label = int(bboxes[k][0])
|
||||
k = k + 1
|
||||
if label == -1:
|
||||
continue
|
||||
cat_id = label_to_cat_id_map[label]
|
||||
rle = mask_util.encode(
|
||||
np.array(
|
||||
mask[:, :, None], order="F", dtype="uint8"))[0]
|
||||
if six.PY3:
|
||||
if 'counts' in rle:
|
||||
rle['counts'] = rle['counts'].decode("utf8")
|
||||
sg_res = {
|
||||
'image_id': cur_image_id,
|
||||
'category_id': cat_id,
|
||||
'segmentation': rle,
|
||||
'score': score
|
||||
}
|
||||
seg_res.append(sg_res)
|
||||
return seg_res
|
||||
|
||||
|
||||
def get_solov2_segm_res(results, image_id, num_id_to_cat_id_map):
|
||||
import pycocotools.mask as mask_util
|
||||
segm_res = []
|
||||
# for each batch
|
||||
segms = results['segm'].astype(np.uint8)
|
||||
clsid_labels = results['cate_label']
|
||||
clsid_scores = results['cate_score']
|
||||
lengths = segms.shape[0]
|
||||
im_id = int(image_id[0][0])
|
||||
if lengths == 0 or segms is None:
|
||||
return None
|
||||
# for each sample
|
||||
for i in range(lengths - 1):
|
||||
clsid = int(clsid_labels[i])
|
||||
catid = num_id_to_cat_id_map[clsid]
|
||||
score = float(clsid_scores[i])
|
||||
mask = segms[i]
|
||||
segm = mask_util.encode(np.array(mask[:, :, np.newaxis], order='F'))[0]
|
||||
segm['counts'] = segm['counts'].decode('utf8')
|
||||
coco_res = {
|
||||
'image_id': im_id,
|
||||
'category_id': catid,
|
||||
'segmentation': segm,
|
||||
'score': score
|
||||
}
|
||||
segm_res.append(coco_res)
|
||||
return segm_res
|
||||
|
||||
|
||||
def get_keypoint_res(results, im_id):
|
||||
anns = []
|
||||
preds = results['keypoint']
|
||||
for idx in range(im_id.shape[0]):
|
||||
image_id = im_id[idx].item()
|
||||
kpts, scores = preds[idx]
|
||||
for kpt, score in zip(kpts, scores):
|
||||
kpt = kpt.flatten()
|
||||
ann = {
|
||||
'image_id': image_id,
|
||||
'category_id': 1, # XXX hard code
|
||||
'keypoints': kpt.tolist(),
|
||||
'score': float(score)
|
||||
}
|
||||
x = kpt[0::3]
|
||||
y = kpt[1::3]
|
||||
x0, x1, y0, y1 = np.min(x).item(), np.max(x).item(), np.min(
|
||||
y).item(), np.max(y).item()
|
||||
ann['area'] = (x1 - x0) * (y1 - y0)
|
||||
ann['bbox'] = [x0, y0, x1 - x0, y1 - y0]
|
||||
anns.append(ann)
|
||||
return anns
|
40
python/fastdeploy/vision/evaluation/utils/map_utils.py
Normal file
40
python/fastdeploy/vision/evaluation/utils/map_utils.py
Normal file
@@ -0,0 +1,40 @@
|
||||
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import
|
||||
import os
|
||||
|
||||
|
||||
def draw_pr_curve(precision,
|
||||
recall,
|
||||
iou=0.5,
|
||||
out_dir='pr_curve',
|
||||
file_name='precision_recall_curve.jpg'):
|
||||
if not os.path.exists(out_dir):
|
||||
os.makedirs(out_dir)
|
||||
output_path = os.path.join(out_dir, file_name)
|
||||
try:
|
||||
import matplotlib.pyplot as plt
|
||||
except Exception as e:
|
||||
# logger.error('Matplotlib not found, plaese install matplotlib.'
|
||||
# 'for example: `pip install matplotlib`.')
|
||||
raise e
|
||||
plt.cla()
|
||||
plt.figure('P-R Curve')
|
||||
plt.title('Precision/Recall Curve(IoU={})'.format(iou))
|
||||
plt.xlabel('Recall')
|
||||
plt.ylabel('Precision')
|
||||
plt.grid(True)
|
||||
plt.plot(recall, precision)
|
||||
plt.savefig(output_path)
|
143
python/fastdeploy/vision/evaluation/utils/seg_metrics.py
Normal file
143
python/fastdeploy/vision/evaluation/utils/seg_metrics.py
Normal file
@@ -0,0 +1,143 @@
|
||||
# Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import numpy as np
|
||||
|
||||
|
||||
def f1_score(intersect_area, pred_area, label_area):
|
||||
class_f1_sco = []
|
||||
for i in range(len(intersect_area)):
|
||||
if pred_area[i] + label_area[i] == 0:
|
||||
f1_sco = 0
|
||||
elif pred_area[i] == 0:
|
||||
f1_sco = 0
|
||||
else:
|
||||
prec = intersect_area[i] / pred_area[i]
|
||||
rec = intersect_area[i] / label_area[i]
|
||||
f1_sco = 2 * prec * rec / (prec + rec)
|
||||
class_f1_sco.append(f1_sco)
|
||||
return np.array(class_f1_sco)
|
||||
|
||||
|
||||
def calculate_area(pred, label, num_classes, ignore_index=255):
|
||||
"""
|
||||
Calculate intersect, prediction and label area
|
||||
|
||||
Args:
|
||||
pred (np.ndarray): The prediction by model.
|
||||
label (np.ndarray): The ground truth of image.
|
||||
num_classes (int): The unique number of target classes.
|
||||
ignore_index (int): Specifies a target value that is ignored. Default: 255.
|
||||
|
||||
Returns:
|
||||
Numpy Array: The intersection area of prediction and the ground on all class.
|
||||
Numpy Array: The prediction area on all class.
|
||||
Numpy Array: The ground truth area on all class
|
||||
"""
|
||||
if not pred.shape == label.shape:
|
||||
raise ValueError('Shape of `pred` and `label should be equal, '
|
||||
'but there are {} and {}.'.format(pred.shape,
|
||||
label.shape))
|
||||
|
||||
mask = label != ignore_index
|
||||
pred = pred + 1
|
||||
label = label + 1
|
||||
pred = pred * mask
|
||||
label = label * mask
|
||||
pred = np.eye(num_classes + 1)[pred]
|
||||
label = np.eye(num_classes + 1)[label]
|
||||
pred = pred[:, 1:]
|
||||
label = label[:, 1:]
|
||||
|
||||
pred_area = []
|
||||
label_area = []
|
||||
intersect_area = []
|
||||
|
||||
for i in range(num_classes):
|
||||
pred_i = pred[:, :, i]
|
||||
label_i = label[:, :, i]
|
||||
pred_area_i = np.sum(pred_i)
|
||||
label_area_i = np.sum(label_i)
|
||||
intersect_area_i = np.sum(pred_i * label_i)
|
||||
pred_area.append(pred_area_i)
|
||||
label_area.append(label_area_i)
|
||||
intersect_area.append(intersect_area_i)
|
||||
return np.array(intersect_area), np.array(pred_area), np.array(label_area)
|
||||
|
||||
|
||||
def mean_iou(intersect_area, pred_area, label_area):
|
||||
"""
|
||||
Calculate iou.
|
||||
|
||||
Args:
|
||||
intersect_area (np.ndarray): The intersection area of prediction and ground truth on all classes.
|
||||
pred_area (np.ndarray): The prediction area on all classes.
|
||||
label_area (np.ndarray): The ground truth area on all classes.
|
||||
|
||||
Returns:
|
||||
np.ndarray: iou on all classes.
|
||||
float: mean iou of all classes.
|
||||
"""
|
||||
union = pred_area + label_area - intersect_area
|
||||
class_iou = []
|
||||
for i in range(len(intersect_area)):
|
||||
if union[i] == 0:
|
||||
iou = 0
|
||||
else:
|
||||
iou = intersect_area[i] / union[i]
|
||||
class_iou.append(iou)
|
||||
miou = np.mean(class_iou)
|
||||
return np.array(class_iou), miou
|
||||
|
||||
|
||||
def accuracy(intersect_area, pred_area):
|
||||
"""
|
||||
Calculate accuracy
|
||||
|
||||
Args:
|
||||
intersect_area (np.ndarray): The intersection area of prediction and ground truth on all classes..
|
||||
pred_area (np.ndarray): The prediction area on all classes.
|
||||
|
||||
Returns:
|
||||
np.ndarray: accuracy on all classes.
|
||||
float: mean accuracy.
|
||||
"""
|
||||
class_acc = []
|
||||
for i in range(len(intersect_area)):
|
||||
if pred_area[i] == 0:
|
||||
acc = 0
|
||||
else:
|
||||
acc = intersect_area[i] / pred_area[i]
|
||||
class_acc.append(acc)
|
||||
macc = np.sum(intersect_area) / np.sum(pred_area)
|
||||
return np.array(class_acc), macc
|
||||
|
||||
|
||||
def kappa(intersect_area, pred_area, label_area):
|
||||
"""
|
||||
Calculate kappa coefficient
|
||||
|
||||
Args:
|
||||
intersect_area (np.ndarray): The intersection area of prediction and ground truth on all classes..
|
||||
pred_area (np.ndarray): The prediction area on all classes.
|
||||
label_area (np.ndarray): The ground truth area on all classes.
|
||||
|
||||
Returns:
|
||||
float: kappa coefficient.
|
||||
"""
|
||||
total_area = np.sum(label_area)
|
||||
po = np.sum(intersect_area) / total_area
|
||||
pe = np.sum(pred_area * label_area) / (total_area * total_area)
|
||||
kappa = (po - pe) / (1 - pe)
|
||||
return kappa
|
34
python/fastdeploy/vision/evaluation/utils/util.py
Normal file
34
python/fastdeploy/vision/evaluation/utils/util.py
Normal file
@@ -0,0 +1,34 @@
|
||||
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import platform
|
||||
import multiprocessing as mp
|
||||
|
||||
|
||||
def is_pic(img_name):
|
||||
valid_suffix = ['JPEG', 'jpeg', 'JPG', 'jpg', 'BMP', 'bmp', 'PNG', 'png']
|
||||
suffix = img_name.split('.')[-1]
|
||||
if suffix not in valid_suffix:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def get_num_workers(num_workers):
|
||||
if not platform.system() == 'Linux':
|
||||
# Dataloader with multi-process model is not supported
|
||||
# on MacOS and Windows currently.
|
||||
return 0
|
||||
if num_workers == 'auto':
|
||||
num_workers = mp.cpu_count() // 2 if mp.cpu_count() // 2 < 2 else 2
|
||||
return num_workers
|
19
python/fastdeploy/vision/facedet/__init__.py
Normal file
19
python/fastdeploy/vision/facedet/__init__.py
Normal file
@@ -0,0 +1,19 @@
|
||||
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import
|
||||
from .contrib.yolov5face import YOLOv5Face
|
||||
from .contrib.retinaface import RetinaFace
|
||||
from .contrib.scrfd import SCRFD
|
||||
from .contrib.ultraface import UltraFace
|
15
python/fastdeploy/vision/facedet/contrib/__init__.py
Normal file
15
python/fastdeploy/vision/facedet/contrib/__init__.py
Normal file
@@ -0,0 +1,15 @@
|
||||
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import
|
98
python/fastdeploy/vision/facedet/contrib/retinaface.py
Normal file
98
python/fastdeploy/vision/facedet/contrib/retinaface.py
Normal file
@@ -0,0 +1,98 @@
|
||||
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import
|
||||
import logging
|
||||
from .... import FastDeployModel, Frontend
|
||||
from .... import c_lib_wrap as C
|
||||
|
||||
|
||||
class RetinaFace(FastDeployModel):
|
||||
def __init__(self,
|
||||
model_file,
|
||||
params_file="",
|
||||
runtime_option=None,
|
||||
model_format=Frontend.ONNX):
|
||||
# 调用基函数进行backend_option的初始化
|
||||
# 初始化后的option保存在self._runtime_option
|
||||
super(RetinaFace, self).__init__(runtime_option)
|
||||
|
||||
self._model = C.vision.facedet.RetinaFace(
|
||||
model_file, params_file, self._runtime_option, model_format)
|
||||
# 通过self.initialized判断整个模型的初始化是否成功
|
||||
assert self.initialized, "RetinaFace initialize failed."
|
||||
|
||||
def predict(self, input_image, conf_threshold=0.7, nms_iou_threshold=0.3):
|
||||
return self._model.predict(input_image, conf_threshold,
|
||||
nms_iou_threshold)
|
||||
|
||||
# 一些跟模型有关的属性封装
|
||||
# 多数是预处理相关,可通过修改如model.size = [640, 480]改变预处理时resize的大小(前提是模型支持)
|
||||
@property
|
||||
def size(self):
|
||||
return self._model.size
|
||||
|
||||
@property
|
||||
def variance(self):
|
||||
return self._model.variance
|
||||
|
||||
@property
|
||||
def downsample_strides(self):
|
||||
return self._model.downsample_strides
|
||||
|
||||
@property
|
||||
def min_sizes(self):
|
||||
return self._model.min_sizes
|
||||
|
||||
@property
|
||||
def landmarks_per_face(self):
|
||||
return self._model.landmarks_per_face
|
||||
|
||||
@size.setter
|
||||
def size(self, wh):
|
||||
assert isinstance(wh, (list, tuple)),\
|
||||
"The value to set `size` must be type of tuple or list."
|
||||
assert len(wh) == 2,\
|
||||
"The value to set `size` must contatins 2 elements means [width, height], but now it contains {} elements.".format(
|
||||
len(wh))
|
||||
self._model.size = wh
|
||||
|
||||
@variance.setter
|
||||
def variance(self, value):
|
||||
assert isinstance(v, (list, tuple)),\
|
||||
"The value to set `variance` must be type of tuple or list."
|
||||
assert len(value) == 2,\
|
||||
"The value to set `variance` must contatins 2 elements".format(
|
||||
len(value))
|
||||
self._model.variance = value
|
||||
|
||||
@downsample_strides.setter
|
||||
def downsample_strides(self, value):
|
||||
assert isinstance(
|
||||
value,
|
||||
list), "The value to set `downsample_strides` must be type of list."
|
||||
self._model.downsample_strides = value
|
||||
|
||||
@min_sizes.setter
|
||||
def min_sizes(self, value):
|
||||
assert isinstance(
|
||||
value, list), "The value to set `min_sizes` must be type of list."
|
||||
self._model.min_sizes = value
|
||||
|
||||
@landmarks_per_face.setter
|
||||
def landmarks_per_face(self, value):
|
||||
assert isinstance(
|
||||
value,
|
||||
int), "The value to set `landmarks_per_face` must be type of int."
|
||||
self._model.landmarks_per_face = value
|
158
python/fastdeploy/vision/facedet/contrib/scrfd.py
Normal file
158
python/fastdeploy/vision/facedet/contrib/scrfd.py
Normal file
@@ -0,0 +1,158 @@
|
||||
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import
|
||||
import logging
|
||||
from .... import FastDeployModel, Frontend
|
||||
from .... import c_lib_wrap as C
|
||||
|
||||
|
||||
class SCRFD(FastDeployModel):
|
||||
def __init__(self,
|
||||
model_file,
|
||||
params_file="",
|
||||
runtime_option=None,
|
||||
model_format=Frontend.ONNX):
|
||||
# 调用基函数进行backend_option的初始化
|
||||
# 初始化后的option保存在self._runtime_option
|
||||
super(SCRFD, self).__init__(runtime_option)
|
||||
|
||||
self._model = C.vision.facedet.SCRFD(
|
||||
model_file, params_file, self._runtime_option, model_format)
|
||||
# 通过self.initialized判断整个模型的初始化是否成功
|
||||
assert self.initialized, "SCRFD initialize failed."
|
||||
|
||||
def predict(self, input_image, conf_threshold=0.7, nms_iou_threshold=0.3):
|
||||
return self._model.predict(input_image, conf_threshold,
|
||||
nms_iou_threshold)
|
||||
|
||||
# 一些跟SCRFD模型有关的属性封装
|
||||
# 多数是预处理相关,可通过修改如model.size = [640, 640]改变预处理时resize的大小(前提是模型支持)
|
||||
@property
|
||||
def size(self):
|
||||
return self._model.size
|
||||
|
||||
@property
|
||||
def padding_value(self):
|
||||
return self._model.padding_value
|
||||
|
||||
@property
|
||||
def is_no_pad(self):
|
||||
return self._model.is_no_pad
|
||||
|
||||
@property
|
||||
def is_mini_pad(self):
|
||||
return self._model.is_mini_pad
|
||||
|
||||
@property
|
||||
def is_scale_up(self):
|
||||
return self._model.is_scale_up
|
||||
|
||||
@property
|
||||
def stride(self):
|
||||
return self._model.stride
|
||||
|
||||
@property
|
||||
def downsample_strides(self):
|
||||
return self._model.downsample_strides
|
||||
|
||||
@property
|
||||
def landmarks_per_face(self):
|
||||
return self._model.landmarks_per_face
|
||||
|
||||
@property
|
||||
def use_kps(self):
|
||||
return self._model.use_kps
|
||||
|
||||
@property
|
||||
def max_nms(self):
|
||||
return self._model.max_nms
|
||||
|
||||
@property
|
||||
def num_anchors(self):
|
||||
return self._model.num_anchors
|
||||
|
||||
@size.setter
|
||||
def size(self, wh):
|
||||
assert isinstance(wh, (list, tuple)),\
|
||||
"The value to set `size` must be type of tuple or list."
|
||||
assert len(wh) == 2,\
|
||||
"The value to set `size` must contatins 2 elements means [width, height], but now it contains {} elements.".format(
|
||||
len(wh))
|
||||
self._model.size = wh
|
||||
|
||||
@padding_value.setter
|
||||
def padding_value(self, value):
|
||||
assert isinstance(
|
||||
value,
|
||||
list), "The value to set `padding_value` must be type of list."
|
||||
self._model.padding_value = value
|
||||
|
||||
@is_no_pad.setter
|
||||
def is_no_pad(self, value):
|
||||
assert isinstance(
|
||||
value, bool), "The value to set `is_no_pad` must be type of bool."
|
||||
self._model.is_no_pad = value
|
||||
|
||||
@is_mini_pad.setter
|
||||
def is_mini_pad(self, value):
|
||||
assert isinstance(
|
||||
value,
|
||||
bool), "The value to set `is_mini_pad` must be type of bool."
|
||||
self._model.is_mini_pad = value
|
||||
|
||||
@is_scale_up.setter
|
||||
def is_scale_up(self, value):
|
||||
assert isinstance(
|
||||
value,
|
||||
bool), "The value to set `is_scale_up` must be type of bool."
|
||||
self._model.is_scale_up = value
|
||||
|
||||
@stride.setter
|
||||
def stride(self, value):
|
||||
assert isinstance(
|
||||
value, int), "The value to set `stride` must be type of int."
|
||||
self._model.stride = value
|
||||
|
||||
@downsample_strides.setter
|
||||
def downsample_strides(self, value):
|
||||
assert isinstance(
|
||||
value,
|
||||
list), "The value to set `downsample_strides` must be type of list."
|
||||
self._model.downsample_strides = value
|
||||
|
||||
@landmarks_per_face.setter
|
||||
def landmarks_per_face(self, value):
|
||||
assert isinstance(
|
||||
value,
|
||||
int), "The value to set `landmarks_per_face` must be type of int."
|
||||
self._model.landmarks_per_face = value
|
||||
|
||||
@use_kps.setter
|
||||
def use_kps(self, value):
|
||||
assert isinstance(
|
||||
value, bool), "The value to set `use_kps` must be type of bool."
|
||||
self._model.use_kps = value
|
||||
|
||||
@max_nms.setter
|
||||
def max_nms(self, value):
|
||||
assert isinstance(
|
||||
value, int), "The value to set `max_nms` must be type of int."
|
||||
self._model.max_nms = value
|
||||
|
||||
@num_anchors.setter
|
||||
def num_anchors(self, value):
|
||||
assert isinstance(
|
||||
value, int), "The value to set `num_anchors` must be type of int."
|
||||
self._model.num_anchors = value
|
53
python/fastdeploy/vision/facedet/contrib/ultraface.py
Normal file
53
python/fastdeploy/vision/facedet/contrib/ultraface.py
Normal file
@@ -0,0 +1,53 @@
|
||||
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import
|
||||
import logging
|
||||
from .... import FastDeployModel, Frontend
|
||||
from .... import c_lib_wrap as C
|
||||
|
||||
|
||||
class UltraFace(FastDeployModel):
|
||||
def __init__(self,
|
||||
model_file,
|
||||
params_file="",
|
||||
runtime_option=None,
|
||||
model_format=Frontend.ONNX):
|
||||
# 调用基函数进行backend_option的初始化
|
||||
# 初始化后的option保存在self._runtime_option
|
||||
super(UltraFace, self).__init__(runtime_option)
|
||||
|
||||
self._model = C.vision.facedet.UltraFace(
|
||||
model_file, params_file, self._runtime_option, model_format)
|
||||
# 通过self.initialized判断整个模型的初始化是否成功
|
||||
assert self.initialized, "UltraFace initialize failed."
|
||||
|
||||
def predict(self, input_image, conf_threshold=0.7, nms_iou_threshold=0.3):
|
||||
return self._model.predict(input_image, conf_threshold,
|
||||
nms_iou_threshold)
|
||||
|
||||
# 一些跟UltraFace模型有关的属性封装
|
||||
# 多数是预处理相关,可通过修改如model.size = [640, 480]改变预处理时resize的大小(前提是模型支持)
|
||||
@property
|
||||
def size(self):
|
||||
return self._model.size
|
||||
|
||||
@size.setter
|
||||
def size(self, wh):
|
||||
assert isinstance(wh, (list, tuple)),\
|
||||
"The value to set `size` must be type of tuple or list."
|
||||
assert len(wh) == 2,\
|
||||
"The value to set `size` must contatins 2 elements means [width, height], but now it contains {} elements.".format(
|
||||
len(wh))
|
||||
self._model.size = wh
|
117
python/fastdeploy/vision/facedet/contrib/yolov5face.py
Normal file
117
python/fastdeploy/vision/facedet/contrib/yolov5face.py
Normal file
@@ -0,0 +1,117 @@
|
||||
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import
|
||||
import logging
|
||||
from .... import FastDeployModel, Frontend
|
||||
from .... import c_lib_wrap as C
|
||||
|
||||
|
||||
class YOLOv5Face(FastDeployModel):
|
||||
def __init__(self,
|
||||
model_file,
|
||||
params_file="",
|
||||
runtime_option=None,
|
||||
model_format=Frontend.ONNX):
|
||||
# 调用基函数进行backend_option的初始化
|
||||
# 初始化后的option保存在self._runtime_option
|
||||
super(YOLOv5Face, self).__init__(runtime_option)
|
||||
|
||||
self._model = C.vision.facedet.YOLOv5Face(
|
||||
model_file, params_file, self._runtime_option, model_format)
|
||||
# 通过self.initialized判断整个模型的初始化是否成功
|
||||
assert self.initialized, "YOLOv5Face initialize failed."
|
||||
|
||||
def predict(self, input_image, conf_threshold=0.25, nms_iou_threshold=0.5):
|
||||
return self._model.predict(input_image, conf_threshold,
|
||||
nms_iou_threshold)
|
||||
|
||||
# 一些跟YOLOv5Face模型有关的属性封装
|
||||
# 多数是预处理相关,可通过修改如model.size = [1280, 1280]改变预处理时resize的大小(前提是模型支持)
|
||||
@property
|
||||
def size(self):
|
||||
return self._model.size
|
||||
|
||||
@property
|
||||
def padding_value(self):
|
||||
return self._model.padding_value
|
||||
|
||||
@property
|
||||
def is_no_pad(self):
|
||||
return self._model.is_no_pad
|
||||
|
||||
@property
|
||||
def is_mini_pad(self):
|
||||
return self._model.is_mini_pad
|
||||
|
||||
@property
|
||||
def is_scale_up(self):
|
||||
return self._model.is_scale_up
|
||||
|
||||
@property
|
||||
def stride(self):
|
||||
return self._model.stride
|
||||
|
||||
@property
|
||||
def landmarks_per_face(self):
|
||||
return self._model.landmarks_per_face
|
||||
|
||||
@size.setter
|
||||
def size(self, wh):
|
||||
assert isinstance(wh, (list, tuple)),\
|
||||
"The value to set `size` must be type of tuple or list."
|
||||
assert len(wh) == 2,\
|
||||
"The value to set `size` must contatins 2 elements means [width, height], but now it contains {} elements.".format(
|
||||
len(wh))
|
||||
self._model.size = wh
|
||||
|
||||
@padding_value.setter
|
||||
def padding_value(self, value):
|
||||
assert isinstance(
|
||||
value,
|
||||
list), "The value to set `padding_value` must be type of list."
|
||||
self._model.padding_value = value
|
||||
|
||||
@is_no_pad.setter
|
||||
def is_no_pad(self, value):
|
||||
assert isinstance(
|
||||
value, bool), "The value to set `is_no_pad` must be type of bool."
|
||||
self._model.is_no_pad = value
|
||||
|
||||
@is_mini_pad.setter
|
||||
def is_mini_pad(self, value):
|
||||
assert isinstance(
|
||||
value,
|
||||
bool), "The value to set `is_mini_pad` must be type of bool."
|
||||
self._model.is_mini_pad = value
|
||||
|
||||
@is_scale_up.setter
|
||||
def is_scale_up(self, value):
|
||||
assert isinstance(
|
||||
value,
|
||||
bool), "The value to set `is_scale_up` must be type of bool."
|
||||
self._model.is_scale_up = value
|
||||
|
||||
@stride.setter
|
||||
def stride(self, value):
|
||||
assert isinstance(
|
||||
value, int), "The value to set `stride` must be type of int."
|
||||
self._model.stride = value
|
||||
|
||||
@landmarks_per_face.setter
|
||||
def landmarks_per_face(self, value):
|
||||
assert isinstance(
|
||||
value,
|
||||
int), "The value to set `landmarks_per_face` must be type of int."
|
||||
self._model.landmarks_per_face = value
|
20
python/fastdeploy/vision/faceid/__init__.py
Normal file
20
python/fastdeploy/vision/faceid/__init__.py
Normal file
@@ -0,0 +1,20 @@
|
||||
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import
|
||||
from .contrib.arcface import ArcFace
|
||||
from .contrib.cosface import CosFace
|
||||
from .contrib.insightface_rec import InsightFaceRecognitionModel
|
||||
from .contrib.partial_fc import PartialFC
|
||||
from .contrib.vpl import VPL
|
15
python/fastdeploy/vision/faceid/contrib/__init__.py
Normal file
15
python/fastdeploy/vision/faceid/contrib/__init__.py
Normal file
@@ -0,0 +1,15 @@
|
||||
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import
|
100
python/fastdeploy/vision/faceid/contrib/arcface.py
Normal file
100
python/fastdeploy/vision/faceid/contrib/arcface.py
Normal file
@@ -0,0 +1,100 @@
|
||||
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import
|
||||
import logging
|
||||
from .... import FastDeployModel, Frontend
|
||||
from .... import c_lib_wrap as C
|
||||
from ..contrib.insightface_rec import InsightFaceRecognitionModel
|
||||
|
||||
|
||||
class ArcFace(FastDeployModel):
|
||||
def __init__(self,
|
||||
model_file,
|
||||
params_file="",
|
||||
runtime_option=None,
|
||||
model_format=Frontend.ONNX):
|
||||
# 调用基函数进行backend_option的初始化
|
||||
# 初始化后的option保存在self._runtime_option
|
||||
super(ArcFace, self).__init__(runtime_option)
|
||||
|
||||
self._model = C.vision.faceid.ArcFace(
|
||||
model_file, params_file, self._runtime_option, model_format)
|
||||
# 通过self.initialized判断整个模型的初始化是否成功
|
||||
assert self.initialized, "ArcFace initialize failed."
|
||||
|
||||
def predict(self, input_image):
|
||||
return self._model.predict(input_image)
|
||||
|
||||
# 一些跟模型有关的属性封装
|
||||
# 多数是预处理相关,可通过修改如model.size = [112, 112]改变预处理时resize的大小(前提是模型支持)
|
||||
@property
|
||||
def size(self):
|
||||
return self._model.size
|
||||
|
||||
@property
|
||||
def alpha(self):
|
||||
return self._model.alpha
|
||||
|
||||
@property
|
||||
def beta(self):
|
||||
return self._model.beta
|
||||
|
||||
@property
|
||||
def swap_rb(self):
|
||||
return self._model.swap_rb
|
||||
|
||||
@property
|
||||
def l2_normalize(self):
|
||||
return self._model.l2_normalize
|
||||
|
||||
@size.setter
|
||||
def size(self, wh):
|
||||
assert isinstance(wh, (list, tuple)),\
|
||||
"The value to set `size` must be type of tuple or list."
|
||||
assert len(wh) == 2,\
|
||||
"The value to set `size` must contatins 2 elements means [width, height], but now it contains {} elements.".format(
|
||||
len(wh))
|
||||
self._model.size = wh
|
||||
|
||||
@alpha.setter
|
||||
def alpha(self, value):
|
||||
assert isinstance(value, (list, tuple)),\
|
||||
"The value to set `alpha` must be type of tuple or list."
|
||||
assert len(value) == 3,\
|
||||
"The value to set `alpha` must contatins 3 elements for each channels, but now it contains {} elements.".format(
|
||||
len(value))
|
||||
self._model.alpha = value
|
||||
|
||||
@beta.setter
|
||||
def beta(self, value):
|
||||
assert isinstance(value, (list, tuple)),\
|
||||
"The value to set `beta` must be type of tuple or list."
|
||||
assert len(value) == 3,\
|
||||
"The value to set `beta` must contatins 3 elements for each channels, but now it contains {} elements.".format(
|
||||
len(value))
|
||||
self._model.beta = value
|
||||
|
||||
@swap_rb.setter
|
||||
def swap_rb(self, value):
|
||||
assert isinstance(
|
||||
value, bool), "The value to set `swap_rb` must be type of bool."
|
||||
self._model.swap_rb = value
|
||||
|
||||
@l2_normalize.setter
|
||||
def l2_normalize(self, value):
|
||||
assert isinstance(
|
||||
value,
|
||||
bool), "The value to set `l2_normalize` must be type of bool."
|
||||
self._model.l2_normalize = value
|
99
python/fastdeploy/vision/faceid/contrib/cosface.py
Normal file
99
python/fastdeploy/vision/faceid/contrib/cosface.py
Normal file
@@ -0,0 +1,99 @@
|
||||
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import
|
||||
import logging
|
||||
from .... import FastDeployModel, Frontend
|
||||
from .... import c_lib_wrap as C
|
||||
|
||||
|
||||
class CosFace(FastDeployModel):
|
||||
def __init__(self,
|
||||
model_file,
|
||||
params_file="",
|
||||
runtime_option=None,
|
||||
model_format=Frontend.ONNX):
|
||||
# 调用基函数进行backend_option的初始化
|
||||
# 初始化后的option保存在self._runtime_option
|
||||
super(CosFace, self).__init__(runtime_option)
|
||||
|
||||
self._model = C.vision.faceid.CosFace(
|
||||
model_file, params_file, self._runtime_option, model_format)
|
||||
# 通过self.initialized判断整个模型的初始化是否成功
|
||||
assert self.initialized, "CosFace initialize failed."
|
||||
|
||||
def predict(self, input_image):
|
||||
return self._model.predict(input_image)
|
||||
|
||||
# 一些跟模型有关的属性封装
|
||||
# 多数是预处理相关,可通过修改如model.size = [112, 112]改变预处理时resize的大小(前提是模型支持)
|
||||
@property
|
||||
def size(self):
|
||||
return self._model.size
|
||||
|
||||
@property
|
||||
def alpha(self):
|
||||
return self._model.alpha
|
||||
|
||||
@property
|
||||
def beta(self):
|
||||
return self._model.beta
|
||||
|
||||
@property
|
||||
def swap_rb(self):
|
||||
return self._model.swap_rb
|
||||
|
||||
@property
|
||||
def l2_normalize(self):
|
||||
return self._model.l2_normalize
|
||||
|
||||
@size.setter
|
||||
def size(self, wh):
|
||||
assert isinstance(wh, (list, tuple)),\
|
||||
"The value to set `size` must be type of tuple or list."
|
||||
assert len(wh) == 2,\
|
||||
"The value to set `size` must contatins 2 elements means [width, height], but now it contains {} elements.".format(
|
||||
len(wh))
|
||||
self._model.size = wh
|
||||
|
||||
@alpha.setter
|
||||
def alpha(self, value):
|
||||
assert isinstance(value, (list, tuple)),\
|
||||
"The value to set `alpha` must be type of tuple or list."
|
||||
assert len(value) == 3,\
|
||||
"The value to set `alpha` must contatins 3 elements for each channels, but now it contains {} elements.".format(
|
||||
len(value))
|
||||
self._model.alpha = value
|
||||
|
||||
@beta.setter
|
||||
def beta(self, value):
|
||||
assert isinstance(value, (list, tuple)),\
|
||||
"The value to set `beta` must be type of tuple or list."
|
||||
assert len(value) == 3,\
|
||||
"The value to set `beta` must contatins 3 elements for each channels, but now it contains {} elements.".format(
|
||||
len(value))
|
||||
self._model.beta = value
|
||||
|
||||
@swap_rb.setter
|
||||
def swap_rb(self, value):
|
||||
assert isinstance(
|
||||
value, bool), "The value to set `swap_rb` must be type of bool."
|
||||
self._model.swap_rb = value
|
||||
|
||||
@l2_normalize.setter
|
||||
def l2_normalize(self, value):
|
||||
assert isinstance(
|
||||
value,
|
||||
bool), "The value to set `l2_normalize` must be type of bool."
|
||||
self._model.l2_normalize = value
|
99
python/fastdeploy/vision/faceid/contrib/insightface_rec.py
Normal file
99
python/fastdeploy/vision/faceid/contrib/insightface_rec.py
Normal file
@@ -0,0 +1,99 @@
|
||||
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import
|
||||
import logging
|
||||
from .... import FastDeployModel, Frontend
|
||||
from .... import c_lib_wrap as C
|
||||
|
||||
|
||||
class InsightFaceRecognitionModel(FastDeployModel):
|
||||
def __init__(self,
|
||||
model_file,
|
||||
params_file="",
|
||||
runtime_option=None,
|
||||
model_format=Frontend.ONNX):
|
||||
# 调用基函数进行backend_option的初始化
|
||||
# 初始化后的option保存在self._runtime_option
|
||||
super(InsightFaceRecognitionModel, self).__init__(runtime_option)
|
||||
|
||||
self._model = C.vision.faceid.InsightFaceRecognitionModel(
|
||||
model_file, params_file, self._runtime_option, model_format)
|
||||
# 通过self.initialized判断整个模型的初始化是否成功
|
||||
assert self.initialized, "InsightFaceRecognitionModel initialize failed."
|
||||
|
||||
def predict(self, input_image):
|
||||
return self._model.predict(input_image)
|
||||
|
||||
# 一些跟InsightFaceRecognitionModel模型有关的属性封装
|
||||
# 多数是预处理相关,可通过修改如model.size = [112, 112]改变预处理时resize的大小(前提是模型支持)
|
||||
@property
|
||||
def size(self):
|
||||
return self._model.size
|
||||
|
||||
@property
|
||||
def alpha(self):
|
||||
return self._model.alpha
|
||||
|
||||
@property
|
||||
def beta(self):
|
||||
return self._model.beta
|
||||
|
||||
@property
|
||||
def swap_rb(self):
|
||||
return self._model.swap_rb
|
||||
|
||||
@property
|
||||
def l2_normalize(self):
|
||||
return self._model.l2_normalize
|
||||
|
||||
@size.setter
|
||||
def size(self, wh):
|
||||
assert isinstance(wh, (list, tuple)),\
|
||||
"The value to set `size` must be type of tuple or list."
|
||||
assert len(wh) == 2,\
|
||||
"The value to set `size` must contatins 2 elements means [width, height], but now it contains {} elements.".format(
|
||||
len(wh))
|
||||
self._model.size = wh
|
||||
|
||||
@alpha.setter
|
||||
def alpha(self, value):
|
||||
assert isinstance(value, (list, tuple)),\
|
||||
"The value to set `alpha` must be type of tuple or list."
|
||||
assert len(value) == 3,\
|
||||
"The value to set `alpha` must contatins 3 elements for each channels, but now it contains {} elements.".format(
|
||||
len(value))
|
||||
self._model.alpha = value
|
||||
|
||||
@beta.setter
|
||||
def beta(self, value):
|
||||
assert isinstance(value, (list, tuple)),\
|
||||
"The value to set `beta` must be type of tuple or list."
|
||||
assert len(value) == 3,\
|
||||
"The value to set `beta` must contatins 3 elements for each channels, but now it contains {} elements.".format(
|
||||
len(value))
|
||||
self._model.beta = value
|
||||
|
||||
@swap_rb.setter
|
||||
def swap_rb(self, value):
|
||||
assert isinstance(
|
||||
value, bool), "The value to set `swap_rb` must be type of bool."
|
||||
self._model.swap_rb = value
|
||||
|
||||
@l2_normalize.setter
|
||||
def l2_normalize(self, value):
|
||||
assert isinstance(
|
||||
value,
|
||||
bool), "The value to set `l2_normalize` must be type of bool."
|
||||
self._model.l2_normalize = value
|
99
python/fastdeploy/vision/faceid/contrib/partial_fc.py
Normal file
99
python/fastdeploy/vision/faceid/contrib/partial_fc.py
Normal file
@@ -0,0 +1,99 @@
|
||||
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import
|
||||
import logging
|
||||
from .... import FastDeployModel, Frontend
|
||||
from .... import c_lib_wrap as C
|
||||
|
||||
|
||||
class PartialFC(FastDeployModel):
|
||||
def __init__(self,
|
||||
model_file,
|
||||
params_file="",
|
||||
runtime_option=None,
|
||||
model_format=Frontend.ONNX):
|
||||
# 调用基函数进行backend_option的初始化
|
||||
# 初始化后的option保存在self._runtime_option
|
||||
super(PartialFC, self).__init__(runtime_option)
|
||||
|
||||
self._model = C.vision.faceid.PartialFC(
|
||||
model_file, params_file, self._runtime_option, model_format)
|
||||
# 通过self.initialized判断整个模型的初始化是否成功
|
||||
assert self.initialized, "PartialFC initialize failed."
|
||||
|
||||
def predict(self, input_image):
|
||||
return self._model.predict(input_image)
|
||||
|
||||
# 一些跟模型有关的属性封装
|
||||
# 多数是预处理相关,可通过修改如model.size = [112, 112]改变预处理时resize的大小(前提是模型支持)
|
||||
@property
|
||||
def size(self):
|
||||
return self._model.size
|
||||
|
||||
@property
|
||||
def alpha(self):
|
||||
return self._model.alpha
|
||||
|
||||
@property
|
||||
def beta(self):
|
||||
return self._model.beta
|
||||
|
||||
@property
|
||||
def swap_rb(self):
|
||||
return self._model.swap_rb
|
||||
|
||||
@property
|
||||
def l2_normalize(self):
|
||||
return self._model.l2_normalize
|
||||
|
||||
@size.setter
|
||||
def size(self, wh):
|
||||
assert isinstance(wh, (list, tuple)),\
|
||||
"The value to set `size` must be type of tuple or list."
|
||||
assert len(wh) == 2,\
|
||||
"The value to set `size` must contatins 2 elements means [width, height], but now it contains {} elements.".format(
|
||||
len(wh))
|
||||
self._model.size = wh
|
||||
|
||||
@alpha.setter
|
||||
def alpha(self, value):
|
||||
assert isinstance(value, (list, tuple)),\
|
||||
"The value to set `alpha` must be type of tuple or list."
|
||||
assert len(value) == 3,\
|
||||
"The value to set `alpha` must contatins 3 elements for each channels, but now it contains {} elements.".format(
|
||||
len(value))
|
||||
self._model.alpha = value
|
||||
|
||||
@beta.setter
|
||||
def beta(self, value):
|
||||
assert isinstance(value, (list, tuple)),\
|
||||
"The value to set `beta` must be type of tuple or list."
|
||||
assert len(value) == 3,\
|
||||
"The value to set `beta` must contatins 3 elements for each channels, but now it contains {} elements.".format(
|
||||
len(value))
|
||||
self._model.beta = value
|
||||
|
||||
@swap_rb.setter
|
||||
def swap_rb(self, value):
|
||||
assert isinstance(
|
||||
value, bool), "The value to set `swap_rb` must be type of bool."
|
||||
self._model.swap_rb = value
|
||||
|
||||
@l2_normalize.setter
|
||||
def l2_normalize(self, value):
|
||||
assert isinstance(
|
||||
value,
|
||||
bool), "The value to set `l2_normalize` must be type of bool."
|
||||
self._model.l2_normalize = value
|
99
python/fastdeploy/vision/faceid/contrib/vpl.py
Normal file
99
python/fastdeploy/vision/faceid/contrib/vpl.py
Normal file
@@ -0,0 +1,99 @@
|
||||
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import
|
||||
import logging
|
||||
from .... import FastDeployModel, Frontend
|
||||
from .... import c_lib_wrap as C
|
||||
|
||||
|
||||
class VPL(FastDeployModel):
|
||||
def __init__(self,
|
||||
model_file,
|
||||
params_file="",
|
||||
runtime_option=None,
|
||||
model_format=Frontend.ONNX):
|
||||
# 调用基函数进行backend_option的初始化
|
||||
# 初始化后的option保存在self._runtime_option
|
||||
super(VPL, self).__init__(runtime_option)
|
||||
|
||||
self._model = C.vision.faceid.VPL(model_file, params_file,
|
||||
self._runtime_option, model_format)
|
||||
# 通过self.initialized判断整个模型的初始化是否成功
|
||||
assert self.initialized, "VPL initialize failed."
|
||||
|
||||
def predict(self, input_image):
|
||||
return self._model.predict(input_image)
|
||||
|
||||
# 一些跟模型有关的属性封装
|
||||
# 多数是预处理相关,可通过修改如model.size = [112, 112]改变预处理时resize的大小(前提是模型支持)
|
||||
@property
|
||||
def size(self):
|
||||
return self._model.size
|
||||
|
||||
@property
|
||||
def alpha(self):
|
||||
return self._model.alpha
|
||||
|
||||
@property
|
||||
def beta(self):
|
||||
return self._model.beta
|
||||
|
||||
@property
|
||||
def swap_rb(self):
|
||||
return self._model.swap_rb
|
||||
|
||||
@property
|
||||
def l2_normalize(self):
|
||||
return self._model.l2_normalize
|
||||
|
||||
@size.setter
|
||||
def size(self, wh):
|
||||
assert isinstance(wh, (list, tuple)),\
|
||||
"The value to set `size` must be type of tuple or list."
|
||||
assert len(wh) == 2,\
|
||||
"The value to set `size` must contatins 2 elements means [width, height], but now it contains {} elements.".format(
|
||||
len(wh))
|
||||
self._model.size = wh
|
||||
|
||||
@alpha.setter
|
||||
def alpha(self, value):
|
||||
assert isinstance(value, (list, tuple)),\
|
||||
"The value to set `alpha` must be type of tuple or list."
|
||||
assert len(value) == 3,\
|
||||
"The value to set `alpha` must contatins 3 elements for each channels, but now it contains {} elements.".format(
|
||||
len(value))
|
||||
self._model.alpha = value
|
||||
|
||||
@beta.setter
|
||||
def beta(self, value):
|
||||
assert isinstance(value, (list, tuple)),\
|
||||
"The value to set `beta` must be type of tuple or list."
|
||||
assert len(value) == 3,\
|
||||
"The value to set `beta` must contatins 3 elements for each channels, but now it contains {} elements.".format(
|
||||
len(value))
|
||||
self._model.beta = value
|
||||
|
||||
@swap_rb.setter
|
||||
def swap_rb(self, value):
|
||||
assert isinstance(
|
||||
value, bool), "The value to set `swap_rb` must be type of bool."
|
||||
self._model.swap_rb = value
|
||||
|
||||
@l2_normalize.setter
|
||||
def l2_normalize(self, value):
|
||||
assert isinstance(
|
||||
value,
|
||||
bool), "The value to set `l2_normalize` must be type of bool."
|
||||
self._model.l2_normalize = value
|
17
python/fastdeploy/vision/matting/__init__.py
Normal file
17
python/fastdeploy/vision/matting/__init__.py
Normal file
@@ -0,0 +1,17 @@
|
||||
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import
|
||||
from .contrib.modnet import MODNet
|
||||
from .ppmatting import PPMatting
|
15
python/fastdeploy/vision/matting/contrib/__init__.py
Normal file
15
python/fastdeploy/vision/matting/contrib/__init__.py
Normal file
@@ -0,0 +1,15 @@
|
||||
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import
|
88
python/fastdeploy/vision/matting/contrib/modnet.py
Normal file
88
python/fastdeploy/vision/matting/contrib/modnet.py
Normal file
@@ -0,0 +1,88 @@
|
||||
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import
|
||||
import logging
|
||||
from .... import FastDeployModel, Frontend
|
||||
from .... import c_lib_wrap as C
|
||||
|
||||
|
||||
class MODNet(FastDeployModel):
|
||||
def __init__(self,
|
||||
model_file,
|
||||
params_file="",
|
||||
runtime_option=None,
|
||||
model_format=Frontend.ONNX):
|
||||
# 调用基函数进行backend_option的初始化
|
||||
# 初始化后的option保存在self._runtime_option
|
||||
super(MODNet, self).__init__(runtime_option)
|
||||
|
||||
self._model = C.vision.matting.MODNet(
|
||||
model_file, params_file, self._runtime_option, model_format)
|
||||
# 通过self.initialized判断整个模型的初始化是否成功
|
||||
assert self.initialized, "MODNet initialize failed."
|
||||
|
||||
def predict(self, input_image):
|
||||
return self._model.predict(input_image)
|
||||
|
||||
# 一些跟模型有关的属性封装
|
||||
# 多数是预处理相关,可通过修改如model.size = [256, 256]改变预处理时resize的大小(前提是模型支持)
|
||||
@property
|
||||
def size(self):
|
||||
return self._model.size
|
||||
|
||||
@property
|
||||
def alpha(self):
|
||||
return self._model.alpha
|
||||
|
||||
@property
|
||||
def beta(self):
|
||||
return self._model.beta
|
||||
|
||||
@property
|
||||
def swap_rb(self):
|
||||
return self._model.swap_rb
|
||||
|
||||
@size.setter
|
||||
def size(self, wh):
|
||||
assert isinstance(wh, (list, tuple)),\
|
||||
"The value to set `size` must be type of tuple or list."
|
||||
assert len(wh) == 2,\
|
||||
"The value to set `size` must contatins 2 elements means [width, height], but now it contains {} elements.".format(
|
||||
len(wh))
|
||||
self._model.size = wh
|
||||
|
||||
@alpha.setter
|
||||
def alpha(self, value):
|
||||
assert isinstance(value, (list, tuple)),\
|
||||
"The value to set `alpha` must be type of tuple or list."
|
||||
assert len(value) == 3,\
|
||||
"The value to set `alpha` must contatins 3 elements for each channels, but now it contains {} elements.".format(
|
||||
len(value))
|
||||
self._model.alpha = value
|
||||
|
||||
@beta.setter
|
||||
def beta(self, value):
|
||||
assert isinstance(value, (list, tuple)),\
|
||||
"The value to set `beta` must be type of tuple or list."
|
||||
assert len(value) == 3,\
|
||||
"The value to set `beta` must contatins 3 elements for each channels, but now it contains {} elements.".format(
|
||||
len(value))
|
||||
self._model.beta = value
|
||||
|
||||
@swap_rb.setter
|
||||
def swap_rb(self, value):
|
||||
assert isinstance(
|
||||
value, bool), "The value to set `swap_rb` must be type of bool."
|
||||
self._model.swap_rb = value
|
38
python/fastdeploy/vision/matting/ppmatting/__init__.py
Normal file
38
python/fastdeploy/vision/matting/ppmatting/__init__.py
Normal file
@@ -0,0 +1,38 @@
|
||||
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import
|
||||
import logging
|
||||
from .... import FastDeployModel, Frontend
|
||||
from .... import c_lib_wrap as C
|
||||
|
||||
|
||||
class PPMatting(FastDeployModel):
|
||||
def __init__(self,
|
||||
model_file,
|
||||
params_file,
|
||||
config_file,
|
||||
runtime_option=None,
|
||||
model_format=Frontend.PADDLE):
|
||||
super(PPMatting, self).__init__(runtime_option)
|
||||
|
||||
assert model_format == Frontend.PADDLE, "PPMatting model only support model format of Frontend.Paddle now."
|
||||
self._model = C.vision.matting.PPMatting(
|
||||
model_file, params_file, config_file, self._runtime_option,
|
||||
model_format)
|
||||
assert self.initialized, "PPMatting model initialize failed."
|
||||
|
||||
def predict(self, input_image):
|
||||
assert input_image is not None, "The input image data is None."
|
||||
return self._model.predict(input_image)
|
20
python/fastdeploy/vision/ocr/__init__.py
Normal file
20
python/fastdeploy/vision/ocr/__init__.py
Normal file
@@ -0,0 +1,20 @@
|
||||
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
from __future__ import absolute_import
|
||||
|
||||
from .ppocr import PPOCRSystemv3
|
||||
from .ppocr import PPOCRSystemv2
|
||||
from .ppocr import DBDetector
|
||||
from .ppocr import Classifier
|
||||
from .ppocr import Recognizer
|
240
python/fastdeploy/vision/ocr/ppocr/__init__.py
Normal file
240
python/fastdeploy/vision/ocr/ppocr/__init__.py
Normal file
@@ -0,0 +1,240 @@
|
||||
# # Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
# #
|
||||
# # Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# # you may not use this file except in compliance with the License.
|
||||
# # You may obtain a copy of the License at
|
||||
# #
|
||||
# # http://www.apache.org/licenses/LICENSE-2.0
|
||||
# #
|
||||
# # Unless required by applicable law or agreed to in writing, software
|
||||
# # distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# # See the License for the specific language governing permissions and
|
||||
# # limitations under the License.
|
||||
|
||||
from __future__ import absolute_import
|
||||
import logging
|
||||
from .... import FastDeployModel, Frontend
|
||||
from .... import c_lib_wrap as C
|
||||
|
||||
|
||||
class DBDetector(FastDeployModel):
|
||||
def __init__(self,
|
||||
model_file="",
|
||||
params_file="",
|
||||
runtime_option=None,
|
||||
model_format=Frontend.PADDLE):
|
||||
# 调用基函数进行backend_option的初始化
|
||||
# 初始化后的option保存在self._runtime_option
|
||||
super(DBDetector, self).__init__(runtime_option)
|
||||
|
||||
if (len(model_file) == 0):
|
||||
self._model = C.vision.ocr.DBDetector()
|
||||
else:
|
||||
self._model = C.vision.ocr.DBDetector(
|
||||
model_file, params_file, self._runtime_option, model_format)
|
||||
# 通过self.initialized判断整个模型的初始化是否成功
|
||||
assert self.initialized, "DBDetector initialize failed."
|
||||
|
||||
# 一些跟DBDetector模型有关的属性封装
|
||||
@property
|
||||
def max_side_len(self):
|
||||
return self._model.max_side_len
|
||||
|
||||
@property
|
||||
def det_db_thresh(self):
|
||||
return self._model.det_db_thresh
|
||||
|
||||
@property
|
||||
def det_db_box_thresh(self):
|
||||
return self._model.det_db_box_thresh
|
||||
|
||||
@property
|
||||
def det_db_unclip_ratio(self):
|
||||
return self._model.det_db_unclip_ratio
|
||||
|
||||
@property
|
||||
def det_db_score_mode(self):
|
||||
return self._model.det_db_score_mode
|
||||
|
||||
@property
|
||||
def use_dilation(self):
|
||||
return self._model.use_dilation
|
||||
|
||||
@property
|
||||
def is_scale(self):
|
||||
return self._model.max_wh
|
||||
|
||||
@max_side_len.setter
|
||||
def max_side_len(self, value):
|
||||
assert isinstance(
|
||||
value, int), "The value to set `max_side_len` must be type of int."
|
||||
self._model.max_side_len = value
|
||||
|
||||
@det_db_thresh.setter
|
||||
def det_db_thresh(self, value):
|
||||
assert isinstance(
|
||||
value,
|
||||
float), "The value to set `det_db_thresh` must be type of float."
|
||||
self._model.det_db_thresh = value
|
||||
|
||||
@det_db_box_thresh.setter
|
||||
def det_db_box_thresh(self, value):
|
||||
assert isinstance(
|
||||
value, float
|
||||
), "The value to set `det_db_box_thresh` must be type of float."
|
||||
self._model.det_db_box_thresh = value
|
||||
|
||||
@det_db_unclip_ratio.setter
|
||||
def det_db_unclip_ratio(self, value):
|
||||
assert isinstance(
|
||||
value, float
|
||||
), "The value to set `det_db_unclip_ratio` must be type of float."
|
||||
self._model.det_db_unclip_ratio = value
|
||||
|
||||
@det_db_score_mode.setter
|
||||
def det_db_score_mode(self, value):
|
||||
assert isinstance(
|
||||
value,
|
||||
str), "The value to set `det_db_score_mode` must be type of str."
|
||||
self._model.det_db_score_mode = value
|
||||
|
||||
@use_dilation.setter
|
||||
def use_dilation(self, value):
|
||||
assert isinstance(
|
||||
value,
|
||||
bool), "The value to set `use_dilation` must be type of bool."
|
||||
self._model.use_dilation = value
|
||||
|
||||
@is_scale.setter
|
||||
def is_scale(self, value):
|
||||
assert isinstance(
|
||||
value, bool), "The value to set `is_scale` must be type of bool."
|
||||
self._model.is_scale = value
|
||||
|
||||
|
||||
class Classifier(FastDeployModel):
|
||||
def __init__(self,
|
||||
model_file="",
|
||||
params_file="",
|
||||
runtime_option=None,
|
||||
model_format=Frontend.PADDLE):
|
||||
# 调用基函数进行backend_option的初始化
|
||||
# 初始化后的option保存在self._runtime_option
|
||||
super(Classifier, self).__init__(runtime_option)
|
||||
|
||||
if (len(model_file) == 0):
|
||||
self._model = C.vision.ocr.Classifier()
|
||||
else:
|
||||
self._model = C.vision.ocr.Classifier(
|
||||
model_file, params_file, self._runtime_option, model_format)
|
||||
# 通过self.initialized判断整个模型的初始化是否成功
|
||||
assert self.initialized, "Classifier initialize failed."
|
||||
|
||||
@property
|
||||
def cls_thresh(self):
|
||||
return self._model.cls_thresh
|
||||
|
||||
@property
|
||||
def cls_image_shape(self):
|
||||
return self._model.cls_image_shape
|
||||
|
||||
@property
|
||||
def cls_batch_num(self):
|
||||
return self._model.cls_batch_num
|
||||
|
||||
@cls_thresh.setter
|
||||
def cls_thresh(self, value):
|
||||
assert isinstance(
|
||||
value,
|
||||
float), "The value to set `cls_thresh` must be type of float."
|
||||
self._model.cls_thresh = value
|
||||
|
||||
@cls_image_shape.setter
|
||||
def cls_image_shape(self, value):
|
||||
assert isinstance(
|
||||
value, list), "The value to set `cls_thresh` must be type of list."
|
||||
self._model.cls_image_shape = value
|
||||
|
||||
@cls_batch_num.setter
|
||||
def cls_batch_num(self, value):
|
||||
assert isinstance(
|
||||
value,
|
||||
int), "The value to set `cls_batch_num` must be type of int."
|
||||
self._model.cls_batch_num = value
|
||||
|
||||
|
||||
class Recognizer(FastDeployModel):
|
||||
def __init__(self,
|
||||
model_file="",
|
||||
params_file="",
|
||||
label_path="",
|
||||
runtime_option=None,
|
||||
model_format=Frontend.PADDLE):
|
||||
# 调用基函数进行backend_option的初始化
|
||||
# 初始化后的option保存在self._runtime_option
|
||||
super(Recognizer, self).__init__(runtime_option)
|
||||
|
||||
if (len(model_file) == 0):
|
||||
self._model = C.vision.ocr.Recognizer()
|
||||
else:
|
||||
self._model = C.vision.ocr.Recognizer(
|
||||
model_file, params_file, label_path, self._runtime_option,
|
||||
model_format)
|
||||
# 通过self.initialized判断整个模型的初始化是否成功
|
||||
assert self.initialized, "Recognizer initialize failed."
|
||||
|
||||
@property
|
||||
def rec_img_h(self):
|
||||
return self._model.rec_img_h
|
||||
|
||||
@property
|
||||
def rec_img_w(self):
|
||||
return self._model.rec_img_w
|
||||
|
||||
@property
|
||||
def rec_batch_num(self):
|
||||
return self._model.rec_batch_num
|
||||
|
||||
@rec_img_h.setter
|
||||
def rec_img_h(self, value):
|
||||
assert isinstance(
|
||||
value, int), "The value to set `rec_img_h` must be type of int."
|
||||
self._model.rec_img_h = value
|
||||
|
||||
@rec_img_w.setter
|
||||
def rec_img_w(self, value):
|
||||
assert isinstance(
|
||||
value, int), "The value to set `rec_img_w` must be type of int."
|
||||
self._model.rec_img_w = value
|
||||
|
||||
@rec_batch_num.setter
|
||||
def rec_batch_num(self, value):
|
||||
assert isinstance(
|
||||
value,
|
||||
int), "The value to set `rec_batch_num` must be type of int."
|
||||
self._model.rec_batch_num = value
|
||||
|
||||
|
||||
class PPOCRSystemv3(FastDeployModel):
|
||||
def __init__(self, det_model=None, cls_model=None, rec_model=None):
|
||||
assert det_model is not None and rec_model is not None, "The det_model and rec_model cannot be None."
|
||||
if cls_model is None:
|
||||
self.system = C.vision.ocr.PPOCRSystemv3(det_model._model, rec_model._model)
|
||||
else:
|
||||
self.system = C.vision.ocr.PPOCRSystemv3(det_model._model, cls_model._model, rec_model._model)
|
||||
|
||||
def predict(self, input_image):
|
||||
return self.system.predict(input_image)
|
||||
|
||||
|
||||
class PPOCRSystemv2(FastDeployModel):
|
||||
def __init__(self, det_model=None, cls_model=None, rec_model=None):
|
||||
assert det_model is not None and rec_model is not None, "The det_model and rec_model cannot be None."
|
||||
if cls_model is None:
|
||||
self.system = C.vision.ocr.PPOCRSystemv2(det_model._model, rec_model._model)
|
||||
else:
|
||||
self.system = C.vision.ocr.PPOCRSystemv2(det_model._model, cls_model._model, rec_model._model)
|
||||
|
||||
def predict(self, input_image):
|
||||
return self.system.predict(input_image)
|
16
python/fastdeploy/vision/segmentation/__init__.py
Normal file
16
python/fastdeploy/vision/segmentation/__init__.py
Normal file
@@ -0,0 +1,16 @@
|
||||
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
from __future__ import absolute_import
|
||||
|
||||
from .ppseg import PaddleSegModel
|
59
python/fastdeploy/vision/segmentation/ppseg/__init__.py
Normal file
59
python/fastdeploy/vision/segmentation/ppseg/__init__.py
Normal file
@@ -0,0 +1,59 @@
|
||||
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import
|
||||
import logging
|
||||
from .... import FastDeployModel, Frontend
|
||||
from .... import c_lib_wrap as C
|
||||
|
||||
|
||||
class PaddleSegModel(FastDeployModel):
|
||||
def __init__(self,
|
||||
model_file,
|
||||
params_file,
|
||||
config_file,
|
||||
runtime_option=None,
|
||||
model_format=Frontend.PADDLE):
|
||||
super(PaddleSegModel, self).__init__(runtime_option)
|
||||
|
||||
assert model_format == Frontend.PADDLE, "PaddleSeg only support model format of Frontend.Paddle now."
|
||||
self._model = C.vision.segmentation.PaddleSegModel(
|
||||
model_file, params_file, config_file, self._runtime_option,
|
||||
model_format)
|
||||
assert self.initialized, "PaddleSeg model initialize failed."
|
||||
|
||||
def predict(self, input_image):
|
||||
return self._model.predict(input_image)
|
||||
|
||||
@property
|
||||
def with_softmax(self):
|
||||
return self._model.with_softmax
|
||||
|
||||
@with_softmax.setter
|
||||
def with_softmax(self, value):
|
||||
assert isinstance(
|
||||
value,
|
||||
bool), "The value to set `with_softmax` must be type of bool."
|
||||
self._model.with_softmax = value
|
||||
|
||||
@property
|
||||
def is_vertical_screen(self):
|
||||
return self._model.is_vertical_screen
|
||||
|
||||
@is_vertical_screen.setter
|
||||
def is_vertical_screen(self, value):
|
||||
assert isinstance(
|
||||
value,
|
||||
bool), "The value to set `is_vertical_screen` must be type of bool."
|
||||
self._model.is_vertical_screen = value
|
70
python/fastdeploy/vision/visualize/__init__.py
Normal file
70
python/fastdeploy/vision/visualize/__init__.py
Normal file
@@ -0,0 +1,70 @@
|
||||
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import
|
||||
import logging
|
||||
from ... import c_lib_wrap as C
|
||||
|
||||
|
||||
def vis_detection(im_data,
|
||||
det_result,
|
||||
score_threshold=0.0,
|
||||
line_size=1,
|
||||
font_size=0.5):
|
||||
return C.vision.Visualize.vis_detection(
|
||||
im_data, det_result, score_threshold, line_size, font_size)
|
||||
|
||||
|
||||
def vis_face_detection(im_data, face_det_result, line_size=1, font_size=0.5):
|
||||
return C.vision.Visualize.vis_face_detection(im_data, face_det_result,
|
||||
line_size, font_size)
|
||||
|
||||
|
||||
def vis_segmentation(im_data, seg_result):
|
||||
return C.vision.Visualize.vis_segmentation(im_data, seg_result)
|
||||
|
||||
|
||||
def vis_matting_alpha(im_data,
|
||||
matting_result,
|
||||
remove_small_connected_area=False):
|
||||
return C.vision.Visualize.vis_matting_alpha(im_data, matting_result,
|
||||
remove_small_connected_area)
|
||||
|
||||
|
||||
def swap_background_matting(im_data,
|
||||
background,
|
||||
result,
|
||||
remove_small_connected_area=False):
|
||||
assert isinstance(
|
||||
result,
|
||||
C.vision.MattingResult), "The result must be MattingResult type"
|
||||
return C.vision.Visualize.swap_background_matting(
|
||||
im_data, background, result, remove_small_connected_area)
|
||||
|
||||
|
||||
def swap_background_segmentation(im_data, background, background_label,
|
||||
result):
|
||||
assert isinstance(
|
||||
result, C.vision.
|
||||
SegmentationResult), "The result must be SegmentaitonResult type"
|
||||
return C.vision.Visualize.swap_background_segmentation(
|
||||
im_data, background, background_label, result)
|
||||
|
||||
|
||||
def remove_small_connected_area(alpha_pred_data, threshold):
|
||||
assert len(alpha_pred_data.shape) == 3, "alpha has a (h, w, 1) shape"
|
||||
return C.vision.Visualize.remove_small_connected_area(alpha_pred_data,
|
||||
threshold)
|
||||
def vis_ppocr(im_data, det_result):
|
||||
return C.vision.Visualize.vis_ppocr(im_data, det_result)
|
5
python/requirements.txt
Normal file
5
python/requirements.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
wheel
|
||||
requests
|
||||
tqdm
|
||||
numpy
|
||||
opencv-python
|
407
python/setup.py
Normal file
407
python/setup.py
Normal file
@@ -0,0 +1,407 @@
|
||||
# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
# This file refered to github.com/onnx/onnx.git
|
||||
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
from __future__ import unicode_literals
|
||||
import shutil
|
||||
import os
|
||||
|
||||
TOP_DIR = os.path.realpath(os.path.dirname(__file__))
|
||||
TOP_DIR = os.path.split(TOP_DIR)[0]
|
||||
PACKAGE_NAME = os.getenv("PACKAGE_NAME", "fastdeploy")
|
||||
wheel_name = "fastdeploy-python"
|
||||
|
||||
from distutils.spawn import find_executable
|
||||
from distutils import sysconfig, log
|
||||
import setuptools
|
||||
import setuptools.command.build_py
|
||||
import setuptools.command.develop
|
||||
import setuptools.command.build_ext
|
||||
|
||||
from collections import namedtuple
|
||||
from contextlib import contextmanager
|
||||
import glob
|
||||
import shlex
|
||||
import subprocess
|
||||
import sys
|
||||
import platform
|
||||
from textwrap import dedent
|
||||
import multiprocessing
|
||||
|
||||
with open(os.path.join(TOP_DIR, "python", "requirements.txt")) as fin:
|
||||
REQUIRED_PACKAGES = fin.read()
|
||||
|
||||
setup_configs = dict()
|
||||
setup_configs["ENABLE_PADDLE_FRONTEND"] = os.getenv("ENABLE_PADDLE_FRONTEND",
|
||||
"ON")
|
||||
setup_configs["ENABLE_ORT_BACKEND"] = os.getenv("ENABLE_ORT_BACKEND", "ON")
|
||||
setup_configs["ENABLE_OPENVINO_BACKEND"] = os.getenv("ENABLE_OPENVINO_BACKEND",
|
||||
"OFF")
|
||||
setup_configs["ENABLE_PADDLE_BACKEND"] = os.getenv("ENABLE_PADDLE_BACKEND",
|
||||
"OFF")
|
||||
setup_configs["ENABLE_VISION"] = os.getenv("ENABLE_VISION", "ON")
|
||||
setup_configs["ENABLE_TEXT"] = os.getenv("ENABLE_TEXT", "ON")
|
||||
setup_configs["ENABLE_TRT_BACKEND"] = os.getenv("ENABLE_TRT_BACKEND", "OFF")
|
||||
setup_configs["WITH_GPU"] = os.getenv("WITH_GPU", "OFF")
|
||||
setup_configs["TRT_DIRECTORY"] = os.getenv("TRT_DIRECTORY", "UNDEFINED")
|
||||
setup_configs["CUDA_DIRECTORY"] = os.getenv("CUDA_DIRECTORY",
|
||||
"/usr/local/cuda")
|
||||
setup_configs["LIBRARY_NAME"] = PACKAGE_NAME
|
||||
setup_configs["PY_LIBRARY_NAME"] = PACKAGE_NAME + "_main"
|
||||
|
||||
if setup_configs["WITH_GPU"] == "ON":
|
||||
wheel_name = "fastdeploy-gpu-python"
|
||||
|
||||
if os.getenv("CMAKE_CXX_COMPILER", None) is not None:
|
||||
setup_configs["CMAKE_CXX_COMPILER"] = os.getenv("CMAKE_CXX_COMPILER")
|
||||
|
||||
SRC_DIR = os.path.join(TOP_DIR, PACKAGE_NAME)
|
||||
CMAKE_BUILD_DIR = os.path.join(TOP_DIR, '.setuptools-cmake-build')
|
||||
|
||||
WINDOWS = (os.name == 'nt')
|
||||
|
||||
CMAKE = find_executable('cmake3') or find_executable('cmake')
|
||||
MAKE = find_executable('make')
|
||||
|
||||
setup_requires = []
|
||||
extras_require = {}
|
||||
|
||||
################################################################################
|
||||
# Global variables for controlling the build variant
|
||||
################################################################################
|
||||
|
||||
# Default value is set to TRUE\1 to keep the settings same as the current ones.
|
||||
# However going forward the recomemded way to is to set this to False\0
|
||||
USE_MSVC_STATIC_RUNTIME = bool(
|
||||
os.getenv('USE_MSVC_STATIC_RUNTIME', '1') == '1')
|
||||
ONNX_NAMESPACE = os.getenv('ONNX_NAMESPACE', 'paddle2onnx')
|
||||
################################################################################
|
||||
# Version
|
||||
################################################################################
|
||||
|
||||
try:
|
||||
git_version = subprocess.check_output(
|
||||
['git', 'rev-parse', 'HEAD'], cwd=TOP_DIR).decode('ascii').strip()
|
||||
except (OSError, subprocess.CalledProcessError):
|
||||
git_version = None
|
||||
|
||||
with open(os.path.join(TOP_DIR, 'VERSION_NUMBER')) as version_file:
|
||||
VersionInfo = namedtuple('VersionInfo', ['version', 'git_version'])(
|
||||
version=version_file.read().strip(), git_version=git_version)
|
||||
|
||||
################################################################################
|
||||
# Pre Check
|
||||
################################################################################
|
||||
|
||||
assert CMAKE, 'Could not find "cmake" executable!'
|
||||
|
||||
################################################################################
|
||||
# Utilities
|
||||
################################################################################
|
||||
|
||||
|
||||
@contextmanager
|
||||
def cd(path):
|
||||
if not os.path.isabs(path):
|
||||
raise RuntimeError('Can only cd to absolute path, got: {}'.format(
|
||||
path))
|
||||
orig_path = os.getcwd()
|
||||
os.chdir(path)
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
os.chdir(orig_path)
|
||||
|
||||
|
||||
################################################################################
|
||||
# Customized commands
|
||||
################################################################################
|
||||
|
||||
|
||||
class ONNXCommand(setuptools.Command):
|
||||
user_options = []
|
||||
|
||||
def initialize_options(self):
|
||||
pass
|
||||
|
||||
def finalize_options(self):
|
||||
pass
|
||||
|
||||
|
||||
def get_all_files(dirname):
|
||||
files = list()
|
||||
for root, dirs, filenames in os.walk(dirname):
|
||||
for f in filenames:
|
||||
fullname = os.path.join(root, f)
|
||||
files.append(fullname)
|
||||
return files
|
||||
|
||||
|
||||
class create_version(ONNXCommand):
|
||||
def run(self):
|
||||
with open(os.path.join(SRC_DIR, 'version.py'), 'w') as f:
|
||||
f.write(
|
||||
dedent('''\
|
||||
# This file is generated by setup.py. DO NOT EDIT!
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
from __future__ import unicode_literals
|
||||
version = '{version}'
|
||||
git_version = '{git_version}'
|
||||
'''.format(**dict(VersionInfo._asdict()))))
|
||||
|
||||
|
||||
class cmake_build(setuptools.Command):
|
||||
"""
|
||||
Compiles everything when `python setupmnm.py build` is run using cmake.
|
||||
Custom args can be passed to cmake by specifying the `CMAKE_ARGS`
|
||||
environment variable.
|
||||
The number of CPUs used by `make` can be specified by passing `-j<ncpus>`
|
||||
to `setup.py build`. By default all CPUs are used.
|
||||
"""
|
||||
user_options = [(str('jobs='), str('j'),
|
||||
str('Specifies the number of jobs to use with make'))]
|
||||
|
||||
built = False
|
||||
|
||||
def initialize_options(self):
|
||||
self.jobs = None
|
||||
|
||||
def finalize_options(self):
|
||||
if sys.version_info[0] >= 3:
|
||||
self.set_undefined_options('build', ('parallel', 'jobs'))
|
||||
if self.jobs is None and os.getenv("MAX_JOBS") is not None:
|
||||
self.jobs = os.getenv("MAX_JOBS")
|
||||
self.jobs = multiprocessing.cpu_count() if self.jobs is None else int(
|
||||
self.jobs)
|
||||
|
||||
def run(self):
|
||||
if cmake_build.built:
|
||||
return
|
||||
cmake_build.built = True
|
||||
if not os.path.exists(CMAKE_BUILD_DIR):
|
||||
os.makedirs(CMAKE_BUILD_DIR)
|
||||
|
||||
with cd(CMAKE_BUILD_DIR):
|
||||
build_type = 'Release'
|
||||
# configure
|
||||
cmake_args = [
|
||||
CMAKE,
|
||||
'-DPYTHON_INCLUDE_DIR={}'.format(sysconfig.get_python_inc()),
|
||||
'-DPYTHON_EXECUTABLE={}'.format(sys.executable),
|
||||
'-DBUILD_FASTDEPLOY_PYTHON=ON',
|
||||
'-DCMAKE_EXPORT_COMPILE_COMMANDS=ON',
|
||||
'-DONNX_NAMESPACE={}'.format(ONNX_NAMESPACE),
|
||||
'-DPY_EXT_SUFFIX={}'.format(
|
||||
sysconfig.get_config_var('EXT_SUFFIX') or ''),
|
||||
]
|
||||
cmake_args.append('-DCMAKE_BUILD_TYPE=%s' % build_type)
|
||||
for k, v in setup_configs.items():
|
||||
cmake_args.append("-D{}={}".format(k, v))
|
||||
if WINDOWS:
|
||||
cmake_args.extend([
|
||||
# we need to link with libpython on windows, so
|
||||
# passing python version to window in order to
|
||||
# find python in cmake
|
||||
'-DPY_VERSION={}'.format('{0}.{1}'.format(* \
|
||||
sys.version_info[:2])),
|
||||
])
|
||||
if platform.architecture()[0] == '64bit':
|
||||
cmake_args.extend(['-A', 'x64', '-T', 'host=x64'])
|
||||
else:
|
||||
cmake_args.extend(['-A', 'Win32', '-T', 'host=x86'])
|
||||
if 'CMAKE_ARGS' in os.environ:
|
||||
extra_cmake_args = shlex.split(os.environ['CMAKE_ARGS'])
|
||||
# prevent crossfire with downstream scripts
|
||||
del os.environ['CMAKE_ARGS']
|
||||
log.info('Extra cmake args: {}'.format(extra_cmake_args))
|
||||
cmake_args.extend(extra_cmake_args)
|
||||
cmake_args.append(TOP_DIR)
|
||||
subprocess.check_call(cmake_args)
|
||||
|
||||
build_args = [CMAKE, '--build', os.curdir]
|
||||
if WINDOWS:
|
||||
build_args.extend(['--config', build_type])
|
||||
build_args.extend(['--', '/maxcpucount:{}'.format(self.jobs)])
|
||||
else:
|
||||
build_args.extend(['--', '-j', str(self.jobs)])
|
||||
subprocess.check_call(build_args)
|
||||
|
||||
|
||||
class build_py(setuptools.command.build_py.build_py):
|
||||
def run(self):
|
||||
self.run_command('create_version')
|
||||
self.run_command('cmake_build')
|
||||
|
||||
generated_python_files = \
|
||||
glob.glob(os.path.join(CMAKE_BUILD_DIR, PACKAGE_NAME, '*.py')) + \
|
||||
glob.glob(os.path.join(CMAKE_BUILD_DIR, PACKAGE_NAME, '*.pyi'))
|
||||
|
||||
for src in generated_python_files:
|
||||
dst = os.path.join(TOP_DIR, os.path.relpath(src, CMAKE_BUILD_DIR))
|
||||
self.copy_file(src, dst)
|
||||
|
||||
return setuptools.command.build_py.build_py.run(self)
|
||||
|
||||
|
||||
class develop(setuptools.command.develop.develop):
|
||||
def run(self):
|
||||
self.run_command('build_py')
|
||||
setuptools.command.develop.develop.run(self)
|
||||
|
||||
|
||||
class build_ext(setuptools.command.build_ext.build_ext):
|
||||
def run(self):
|
||||
self.run_command('cmake_build')
|
||||
setuptools.command.build_ext.build_ext.run(self)
|
||||
|
||||
def build_extensions(self):
|
||||
for ext in self.extensions:
|
||||
fullname = self.get_ext_fullname(ext.name)
|
||||
filename = os.path.basename(self.get_ext_filename(fullname))
|
||||
|
||||
lib_path = CMAKE_BUILD_DIR
|
||||
if os.name == 'nt':
|
||||
debug_lib_dir = os.path.join(lib_path, "Debug")
|
||||
release_lib_dir = os.path.join(lib_path, "Release")
|
||||
if os.path.exists(debug_lib_dir):
|
||||
lib_path = debug_lib_dir
|
||||
elif os.path.exists(release_lib_dir):
|
||||
lib_path = release_lib_dir
|
||||
src = os.path.join(lib_path, filename)
|
||||
dst = os.path.join(
|
||||
os.path.realpath(self.build_lib), PACKAGE_NAME, filename)
|
||||
self.copy_file(src, dst)
|
||||
|
||||
|
||||
class mypy_type_check(ONNXCommand):
|
||||
description = 'Run MyPy type checker'
|
||||
|
||||
def run(self):
|
||||
"""Run command."""
|
||||
onnx_script = os.path.realpath(
|
||||
os.path.join(
|
||||
os.path.dirname(os.path.abspath(__file__)),
|
||||
"tools/mypy-onnx.py"))
|
||||
returncode = subprocess.call([sys.executable, onnx_script])
|
||||
sys.exit(returncode)
|
||||
|
||||
|
||||
cmdclass = {
|
||||
'create_version': create_version,
|
||||
'cmake_build': cmake_build,
|
||||
'build_py': build_py,
|
||||
'develop': develop,
|
||||
'build_ext': build_ext,
|
||||
'typecheck': mypy_type_check,
|
||||
}
|
||||
|
||||
################################################################################
|
||||
# Extensions
|
||||
################################################################################
|
||||
|
||||
ext_modules = [
|
||||
setuptools.Extension(
|
||||
name=str(PACKAGE_NAME + '.' + setup_configs["PY_LIBRARY_NAME"]),
|
||||
sources=[]),
|
||||
]
|
||||
|
||||
################################################################################
|
||||
# Packages
|
||||
################################################################################
|
||||
|
||||
# no need to do fancy stuff so far
|
||||
if PACKAGE_NAME != "fastdeploy":
|
||||
packages = setuptools.find_packages(
|
||||
exclude=['fastdeploy*', 'build_scripts'])
|
||||
else:
|
||||
packages = setuptools.find_packages(exclude=['build_scripts'])
|
||||
|
||||
################################################################################
|
||||
# Test
|
||||
################################################################################
|
||||
|
||||
if sys.version_info[0] == 3:
|
||||
# Mypy doesn't work with Python 2
|
||||
extras_require['mypy'] = ['mypy==0.600']
|
||||
|
||||
################################################################################
|
||||
# Final
|
||||
################################################################################
|
||||
|
||||
package_data = {PACKAGE_NAME: ["LICENSE", "ThirdPartyNotices.txt"]}
|
||||
|
||||
if sys.argv[1] == "install" or sys.argv[1] == "bdist_wheel":
|
||||
shutil.copy(
|
||||
os.path.join(TOP_DIR, "ThirdPartyNotices.txt"),
|
||||
os.path.join(TOP_DIR, PACKAGE_NAME))
|
||||
shutil.copy(
|
||||
os.path.join(TOP_DIR, "LICENSE"), os.path.join(TOP_DIR, PACKAGE_NAME))
|
||||
if not os.path.exists(
|
||||
os.path.join(TOP_DIR, "python", "fastdeploy", "libs", "third_libs")):
|
||||
print(
|
||||
"Didn't detect path: fastdeploy/libs/third_libs exist, please execute `python setup.py build` first"
|
||||
)
|
||||
sys.exit(0)
|
||||
sys.path.append(TOP_DIR)
|
||||
from build_scripts.process_libraries import process_libraries
|
||||
all_lib_data = process_libraries(
|
||||
os.path.split(os.path.abspath(__file__))[0])
|
||||
package_data[PACKAGE_NAME].extend(all_lib_data)
|
||||
setuptools.setup(
|
||||
name=wheel_name,
|
||||
version=VersionInfo.version,
|
||||
ext_modules=ext_modules,
|
||||
description="Deploy Kit Tool For Deeplearning models.",
|
||||
packages=packages,
|
||||
package_data=package_data,
|
||||
include_package_data=True,
|
||||
setup_requires=setup_requires,
|
||||
extras_require=extras_require,
|
||||
author='fastdeploy',
|
||||
author_email='fastdeploy@baidu.com',
|
||||
url='https://github.com/PaddlePaddle/FastDeploy.git',
|
||||
install_requires=REQUIRED_PACKAGES,
|
||||
classifiers=[
|
||||
"Programming Language :: Python :: 3",
|
||||
"License :: OSI Approved :: Apache Software License",
|
||||
"Operating System :: OS Independent",
|
||||
],
|
||||
license='Apache 2.0')
|
||||
else:
|
||||
setuptools.setup(
|
||||
name=wheel_name,
|
||||
version=VersionInfo.version,
|
||||
description="Deploy Kit Tool For Deeplearning models.",
|
||||
ext_modules=ext_modules,
|
||||
cmdclass=cmdclass,
|
||||
packages=packages,
|
||||
package_data=package_data,
|
||||
include_package_data=True,
|
||||
setup_requires=setup_requires,
|
||||
extras_require=extras_require,
|
||||
author='fastdeploy',
|
||||
author_email='fastdeploy@baidu.com',
|
||||
url='https://github.com/PaddlePaddle/FastDeploy.git',
|
||||
install_requires=REQUIRED_PACKAGES,
|
||||
classifiers=[
|
||||
"Programming Language :: Python :: 3",
|
||||
"License :: OSI Approved :: Apache Software License",
|
||||
"Operating System :: OS Independent",
|
||||
],
|
||||
license='Apache 2.0')
|
Reference in New Issue
Block a user