diff --git a/python/examples/imagenet/image_rpc_client.py b/python/examples/imagenet/image_rpc_client.py index f905179629f0dfc8c9da09b0cae90bae7be3687e..4d74d2ed26a757a6f7978d8071286d3d4bcd5dfb 100644 --- a/python/examples/imagenet/image_rpc_client.py +++ b/python/examples/imagenet/image_rpc_client.py @@ -13,22 +13,24 @@ # limitations under the License. import sys -from image_reader import ImageReader from paddle_serving_client import Client +from paddle_serving_app.reader import Sequential, File2Image, Resize, CenterCrop, RGB2BGR, Transpose, Div, Normalize import time client = Client() client.load_client_config(sys.argv[1]) client.connect(["127.0.0.1:9393"]) -reader = ImageReader() + +seq = Sequential([ + File2Image(), Resize(256), CenterCrop(224), RGB2BGR(), Transpose((2, 0, 1)), + Div(255), Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) +]) +print(seq) start = time.time() +image_file = "daisy.jpg" for i in range(1000): - with open("./data/n01440764_10026.JPEG", "rb") as f: - img = f.read() - img = reader.process_image(img) + img = seq(image_file) fetch_map = client.predict(feed={"image": img}, fetch=["score"]) end = time.time() print(end - start) - -#print(fetch_map["score"]) diff --git a/python/paddle_serving_app/reader/__init__.py b/python/paddle_serving_app/reader/__init__.py index 61f1bfed083e3bb7cf158a6301b61eb5df8679c5..397c5caa91a8ab3bb33cde58e944c8dfc917889a 100644 --- a/python/paddle_serving_app/reader/__init__.py +++ b/python/paddle_serving_app/reader/__init__.py @@ -11,4 +11,4 @@ # 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 .image_reader import ImageReader, File2Image, URL2Image, Sequential, Normalize, CenterCrop, Resize +from .image_reader import ImageReader, File2Image, URL2Image, Sequential, Normalize, CenterCrop, Resize, Transpose, Div, RGB2BGR, BGR2RGB diff --git a/python/paddle_serving_app/reader/functional.py b/python/paddle_serving_app/reader/functional.py index 80048150a11c771775757f699539c7df9bf5c027..6d1955ff78679e9757bddf850c3b9551860d33ca 100644 --- a/python/paddle_serving_app/reader/functional.py +++ b/python/paddle_serving_app/reader/functional.py @@ -16,14 +16,17 @@ import cv2 import numpy as np +def transpose(img, transpose_target): + img = img.transpose(transpose_target) + return img + + def normalize(img, mean, std): # need to optimize here - img = img.astype('float32').transpose((2, 0, 1)) / 255 img_mean = np.array(mean).reshape((3, 1, 1)) img_std = np.array(std).reshape((3, 1, 1)) img -= img_mean img /= img_std - img = img.transpose((1, 2, 0)) return img @@ -47,7 +50,7 @@ def resize(img, target_size, interpolation): resized_width = target_size[0] resized_height = target_size[1] else: - percent = float(target_size) / min(img.shape[1], img.shape[2]) + percent = float(target_size) / min(img.shape[0], img.shape[1]) resized_width = int(round(img.shape[1] * percent)) resized_height = int(round(img.shape[0] * percent)) if interpolation: @@ -55,5 +58,4 @@ def resize(img, target_size, interpolation): img, (resized_width, resized_height), interpolation=interpolation) else: resized = cv2.resize(img, (resized_width, resized_height)) - print(resized.shape) return resized diff --git a/python/paddle_serving_app/reader/image_reader.py b/python/paddle_serving_app/reader/image_reader.py index ab076c722917f31f3f87fcec0b3b3d16cedcd099..9342405cdd0f1038dbdbb919356520321a39b888 100644 --- a/python/paddle_serving_app/reader/image_reader.py +++ b/python/paddle_serving_app/reader/image_reader.py @@ -17,7 +17,7 @@ import numpy as np import base64 import functional as F -_cv2_interpolation_to_str = {cv2.INTER_LINEAR: "cv2.INTER_LINEAR"} +_cv2_interpolation_to_str = {cv2.INTER_LINEAR: "cv2.INTER_LINEAR", None: "None"} class Sequential(object): @@ -51,6 +51,28 @@ class Sequential(object): return format_string_ +class RGB2BGR(object): + def __init__(self): + pass + + def __call__(self, img): + return img[:, :, ::-1] + + def __repr__(self): + return self.__class__.__name__ + "()" + + +class BGR2RGB(object): + def __init__(self): + pass + + def __call__(self, img): + return img[:, :, ::-1] + + def __repr__(self): + return self.__class__.__name__ + "()" + + class File2Image(object): def __init__(self): pass @@ -81,6 +103,40 @@ class URL2Image(object): return self.__class__.__name__ + "()" +class Base64ToImage(object): + def __init__(self): + pass + + def __call__(self, img_base64): + img = base64.b64decode(img_base64) + return img + + def __repr__(self): + return self.__class__.__name__ + "()" + + +class Div(object): + """ divide by some float number """ + + def __init__(self, value): + self.value = value + + def __call__(self, img): + """ + Args: + img (numpy array): (int8 numpy array) + + Returns: + img (numpy array): (float32 numpy array) + """ + img = img.astype('float32') / self.value + + return img + + def __repr__(self): + return self.__class__.__name__ + "({})".format(self.value) + + class Normalize(object): """Normalize a tensor image with mean and standard deviation. Given mean: ``(M1,...,Mn)`` and std: ``(S1,..,Sn)`` for ``n`` channels, this transform @@ -115,6 +171,27 @@ class Normalize(object): self.std) +class Lambda(object): + """Apply a user-defined lambda as a transform. + Very shame to just copy from + https://github.com/pytorch/vision/blob/master/torchvision/transforms/transforms.py#L301 + + Args: + lambd (function): Lambda/function to be used for transform. + """ + + def __init__(self, lambd): + assert callable(lambd), repr(type(lambd) + .__name__) + " object is not callable" + self.lambd = lambd + + def __call__(self, img): + return self.lambd(img) + + def __repr__(self): + return self.__class__.__name__ + '()' + + class CenterCrop(object): """Crops the given Image at the center. @@ -154,18 +231,32 @@ class Resize(object): ``PIL.Image.BILINEAR`` """ - def __init__(self, size, interpolation=cv2.INTER_LINEAR): + def __init__(self, size, interpolation=None): self.size = size self.interpolation = interpolation def __call__(self, img): return F.resize(img, self.size, self.interpolation) - def __repr__(self, img): + def __repr__(self): return self.__class__.__name__ + '(size={0}, interpolation={1})'.format( self.size, _cv2_interpolation_to_str[self.interpolation]) +class Transpose(object): + def __init__(self, transpose_target): + self.transpose_target = transpose_target + + def __call__(self, img): + return F.transpose(img, self.transpose_target) + return img + + def __repr__(self): + format_string = self.__class__.__name__ + \ + "({})".format(self.transpose_target) + return format_string + + class ImageReader(): def __init__(self, image_shape=[3, 224, 224],