未验证 提交 9b4b7a67 编写于 作者: W Wei Shengyu 提交者: GitHub

Merge pull request #1746 from weisy11/deploy_v2

add det code
AlgoModule:
- preprocess:
- processor_type: data_processor
processor_name: image_processor
image_processors:
- ResizeImage:
size: [640, 640]
interpolation: 2
- NormalizeImage:
scale: 0.00392157
mean: [0.485, 0.456, 0.406]
std: [0.229, 0.224, 0.225]
- ToRGB
from abc import ABC, abstractmethod
from algo_mod import build_algo_mod
from searcher import build_searcher
from data_processor import build_data_processor
from processor.algo_mod import predictors, searcher
def build_processor(config):
processor_type = config.get("processor_type")
if processor_type == "algo_mod":
return build_algo_mod(config)
elif processor_type == "searcher":
return build_searcher(config)
elif processor_type == "data_processor":
return build_data_processor(config)
else:
raise NotImplemented("processor_type {} not implemented.".format(processor_type))
processor_mod = locals()[processor_type]
processor_name = config.get("processor_name")
return getattr(processor_mod, processor_name)
class BaseProcessor(ABC):
......
from .fake_cls import FakeClassifier
from .. import BaseProcessor, build_processor
def build_algo_mod(config):
algo_name = config.get("algo_name")
if algo_name == "fake_clas":
return FakeClassifier(config)
class AlgoMod(BaseProcessor):
def __init__(self, config):
self.pre_processor = build_processor(config["pre_processor"])
self.predictor = build_processor(config["predictor"])
self.post_processor = build_processor(config["post_processor"])
def process(self, input_data):
input_data = self.pre_processor(input_data)
input_data = self.predictor(input_data)
input_data = self.post_processor(input_data)
return input_data
from functools import partial
import six
import math
import random
import cv2
import numpy as np
import importlib
from PIL import Image
import paddle
from utils import logger
from processor import BaseProcessor
class PreProcesser(object):
class ImageProcessor(BaseProcessor):
def __init__(self, config):
"""Image PreProcesser
Args:
config (list): A list consisting of Dict object that describe an image processer operator.
"""
super().__init__()
self.ops = self.create_ops(config)
def create_ops(self, config):
if not isinstance(config, list):
msg = "The preprocess config should be a list consisting of Dict object."
logger.error(msg)
raise Exception(msg)
mod = importlib.import_module(__name__)
ops = []
for op_config in config:
name = list(op_config)[0]
param = {} if op_config[name] is None else op_config[name]
op = getattr(mod, name)(**param)
ops.append(op)
return ops
self.processors = []
for processor_config in config.get("image_processors"):
name = list(processor_config)[0]
param = {} if processor_config[name] is None else processor_config[name]
op = locals()[name](**param)
self.processors.append(op)
def process(self, input_data):
image = input_data["input_image"]
for processor in self.processors:
if isinstance(processor, BaseProcessor):
input_data["image"] = image
input_data = processor.process(input_data)
else:
image = processor(image)
return input_data
class GetShapeInfo(BaseProcessor):
def __init__(self):
pass
def process(self, input_data):
input_image = input_data["input_image"]
image = input_data["image"]
input_data['im_shape'] = np.array(input_image.shape[:2], dtype=np.float32)
input_data['input_shape'] = np.array(image.shape[:2], dtype=np.float32)
input_data['scale_factor'] = np.array([image.shape[0] / input_image.shape[0],
image.shape[1] / input_image.shape[1]], dtype=np.float32)
def __call__(self, img, img_info=None):
if img_info:
for op in self.ops:
img, img_info = op(img, img_info)
return img, img_info
else:
for op in self.ops:
img = op(img)
return img
class ToTensor(BaseProcessor):
def __init__(self, config):
pass
def process(self, input_data):
image = input_data["image"]
input_data["input_tensor"] = paddle.to_tensor(image)
return input_data
class DecodeImage(object):
""" decode image """
def __init__(self, to_rgb=True, to_np=False, channel_first=False):
self.to_rgb = to_rgb
self.to_np = to_np # to numpy
self.channel_first = channel_first # only enabled when to_np is True
class ToRGB:
def __init__(self):
pass
def __call__(self, img):
img = img[:, :, ::-1]
return img
class ToCHWImage:
def __init__(self):
pass
def __call__(self, img, img_info=None):
if six.PY2:
assert type(img) is str and len(
img) > 0, "invalid input 'img' in DecodeImage"
else:
assert type(img) is bytes and len(
img) > 0, "invalid input 'img' in DecodeImage"
data = np.frombuffer(img, dtype='uint8')
img = cv2.imdecode(data, 1)
if self.to_rgb:
assert img.shape[2] == 3, 'invalid shape of image[%s]' % (
img.shape)
img = img[:, :, ::-1]
if self.channel_first:
img = img.transpose((2, 0, 1))
if img_info:
img_info["im_shape"] = np.array(img.shape[:2], dtype=np.float32)
img_info["scale_factor"] = np.array([1., 1.], dtype=np.float32)
return img, img_info
else:
return img
img = img.transpose((2, 0, 1))
return img
class ResizeImage:
def __init__(self,
size=None,
resize_short=None,
interpolation=None,
backend="cv2"):
if resize_short is not None and resize_short > 0:
self.resize_short = resize_short
self.w = None
self.h = None
elif size is not None:
self.resize_short = None
self.w = size if type(size) is int else size[0]
self.h = size if type(size) is int else size[1]
else:
raise Exception("invalid params for ReisizeImage for '\
'both 'size' and 'resize_short' are None")
class UnifiedResize(object):
def __init__(self, interpolation=None, backend="cv2"):
_cv2_interp_from_str = {
'nearest': cv2.INTER_NEAREST,
'bilinear': cv2.INTER_LINEAR,
......@@ -114,38 +122,12 @@ class UnifiedResize(object):
self.resize_func = partial(_pil_resize, resample=interpolation)
else:
logger.warning(
f"The backend of Resize only support \"cv2\" or \"PIL\". \"f{backend}\" is unavailable. Use \"cv2\" instead."
f"The backend of Resize only support \"cv2\" or \"PIL\". \"f{backend}\" is unavailable. "
f"Use \"cv2\" instead."
)
self.resize_func = cv2.resize
def __call__(self, src, size):
return self.resize_func(src, size)
class ResizeImage(object):
""" resize image """
def __init__(self,
size=None,
resize_short=None,
interpolation=None,
backend="cv2"):
if resize_short is not None and resize_short > 0:
self.resize_short = resize_short
self.w = None
self.h = None
elif size is not None:
self.resize_short = None
self.w = size if type(size) is int else size[0]
self.h = size if type(size) is int else size[1]
else:
raise Exception("invalid params for ReisizeImage for '\
'both 'size' and 'resize_short' are None")
self._resize_func = UnifiedResize(
interpolation=interpolation, backend=backend)
def __call__(self, img, img_info=None):
def __call__(self, img):
img_h, img_w = img.shape[:2]
if self.resize_short is not None:
percent = float(self.resize_short) / min(img_w, img_h)
......@@ -154,17 +136,11 @@ class ResizeImage(object):
else:
w = self.w
h = self.h
img = self._resize_func(img, (w, h))
if img_info:
img_info["input_shape"] = img.shape[:2]
img_info["scale_factor"] = np.array(
[img.shape[0] / img_h, img.shape[1] / img_w]).astype("float32")
return img, img_info
else:
return img
img = self.resize_func(img, (w, h))
return img
class CropImage(object):
class CropImage:
""" crop image """
def __init__(self, size):
......@@ -173,34 +149,25 @@ class CropImage(object):
else:
self.size = size # (h, w)
def __call__(self, img, img_info=None):
def __call__(self, img):
w, h = self.size
img_h, img_w = img.shape[:2]
if img_h < h or img_w < w:
raise Exception(
f"The size({h}, {w}) of CropImage must be greater than size({img_h}, {img_w}) of image. Please check image original size and size of ResizeImage if used."
f"The size({h}, {w}) of CropImage must be greater than size({img_h}, {img_w}) of image. "
f"Please check image original size and size of ResizeImage if used."
)
w_start = (img_w - w) // 2
h_start = (img_h - h) // 2
w_end = w_start + w
h_end = h_start + h
img = img[h_start:h_end, w_start:w_end, :]
if img_info:
img_info["input_shape"] = img.shape[:2]
# TODO(gaotingquan): im_shape is needed to update?
img_info["im_shape"] = np.array(img.shape[:2], dtype=np.float32)
return img, img_info
else:
return img
return img
class NormalizeImage(object):
""" normalize image such as substract mean, divide std
"""
class NormalizeImage:
def __init__(self,
scale=None,
mean=None,
......@@ -210,9 +177,8 @@ class NormalizeImage(object):
channel_num=3):
if isinstance(scale, str):
scale = eval(scale)
assert channel_num in [
3, 4
], "channel number of input image should be set to 3 or 4."
assert channel_num in [3, 4], \
"channel number of input image should be set to 3 or 4."
self.channel_num = channel_num
self.output_dtype = 'float16' if output_fp16 else 'float32'
self.scale = np.float32(scale if scale is not None else 1.0 / 255.0)
......@@ -224,12 +190,8 @@ class NormalizeImage(object):
self.mean = np.array(mean).reshape(shape).astype('float32')
self.std = np.array(std).reshape(shape).astype('float32')
def __call__(self, img, img_info=None):
if isinstance(img, Image.Image):
img = np.array(img)
assert isinstance(img,
np.ndarray), "invalid input 'img' in NormalizeImage"
def __call__(self, img):
assert isinstance(img, np.ndarray), "invalid input 'img' in NormalizeImage"
img = (img.astype('float32') * self.scale - self.mean) / self.std
......@@ -244,25 +206,4 @@ class NormalizeImage(object):
if self.order == 'chw' else np.concatenate(
(img, pad_zeros), axis=2))
img = img.astype(self.output_dtype)
if img_info:
return img, img_info
else:
return img
class ToCHWImage(object):
""" convert hwc image to chw image
"""
def __init__(self):
pass
def __call__(self, img, img_info=None):
if isinstance(img, Image.Image):
img = np.array(img)
img = img.transpose((2, 0, 1))
if img_info:
return img, img_info
else:
return img
return img
from .fake_cls import FakeClassifier
def build_algo_mod(config):
algo_name = config.get("algo_name")
if algo_name == "fake_clas":
return FakeClassifier(config)
from .. import BaseProcessor
from processor import BaseProcessor
class FakeClassifier(BaseProcessor):
......
# from bbox_cropper import
def build_data_processor(config):
return
from .. import BaseProcessor
class ImageReader(BaseProcessor):
def __init__(self):
pass
def process(self, input_data):
pass
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册