提交 90368eb1 编写于 作者: W weishengyu

add det code

上级 2595af2b
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 abc import ABC, abstractmethod
from algo_mod import build_algo_mod from processor.algo_mod import predictors, searcher
from searcher import build_searcher
from data_processor import build_data_processor
def build_processor(config): def build_processor(config):
processor_type = config.get("processor_type") processor_type = config.get("processor_type")
if processor_type == "algo_mod": processor_mod = locals()[processor_type]
return build_algo_mod(config) processor_name = config.get("processor_name")
elif processor_type == "searcher": return getattr(processor_mod, processor_name)
return build_searcher(config)
elif processor_type == "data_processor":
return build_data_processor(config)
else:
raise NotImplemented("processor_type {} not implemented.".format(processor_type))
class BaseProcessor(ABC): class BaseProcessor(ABC):
......
from .fake_cls import FakeClassifier from .. import BaseProcessor, build_processor
def build_algo_mod(config): class AlgoMod(BaseProcessor):
algo_name = config.get("algo_name") def __init__(self, config):
if algo_name == "fake_clas": self.pre_processor = build_processor(config["pre_processor"])
return FakeClassifier(config) 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 .. import BaseProcessor from processor import BaseProcessor
class BBoxCropper(BaseProcessor): class BBoxCropper(BaseProcessor):
......
from functools import partial from functools import partial
import six
import math
import random
import cv2 import cv2
import numpy as np import numpy as np
import importlib import importlib
from PIL import Image from PIL import Image
import paddle
from utils import logger from utils import logger
from processor import BaseProcessor
class PreProcesser(object): class ImageProcessor(BaseProcessor):
def __init__(self, config): def __init__(self, config):
"""Image PreProcesser self.processors = []
for processor_config in config.get("image_processors"):
Args: name = list(processor_config)[0]
config (list): A list consisting of Dict object that describe an image processer operator. param = {} if processor_config[name] is None else processor_config[name]
""" op = locals()[name](**param)
super().__init__() self.processors.append(op)
self.ops = self.create_ops(config)
def process(self, input_data):
def create_ops(self, config): image = input_data["input_image"]
if not isinstance(config, list): for processor in self.processors:
msg = "The preprocess config should be a list consisting of Dict object." if isinstance(processor, BaseProcessor):
logger.error(msg) input_data["image"] = image
raise Exception(msg) input_data = processor.process(input_data)
mod = importlib.import_module(__name__) else:
ops = [] image = processor(image)
for op_config in config: return input_data
name = list(op_config)[0]
param = {} if op_config[name] is None else op_config[name]
op = getattr(mod, name)(**param) class GetShapeInfo(BaseProcessor):
ops.append(op) def __init__(self):
return ops 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): class ToRGB:
self.to_rgb = to_rgb def __init__(self):
self.to_np = to_np # to numpy pass
self.channel_first = channel_first # only enabled when to_np is True
def __call__(self, img):
img = img[:, :, ::-1]
return img
class ToCHWImage:
def __init__(self):
pass
def __call__(self, img, img_info=None): def __call__(self, img, img_info=None):
if six.PY2: img = img.transpose((2, 0, 1))
assert type(img) is str and len( return img
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
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 = { _cv2_interp_from_str = {
'nearest': cv2.INTER_NEAREST, 'nearest': cv2.INTER_NEAREST,
'bilinear': cv2.INTER_LINEAR, 'bilinear': cv2.INTER_LINEAR,
...@@ -114,38 +122,12 @@ class UnifiedResize(object): ...@@ -114,38 +122,12 @@ class UnifiedResize(object):
self.resize_func = partial(_pil_resize, resample=interpolation) self.resize_func = partial(_pil_resize, resample=interpolation)
else: else:
logger.warning( 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 self.resize_func = cv2.resize
def __call__(self, src, size): def __call__(self, img):
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):
img_h, img_w = img.shape[:2] img_h, img_w = img.shape[:2]
if self.resize_short is not None: if self.resize_short is not None:
percent = float(self.resize_short) / min(img_w, img_h) percent = float(self.resize_short) / min(img_w, img_h)
...@@ -154,17 +136,11 @@ class ResizeImage(object): ...@@ -154,17 +136,11 @@ class ResizeImage(object):
else: else:
w = self.w w = self.w
h = self.h h = self.h
img = self._resize_func(img, (w, h)) img = self.resize_func(img, (w, h))
if img_info: return img
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
class CropImage(object): class CropImage:
""" crop image """ """ crop image """
def __init__(self, size): def __init__(self, size):
...@@ -173,34 +149,25 @@ class CropImage(object): ...@@ -173,34 +149,25 @@ class CropImage(object):
else: else:
self.size = size # (h, w) self.size = size # (h, w)
def __call__(self, img, img_info=None): def __call__(self, img):
w, h = self.size w, h = self.size
img_h, img_w = img.shape[:2] img_h, img_w = img.shape[:2]
if img_h < h or img_w < w: if img_h < h or img_w < w:
raise Exception( 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 w_start = (img_w - w) // 2
h_start = (img_h - h) // 2 h_start = (img_h - h) // 2
w_end = w_start + w w_end = w_start + w
h_end = h_start + h h_end = h_start + h
img = img[h_start:h_end, w_start:w_end, :] img = img[h_start:h_end, w_start:w_end, :]
if img_info: return img
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
class NormalizeImage(object):
""" normalize image such as substract mean, divide std
"""
class NormalizeImage:
def __init__(self, def __init__(self,
scale=None, scale=None,
mean=None, mean=None,
...@@ -210,9 +177,8 @@ class NormalizeImage(object): ...@@ -210,9 +177,8 @@ class NormalizeImage(object):
channel_num=3): channel_num=3):
if isinstance(scale, str): if isinstance(scale, str):
scale = eval(scale) scale = eval(scale)
assert channel_num in [ assert channel_num in [3, 4], \
3, 4 "channel number of input image should be set to 3 or 4."
], "channel number of input image should be set to 3 or 4."
self.channel_num = channel_num self.channel_num = channel_num
self.output_dtype = 'float16' if output_fp16 else 'float32' self.output_dtype = 'float16' if output_fp16 else 'float32'
self.scale = np.float32(scale if scale is not None else 1.0 / 255.0) self.scale = np.float32(scale if scale is not None else 1.0 / 255.0)
...@@ -224,12 +190,8 @@ class NormalizeImage(object): ...@@ -224,12 +190,8 @@ class NormalizeImage(object):
self.mean = np.array(mean).reshape(shape).astype('float32') self.mean = np.array(mean).reshape(shape).astype('float32')
self.std = np.array(std).reshape(shape).astype('float32') self.std = np.array(std).reshape(shape).astype('float32')
def __call__(self, img, img_info=None): def __call__(self, img):
if isinstance(img, Image.Image): assert isinstance(img, np.ndarray), "invalid input 'img' in NormalizeImage"
img = np.array(img)
assert isinstance(img,
np.ndarray), "invalid input 'img' in NormalizeImage"
img = (img.astype('float32') * self.scale - self.mean) / self.std img = (img.astype('float32') * self.scale - self.mean) / self.std
...@@ -244,25 +206,4 @@ class NormalizeImage(object): ...@@ -244,25 +206,4 @@ class NormalizeImage(object):
if self.order == 'chw' else np.concatenate( if self.order == 'chw' else np.concatenate(
(img, pad_zeros), axis=2)) (img, pad_zeros), axis=2))
img = img.astype(self.output_dtype) img = img.astype(self.output_dtype)
if img_info: return img
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
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): 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.
先完成此消息的编辑!
想要评论请 注册