diff --git a/docs/imgs/Readme_Related/Image_Classification_MarineBiometrics.png b/docs/imgs/Readme_Related/Image_Classification_MarineBiometrics.png new file mode 100644 index 0000000000000000000000000000000000000000..0076ea232298f58055664ddfaa06c76a1d205fae Binary files /dev/null and b/docs/imgs/Readme_Related/Image_Classification_MarineBiometrics.png differ diff --git a/modules/thirdparty/image/classification/marine_biometrics/README.md b/modules/thirdparty/image/classification/marine_biometrics/README.md new file mode 100644 index 0000000000000000000000000000000000000000..6ba7acd92dc5f94c28a65695a7fcd0f93050190e --- /dev/null +++ b/modules/thirdparty/image/classification/marine_biometrics/README.md @@ -0,0 +1,69 @@ +marine_biometrics + +类别 图像 - 图像分类 + +网络 ResNet50_vd_ssld + +数据集 Fish4Knowledge + +# 模型概述 +海洋生物识别(marine_biometrics),该模型可准确识别鱼的种类。该PaddleHub Module支持API预测及命令行预测。 + +# 选择模型版本进行安装 +$ hub install marine_biometrics==1.0.0 + +# 在线体验 +[AI Studio快速体验](https://aistudio.baidu.com/aistudio/projectdetail/1667809) + +# 命令行预测示例 +$ hub run marine_biometrics --image 1.png --use_gpu True + +# Module API说明 +## def predict(data) +海洋生物识别预测接口,输入一张图像,输出该图像上鱼的类别 +### 参数 +- data:dict类型,key为image,str类型,value为待检测的图片路径,list类型。 + +### 返回 +- result:list类型,每个元素为对应输入图片的预测结果。预测结果为dict类型,key为该图片分类结果label,value为该label对应的概率 + +# 代码示例 + +## API调用 + +~~~ +import cv2 +import paddlehub as hub + +module = hub.Module(name="MarineBiometrics") + +images = [cv2.imread('PATH/TO/IMAGE')] + +# execute predict and print the result +results = module.predict(images=images) +for result in results: + print(result) +~~~ + +## 命令行调用 +~~~ +$ hub run marine_biometrics --image 1.png --use_gpu True +~~~ + +# 效果展示 + +## 原图 + + +## 输出结果 +~~~ +[{'category_id': 16, 'category': 'Plectroglyphidodon_dickii', 'score': 0.9932127}] +~~~ + +# 贡献者 +郑博培、彭兆帅 + +# 依赖 +paddlepaddle >= 2.0.0 + +paddlehub >= 2.0.0 diff --git a/modules/thirdparty/image/classification/marine_biometrics/__init__.py b/modules/thirdparty/image/classification/marine_biometrics/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..8b137891791fe96927ad78e64b0aad7bded08bdc --- /dev/null +++ b/modules/thirdparty/image/classification/marine_biometrics/__init__.py @@ -0,0 +1 @@ + diff --git a/modules/thirdparty/image/classification/marine_biometrics/module.py b/modules/thirdparty/image/classification/marine_biometrics/module.py new file mode 100644 index 0000000000000000000000000000000000000000..f20cf1ae3af13ff4f1e5bfeb416fd7b6ec60a4b1 --- /dev/null +++ b/modules/thirdparty/image/classification/marine_biometrics/module.py @@ -0,0 +1,147 @@ +from __future__ import absolute_import +from __future__ import division + +import os +import cv2 +import argparse +import base64 +import paddlex as pdx + +import numpy as np +import paddlehub as hub +from paddlehub.module.module import moduleinfo, runnable, serving + + +def base64_to_cv2(b64str): + data = base64.b64decode(b64str.encode('utf8')) + data = np.fromstring(data, np.uint8) + data = cv2.imdecode(data, cv2.IMREAD_COLOR) + return data + + +def cv2_to_base64(image): + # return base64.b64encode(image) + data = cv2.imencode('.jpg', image)[1] + return base64.b64encode(data.tostring()).decode('utf8') + + +def read_images(paths): + images = [] + for path in paths: + images.append(cv2.imread(path)) + return images + + +@moduleinfo( + name='marine_biometrics', + type='cv/classification', + author='郑博培、彭兆帅', + author_email='2733821739@qq.com, 1084667371@qq.com', + summary='The model uses convolution neural network to tell you the key to identify marine fish, so that anyone can call out the names of the creatures.', + version='1.0.0') +class MODULE(hub.Module): + def _initialize(self, **kwargs): + self.default_pretrained_model_path = os.path.join( + self.directory, 'assets') + self.model = pdx.deploy.Predictor(self.default_pretrained_model_path, + **kwargs) + + def predict(self, + images=None, + paths=None, + data=None, + batch_size=1, + use_gpu=False, + **kwargs): + + all_data = images if images is not None else read_images(paths) + total_num = len(all_data) + loop_num = int(np.ceil(total_num / batch_size)) + + res = [] + for iter_id in range(loop_num): + batch_data = list() + handle_id = iter_id * batch_size + for image_id in range(batch_size): + try: + batch_data.append(all_data[handle_id + image_id]) + except IndexError: + break + out = self.model.batch_predict(batch_data, **kwargs) + res.extend(out) + return res + + @serving + def serving_method(self, images, **kwargs): + """ + Run as a service. + """ + images_decode = [base64_to_cv2(image) for image in images] + results = self.predict(images_decode, **kwargs) + res = [] + for result in results: + if isinstance(result, dict): + # result_new = dict() + for key, value in result.items(): + if isinstance(value, np.ndarray): + result[key] = cv2_to_base64(value) + elif isinstance(value, np.generic): + result[key] = np.asscalar(value) + + elif isinstance(result, list): + for index in range(len(result)): + for key, value in result[index].items(): + if isinstance(value, np.ndarray): + result[index][key] = cv2_to_base64(value) + elif isinstance(value, np.generic): + result[index][key] = np.asscalar(value) + else: + raise RuntimeError('The result cannot be used in serving.') + res.append(result) + return res + + @runnable + def run_cmd(self, argvs): + """ + Run as a command. + """ + self.parser = argparse.ArgumentParser( + description="Run the {} module.".format(self.name), + prog='hub run {}'.format(self.name), + usage='%(prog)s', + add_help=True) + self.arg_input_group = self.parser.add_argument_group( + title="Input options", description="Input data. Required") + self.arg_config_group = self.parser.add_argument_group( + title="Config options", + description= + "Run configuration for controlling module behavior, not required.") + self.add_module_config_arg() + self.add_module_input_arg() + args = self.parser.parse_args(argvs) + results = self.predict( + paths=[args.input_path], + use_gpu=args.use_gpu) + return results + + def add_module_config_arg(self): + """ + Add the command config options. + """ + self.arg_config_group.add_argument( + '--use_gpu', + type=bool, + default=False, + help="whether use GPU or not") + + def add_module_input_arg(self): + """ + Add the command input options. + """ + self.arg_input_group.add_argument( + '--input_path', type=str, help="path to image.") + +if __name__ == '__main__': + module = MODULE(directory='./new_model') + images = [cv2.imread('./cat.jpg'), cv2.imread('./cat.jpg'), cv2.imread('./cat.jpg')] + res = module.predict(images=images) diff --git a/modules/thirdparty/image/classification/marine_biometrics/serving_client_demo.py b/modules/thirdparty/image/classification/marine_biometrics/serving_client_demo.py new file mode 100644 index 0000000000000000000000000000000000000000..3acaa6c9608827577638f15b777e652546aef941 --- /dev/null +++ b/modules/thirdparty/image/classification/marine_biometrics/serving_client_demo.py @@ -0,0 +1,25 @@ +# coding: utf8 +import requests +import json +import cv2 +import base64 + + +def cv2_to_base64(image): + data = cv2.imencode('.jpg', image)[1] + return base64.b64encode(data.tostring()).decode('utf8') + + +if __name__ == '__main__': + # 获取图片的base64编码格式 + img1 = cv2_to_base64(cv2.imread("IMAGE_PATH1")) + img2 = cv2_to_base64(cv2.imread("IMAGE_PATH2")) + data = {'images': [img1, img2]} + # 指定content-type + headers = {"Content-type": "application/json"} + # 发送HTTP请求 + url = "http://127.0.0.1:8866/predict/MarineBiometrics" + r = requests.post(url=url, headers=headers, data=json.dumps(data)) + + # 打印预测结果 + print(r.json()["results"])