From ffdd282cf332b6a5c6af1b52003a13eaaf60af12 Mon Sep 17 00:00:00 2001 From: GuoRentong Date: Thu, 24 Mar 2022 11:06:57 +0800 Subject: [PATCH] Add cv2 implementation of image decode Signed-off-by: GuoRentong --- .gitignore | 110 ++++++++++++++++++++++++++++++++++++++++++++ README.md | 74 ++++++++++++++++++++++++++++- __init__.py | 20 ++++++++ image_decode_cv2.py | 62 +++++++++++++++++++++++++ requirements.txt | 3 ++ 5 files changed, 268 insertions(+), 1 deletion(-) create mode 100644 .gitignore create mode 100644 __init__.py create mode 100644 image_decode_cv2.py create mode 100644 requirements.txt diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d1a994f --- /dev/null +++ b/.gitignore @@ -0,0 +1,110 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a Python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +tests/unittests/test_cache/* +nosetests.xml +coverage.xml +*.cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ + +.DS_Store +.idea +.try +.vscode/ diff --git a/README.md b/README.md index 74e879d..6b3c978 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,74 @@ -# cv2 +## Image Decode Implementation with CV2 + +*author: Kaiyuan Hu, Rentong Guo* + + + +### Desription + +An image decode operator implementation with OpenCV. + + + +```python +import towhee import ops + +img_decode = ops.image_decode.cv2() +img = img_decode('./dog.jpg') +``` + + + +### Factory method + +Create the operator via the following factory method + +***ops.image_decode.cv2()*** + + + +### Interface + +An image decode operator takes an image path as input. It decodes the image back to ndarray. + + + +**Parameters:** + +​ ***img***: *str* + +​ Image file path. + + + +**Returns**: *numpy.ndarray* + +​ The decoded image data. + + + +### Code Example + +Load a image from path './dog.jpg'. + + *Write the pipeline in simplified style*: + +```python +import towhee.DataCollection as dc + +dc.glob(./dog.jpg) + .image_decode.cv2() + .show() +``` + +*Write a same pipeline with explicit inputs/outputs name specifications:* + +```python +import towhee.DataCollection as dc + +dc.glob['path'](./dog.jpg) + .image_decode.cv2['path', 'img']() + .select('img') + .show() +``` diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..c3f28e4 --- /dev/null +++ b/__init__.py @@ -0,0 +1,20 @@ +# Copyright 2021 Zilliz. 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 .image_decode_cv2 import ImageDecodeCV2 + + +# The factory method +def cv2(): + return ImageDecodeCV2() diff --git a/image_decode_cv2.py b/image_decode_cv2.py new file mode 100644 index 0000000..b5c4983 --- /dev/null +++ b/image_decode_cv2.py @@ -0,0 +1,62 @@ +# Copyright 2021 Zilliz. 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 logging +import cv2 +import requests +import numpy as np + +from towhee import register +from towhee.operator import PyOperator, OperatorFlag +from towhee._types import Image + +log = logging.getLogger() + + +@register(output_schema=['img'], + flag=OperatorFlag.STATELESS | OperatorFlag.REUSEABLE) +class ImageDecodeCV2(PyOperator): + def __init__(self): + pass + + @staticmethod + def _load_from_remote(image_url: str) -> np.ndarray: + try: + r = requests.get(image_url, timeout=(20, 20)) + if r.status_code // 100 != 2: + log.error('Download image from %s failed, error msg: %s, request code: %s ', + image_url, r.text, r.status_code) + return None + arr = np.asarray(bytearray(r.content), dtype=np.uint8) + return cv2.imdecode(arr, -1) + except Exception as e: + log.error('Download image from %s failed, error msg: %s', image_url, str(e)) + return False + + @staticmethod + def _load_from_local(image_path: str) -> np.ndarray: + return cv2.imread(image_path) + + def __call__(self, image_path: str): + if image_path.startswith('http'): + bgr_cv_image = ImageDecodeCV2._load_from_remote(image_path) + else: + bgr_cv_image = ImageDecodeCV2._load_from_local(image_path) + if bgr_cv_image is None: + err = 'Read image %s failed' % image_path + log.error(err) + raise RuntimeError(err) + + return Image(bgr_cv_image, 'BGR') diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..23f1708 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +opencv-python +requests +numpy \ No newline at end of file