---
comments: true
---
# 通用图像分类产线使用教程
## 1. 通用图像分类产线介绍
图像分类是一种将图像分配到预定义类别的技术。它广泛应用于物体识别、场景理解和自动标注等领域。图像分类可以识别各种物体,如动物、植物、交通标志等,并根据其特征将其归类。通过使用深度学习模型,图像分类能够自动提取图像特征并进行准确分类。
通用图像分类产线中包含了图像分类模块,如您更考虑模型精度,请选择精度较高的模型,如您更考虑模型推理速度,请选择推理速度较快的模型,如您更考虑模型存储大小,请选择存储大小较小的模型。
👉模型列表详情
| 模型 |
Top1 Acc(%) |
GPU推理耗时 (ms) |
CPU推理耗时(ms) |
模型存储大小 (M) |
介绍 |
| CLIP_vit_base_patch16_224 |
85.36 |
13.1957 |
285.493 |
306.5 M |
CLIP是一种基于视觉和语言相关联的图像分类模型,采用对比学习和预训练方法,实现无监督或弱监督的图像分类,尤其适用于大规模数据集。模型通过将图像和文本映射到同一表示空间,学习到通用特征,具有良好的泛化能力和解释性。其在较好的训练误差,在很多下游任务都有较好的表现。 |
| CLIP_vit_large_patch14_224 |
88.1 |
51.1284 |
1131.28 |
1.04 G |
| ConvNeXt_base_224 |
83.84 |
12.8473 |
1513.87 |
313.9 M |
ConvNeXt系列模型是Meta在2022年提出的基于CNN架构的模型。该系列模型是在ResNet的基础上,通过借鉴SwinTransformer的优点设计,包括训练策略和网络结构的优化思路,从而改进的纯CNN架构网络,探索了卷积神经网络的性能上限。ConvNeXt系列模型具备卷积神经网络的诸多优点,包括推理效率高和易于迁移到下游任务等。 |
| ConvNeXt_base_384 |
84.90 |
31.7607 |
3967.05 |
313.9 M |
| ConvNeXt_large_224 |
84.26 |
26.8103 |
2463.56 |
700.7 M |
| ConvNeXt_large_384 |
85.27 |
66.4058 |
6598.92 |
700.7 M |
| ConvNeXt_small |
83.13 |
9.74075 |
1127.6 |
178.0 M |
| ConvNeXt_tiny |
82.03 |
5.48923 |
672.559 |
104.1 M |
| FasterNet-L |
83.5 |
23.4415 |
- |
357.1 M |
FasterNet是一个旨在提高运行速度的神经网络,改进点主要如下:
1.重新审视了流行的运算符,发现低FLOPS主要来自于运算频繁的内存访问,特别是深度卷积;
2.提出了部分卷积(PConv),通过减少冗余计算和内存访问来更高效地提取图像特征;
3.基于PConv推出了FasterNet系列模型,这是一种新的设计方案,在不影响模型任务性能的情况下,在各种设备上实现了显著更高的运行速度。 |
| FasterNet-M |
83.0 |
21.8936 |
- |
204.6 M |
| FasterNet-S |
81.3 |
13.0409 |
- |
119.3 M |
| FasterNet-T0 |
71.9 |
12.2432 |
- |
15.1 M |
| FasterNet-T1 |
75.9 |
11.3562 |
- |
29.2 M |
| FasterNet-T2 |
79.1 |
10.703 |
- |
57.4 M |
| MobileNetV1_x0_5 |
63.5 |
1.86754 |
7.48297 |
4.8 M |
MobileNetV1是Google于2017年发布的用于移动设备或嵌入式设备中的网络。该网络将传统的卷积操作拆解成深度可分离卷积,即Depthwise卷积和Pointwise卷积的组合。相比传统的卷积网络,该组合可以大大节省参数量和计算量。同时该网络可以用于图像分类等其他视觉任务中。 |
| MobileNetV1_x0_25 |
51.4 |
1.83478 |
4.83674 |
1.8 M |
| MobileNetV1_x0_75 |
68.8 |
2.57903 |
10.6343 |
9.3 M |
| MobileNetV1_x1_0 |
71.0 |
2.78781 |
13.98 |
15.2 M |
| MobileNetV2_x0_5 |
65.0 |
4.94234 |
11.1629 |
7.1 M |
MobileNetV2是Google继MobileNetV1提出的一种轻量级网络。相比MobileNetV1,MobileNetV2提出了Linear bottlenecks与Inverted residual block作为网络基本结构,通过大量地堆叠这些基本模块,构成了MobileNetV2的网络结构。最后,在FLOPs只有MobileNetV1的一半的情况下取得了更高的分类精度。 |
| MobileNetV2_x0_25 |
53.2 |
4.50856 |
9.40991 |
5.5 M |
| MobileNetV2_x1_0 |
72.2 |
6.12159 |
16.0442 |
12.6 M |
| MobileNetV2_x1_5 |
74.1 |
6.28385 |
22.5129 |
25.0 M |
| MobileNetV2_x2_0 |
75.2 |
6.12888 |
30.8612 |
41.2 M |
| MobileNetV3_large_x0_5 |
69.2 |
6.31302 |
14.5588 |
9.6 M |
MobileNetV3是Google于2019年提出的一种基于NAS的轻量级网络。为了进一步提升效果,将relu和sigmoid激活函数分别替换为hard_swish与hard_sigmoid激活函数,同时引入了一些专门为减少网络计算量的改进策略。 |
| MobileNetV3_large_x0_35 |
64.3 |
5.76207 |
13.9041 |
7.5 M |
| MobileNetV3_large_x0_75 |
73.1 |
8.41737 |
16.9506 |
14.0 M |
| MobileNetV3_large_x1_0 |
75.3 |
8.64112 |
19.1614 |
19.5 M |
| MobileNetV3_large_x1_25 |
76.4 |
8.73358 |
22.1296 |
26.5 M |
| MobileNetV3_small_x0_5 |
59.2 |
5.16721 |
11.2688 |
6.8 M |
| MobileNetV3_small_x0_35 |
53.0 |
5.22053 |
11.0055 |
6.0 M |
| MobileNetV3_small_x0_75 |
66.0 |
5.39831 |
12.8313 |
8.5 M |
| MobileNetV3_small_x1_0 |
68.2 |
6.00993 |
12.9598 |
10.5 M |
| MobileNetV3_small_x1_25 |
70.7 |
6.9589 |
14.3995 |
13.0 M |
| MobileNetV4_conv_large |
83.4 |
12.5485 |
51.6453 |
125.2 M |
MobileNetV4是专为移动设备设计的高效架构。其核心在于引入了UIB(Universal Inverted Bottleneck)模块,这是一种统一且灵活的结构,融合了IB(Inverted Bottleneck)、ConvNeXt、FFN(Feed Forward Network)以及最新的ExtraDW(Extra Depthwise)模块。与UIB同时推出的还有Mobile MQA,这是种专为移动加速器定制的注意力块,可实现高达39%的显著加速。此外,MobileNetV4引入了一种新的神经架构搜索(Neural Architecture Search, NAS)方案,以提升搜索的有效性。 |
| MobileNetV4_conv_medium |
79.9 |
9.65509 |
26.6157 |
37.6 M |
| MobileNetV4_conv_small |
74.6 |
5.24172 |
11.0893 |
14.7 M |
| MobileNetV4_hybrid_large |
83.8 |
20.0726 |
213.769 |
145.1 M |
| MobileNetV4_hybrid_medium |
80.5 |
19.7543 |
62.2624 |
42.9 M |
| PP-HGNet_base |
85.0 |
14.2969 |
327.114 |
249.4 M |
PP-HGNet(High Performance GPU Net)是百度飞桨视觉团队研发的适用于GPU平台的高性能骨干网络。该网络结合VOVNet的基础出使用了可学习的下采样层(LDS Layer),融合了ResNet_vd、PPHGNet等模型的优点。该模型在GPU平台上与其他SOTA模型在相同的速度下有着更高的精度。在同等速度下,该模型高于ResNet34-0模型3.8个百分点,高于ResNet50-0模型2.4个百分点,在使用相同的SLSD条款下,最终超越了ResNet50-D模型4.7个百分点。与此同时,在相同精度下,其推理速度也远超主流VisionTransformer的推理速度。 |
| PP-HGNet_small |
81.51 |
5.50661 |
119.041 |
86.5 M |
| PP-HGNet_tiny |
79.83 |
5.22006 |
69.396 |
52.4 M |
| PP-HGNetV2-B0 |
77.77 |
6.53694 |
23.352 |
21.4 M |
PP-HGNetV2(High Performance GPU Network V2)是百度飞桨视觉团队的PP-HGNet的下一代版本,其在PP-HGNet的基础上,做了进一步优化和改进,其在NVIDIA发布的“Accuracy-Latency Balance”做到了极致,精度大幅超越了其他同样推理速度的模型。在每种标签分类,考标场景中,都有较强的表现。 |
| PP-HGNetV2-B1 |
79.18 |
6.56034 |
27.3099 |
22.6 M |
| PP-HGNetV2-B2 |
81.74 |
9.60494 |
43.1219 |
39.9 M |
| PP-HGNetV2-B3 |
82.98 |
11.0042 |
55.1367 |
57.9 M |
| PP-HGNetV2-B4 |
83.57 |
9.66407 |
54.2462 |
70.4 M |
| PP-HGNetV2-B5 |
84.75 |
15.7091 |
115.926 |
140.8 M |
| PP-HGNetV2-B6 |
86.30 |
21.226 |
255.279 |
268.4 M |
| PP-LCNet_x0_5 |
63.14 |
3.67722 |
6.66857 |
6.7 M |
PP-LCNet是百度飞桨视觉团队自研的轻量级骨干网络,它能在不增加推理时间的前提下,进一步提升模型的性能,大幅超越其他轻量级SOTA模型。 |
| PP-LCNet_x0_25 |
51.86 |
2.65341 |
5.81357 |
5.5 M |
| PP-LCNet_x0_35 |
58.09 |
2.7212 |
6.28944 |
5.9 M |
| PP-LCNet_x0_75 |
68.18 |
3.91032 |
8.06953 |
8.4 M |
| PP-LCNet_x1_0 |
71.32 |
3.84845 |
9.23735 |
10.5 M |
| PP-LCNet_x1_5 |
73.71 |
3.97666 |
12.3457 |
16.0 M |
| PP-LCNet_x2_0 |
75.18 |
4.07556 |
16.2752 |
23.2 M |
| PP-LCNet_x2_5 |
76.60 |
4.06028 |
21.5063 |
32.1 M |
| PP-LCNetV2_base |
77.05 |
5.23428 |
19.6005 |
23.7 M |
PP-LCNetV2 图像分类模型是百度飞桨视觉团队自研的 PP-LCNet 的下一代版本,其在 PP-LCNet 的基础上,做了进一步优化和改进,主要使用重参数化策略组合了不同大小卷积核的深度卷积,并优化了点卷积、Shortcut等。在不使用额外数据的前提下,PPLCNetV2_base 模型在图像分类 ImageNet 数据集上能够取得超过 77% 的 Top1 Acc,同时在 Intel CPU 平台的推理时间在 4.4 ms 以下 |
| PP-LCNetV2_large |
78.51 |
6.78335 |
30.4378 |
37.3 M |
| PP-LCNetV2_small |
73.97 |
3.89762 |
13.0273 |
14.6 M |
| ResNet18_vd |
72.3 |
3.53048 |
31.3014 |
41.5 M |
ResNet 系列模型是在 2015 年提出的,一举在 ILSVRC2015 比赛中取得冠军,top5 错误率为 3.57%。该网络创新性的提出了残差结构,通过堆叠多个残差结构从而构建了 ResNet 网络。实验表明使用残差块可以有效地提升收敛速度和精度。 |
| ResNet18 |
71.0 |
2.4868 |
27.4601 |
41.5 M |
| ResNet34_vd |
76.0 |
5.60675 |
56.0653 |
77.3 M |
| ResNet34 |
74.6 |
4.16902 |
51.925 |
77.3 M |
| ResNet50_vd |
79.1 |
10.1885 |
68.446 |
90.8 M |
| ResNet50 |
76.5 |
9.62383 |
64.8135 |
90.8 M |
| ResNet101_vd |
80.2 |
20.0563 |
124.85 |
158.4 M |
| ResNet101 |
77.6 |
19.2297 |
121.006 |
158.4 M |
| ResNet152_vd |
80.6 |
29.6439 |
181.678 |
214.3 M |
| ResNet152 |
78.3 |
30.0461 |
177.707 |
214.2 M |
| ResNet200_vd |
80.9 |
39.1628 |
235.185 |
266.0 M |
| StarNet-S1 |
73.6 |
9.895 |
23.0465 |
11.2 M |
StarNet 聚焦于研究网络设计中“星操作”(即元素级乘法)的未开发潜力。揭示星操作能够将输入映射到高维、非线性特征空间的能力,这一过程类似于核技巧,但无需扩大网络规模。因此进一步提出了 StarNet,一个简单而强大的原型网络,该网络在紧凑的网络结构和有限的计算资源下,展现出了卓越的性能和低延迟。 |
| StarNet-S2 |
74.8 |
7.91279 |
21.9571 |
14.3 M |
| StarNet-S3 |
77.0 |
10.7531 |
30.7656 |
22.2 M |
| StarNet-S4 |
79.0 |
15.2868 |
43.2497 |
28.9 M |
| SwinTransformer_base_patch4_window7_224 |
83.37 |
16.9848 |
383.83 |
310.5 M |
SwinTransformer 是一种新的视觉 Transformer 网络,可以用作计算机视觉领域的通用骨干网路。SwinTransformer 由移动窗口(shifted windows)表示的层次 Transformer 结构组成。移动窗口将自注意计算限制在非重叠的局部窗口上,同时允许跨窗口连接,从而提高了网络性能。 |
| SwinTransformer_base_patch4_window12_384 |
84.17 |
37.2855 |
1178.63 |
311.4 M |
| SwinTransformer_large_patch4_window7_224 |
86.19 |
27.5498 |
689.729 |
694.8 M |
| SwinTransformer_large_patch4_window12_384 |
87.06 |
74.1768 |
2105.22 |
696.1 M |
| SwinTransformer_small_patch4_window7_224 |
83.21 |
16.3982 |
285.56 |
175.6 M |
| SwinTransformer_tiny_patch4_window7_224 |
81.10 |
8.54846 |
156.306 |
100.1 M |
注:以上精度指标为 ImageNet-1k 验证集 Top1 Acc。所有模型 GPU 推理耗时基于 NVIDIA Tesla T4 机器,精度类型为 FP32, CPU 推理速度基于 Intel(R) Xeon(R) Gold 5117 CPU @ 2.00GHz,线程数为8,精度类型为 FP32。
## 2. 快速开始
PaddleX 所提供的预训练的模型产线均可以快速体验效果,你可以在线体验通用图像分类产线的效果,也可以在本地使用命令行或 Python 体验通用图像分类产线的效果。
### 2.1 在线体验
您可以[在线体验](https://aistudio.baidu.com/community/app/100061/webUI)通用图像分类产线的效果,用官方提供的 demo 图片进行识别,例如:
如果您对产线运行的效果满意,可以直接对产线进行集成部署,如果不满意,您也可以利用私有数据对产线中的模型进行在线微调。
### 2.2 本地体验
在本地使用通用图像分类产线前,请确保您已经按照[PaddleX本地安装教程](../../../installation/installation.md)完成了PaddleX的wheel包安装。
#### 2.2.1 命令行方式体验
一行命令即可快速体验图像分类产线效果,使用 [测试文件](https://paddle-model-ecology.bj.bcebos.com/paddlex/imgs/demo_image/general_image_classification_001.jpg),并将 `--input` 替换为本地路径,进行预测
```bash
paddlex --pipeline image_classification --input general_image_classification_001.jpg --device gpu:0
```
参数说明:
```
--pipeline:产线名称,此处为图像分类产线
--input:待处理的输入图片的本地路径或URL
--device 使用的GPU序号(例如gpu:0表示使用第0块GPU,gpu:1,2表示使用第1、2块GPU),也可选择使用CPU(--device cpu)
```
在执行上述 Python 脚本时,加载的是默认的图像分类产线配置文件,若您需要自定义配置文件,可执行如下命令获取:
👉点击展开
paddlex --get_pipeline_config image_classification
执行后,图像分类产线配置文件将被保存在当前路径。若您希望自定义保存位置,可执行如下命令(假设自定义保存位置为 ./my_path ):
paddlex --get_pipeline_config image_classification --save_path ./my_path
获取产线配置文件后,可将 --pipeline 替换为配置文件保存路径,即可使配置文件生效。例如,若配置文件保存路径为 ./image_classification.yaml,只需执行:
paddlex --pipeline ./image_classification.yaml --input general_image_classification_001.jpg --device gpu:0
其中,--model、--device 等参数无需指定,将使用配置文件中的参数。若依然指定了参数,将以指定的参数为准。
运行后,得到的结果为:
```
{'input_path': 'general_image_classification_001.jpg', 'class_ids': [296, 170, 356, 258, 248], 'scores': [0.62736, 0.03752, 0.03256, 0.0323, 0.03194], 'label_names': ['ice bear, polar bear, Ursus Maritimus, Thalarctos maritimus', 'Irish wolfhound', 'weasel', 'Samoyed, Samoyede', 'Eskimo dog, husky']}
```
可视化图片默认不进行保存,您可以通过 `--save_path` 自定义保存路径,随后所有结果将被保存在指定路径下。
#### 2.2.2 Python脚本方式集成
几行代码即可完成产线的快速推理,以通用图像分类产线为例:
```
from paddlex import create_pipeline
pipeline = create_pipeline(pipeline="image_classification")
output = pipeline.predict("general_image_classification_001.jpg")
for res in output:
res.print() ## 打印预测的结构化输出
res.save_to_img("./output/") ## 保存结果可视化图像
res.save_to_json("./output/") ## 保存预测的结构化输出
```
得到的结果与命令行方式相同。
在上述 Python 脚本中,执行了如下几个步骤:
(1)实例化 `create_pipeline` 实例化产线对象:具体参数说明如下:
API参考
对于服务提供的所有操作:
- 响应体以及POST请求的请求体均为JSON数据(JSON对象)。
- 当请求处理成功时,响应状态码为
200,响应体的属性如下:
| 名称 |
类型 |
含义 |
errorCode |
integer |
错误码。固定为0。 |
errorMsg |
string |
错误说明。固定为"Success"。 |
响应体还可能有result属性,类型为object,其中存储操作结果信息。
| 名称 |
类型 |
含义 |
errorCode |
integer |
错误码。与响应状态码相同。 |
errorMsg |
string |
错误说明。 |
服务提供的操作如下:
对图像进行分类。
POST /image-classification
| 名称 |
类型 |
含义 |
是否必填 |
image |
string |
服务可访问的图像文件的URL或图像文件内容的Base64编码结果。 |
是 |
inferenceParams |
object |
推理参数。 |
否 |
inferenceParams的属性如下:
| 名称 |
类型 |
含义 |
是否必填 |
topK |
integer |
结果中将只保留得分最高的topK个类别。 |
否 |
- 请求处理成功时,响应体的
result具有如下属性:
| 名称 |
类型 |
含义 |
categories |
array |
图像类别信息。 |
image |
string |
图像分类结果图。图像为JPEG格式,使用Base64编码。 |
categories中的每个元素为一个object,具有如下属性:
| 名称 |
类型 |
含义 |
id |
integer |
类别ID。 |
name |
string |
类别名称。 |
score |
number |
类别得分。 |
result示例如下:
{
"categories": [
{
"id": 5,
"name": "兔子",
"score": 0.93
}
],
"image": "xxxxxx"
}
多语言调用服务示例
Python
import base64
import requests
API_URL = "http://localhost:8080/image-classification" # 服务URL
image_path = "./demo.jpg"
output_image_path = "./out.jpg"
# 对本地图像进行Base64编码
with open(image_path, "rb") as file:
image_bytes = file.read()
image_data = base64.b64encode(image_bytes).decode("ascii")
payload = {"image": image_data} # Base64编码的文件内容或者图像URL
# 调用API
response = requests.post(API_URL, json=payload)
# 处理接口返回数据
assert response.status_code == 200
result = response.json()["result"]
with open(output_image_path, "wb") as file:
file.write(base64.b64decode(result["image"]))
print(f"Output image saved at {output_image_path}")
print("\nCategories:")
print(result["categories"])
C++
#include <iostream>
#include "cpp-httplib/httplib.h" // https://github.com/Huiyicc/cpp-httplib
#include "nlohmann/json.hpp" // https://github.com/nlohmann/json
#include "base64.hpp" // https://github.com/tobiaslocker/base64
int main() {
httplib::Client client("localhost:8080");
const std::string imagePath = "./demo.jpg";
const std::string outputImagePath = "./out.jpg";
httplib::Headers headers = {
{"Content-Type", "application/json"}
};
// 对本地图像进行Base64编码
std::ifstream file(imagePath, std::ios::binary | std::ios::ate);
std::streamsize size = file.tellg();
file.seekg(0, std::ios::beg);
std::vector<char> buffer(size);
if (!file.read(buffer.data(), size)) {
std::cerr << "Error reading file." << std::endl;
return 1;
}
std::string bufferStr(reinterpret_cast<const char*>(buffer.data()), buffer.size());
std::string encodedImage = base64::to_base64(bufferStr);
nlohmann::json jsonObj;
jsonObj["image"] = encodedImage;
std::string body = jsonObj.dump();
// 调用API
auto response = client.Post("/image-classification", headers, body, "application/json");
// 处理接口返回数据
if (response && response->status == 200) {
nlohmann::json jsonResponse = nlohmann::json::parse(response->body);
auto result = jsonResponse["result"];
encodedImage = result["image"];
std::string decodedString = base64::from_base64(encodedImage);
std::vector<unsigned char> decodedImage(decodedString.begin(), decodedString.end());
std::ofstream outputImage(outPutImagePath, std::ios::binary | std::ios::out);
if (outputImage.is_open()) {
outputImage.write(reinterpret_cast<char*>(decodedImage.data()), decodedImage.size());
outputImage.close();
std::cout << "Output image saved at " << outPutImagePath << std::endl;
} else {
std::cerr << "Unable to open file for writing: " << outPutImagePath << std::endl;
}
auto categories = result["categories"];
std::cout << "\nCategories:" << std::endl;
for (const auto& category : categories) {
std::cout << category << std::endl;
}
} else {
std::cout << "Failed to send HTTP request." << std::endl;
return 1;
}
return 0;
}
Java
import okhttp3.*;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Base64;
public class Main {
public static void main(String[] args) throws IOException {
String API_URL = "http://localhost:8080/image-classification"; // 服务URL
String imagePath = "./demo.jpg"; // 本地图像
String outputImagePath = "./out.jpg"; // 输出图像
// 对本地图像进行Base64编码
File file = new File(imagePath);
byte[] fileContent = java.nio.file.Files.readAllBytes(file.toPath());
String imageData = Base64.getEncoder().encodeToString(fileContent);
ObjectMapper objectMapper = new ObjectMapper();
ObjectNode params = objectMapper.createObjectNode();
params.put("image", imageData); // Base64编码的文件内容或者图像URL
// 创建 OkHttpClient 实例
OkHttpClient client = new OkHttpClient();
MediaType JSON = MediaType.Companion.get("application/json; charset=utf-8");
RequestBody body = RequestBody.Companion.create(params.toString(), JSON);
Request request = new Request.Builder()
.url(API_URL)
.post(body)
.build();
// 调用API并处理接口返回数据
try (Response response = client.newCall(request).execute()) {
if (response.isSuccessful()) {
String responseBody = response.body().string();
JsonNode resultNode = objectMapper.readTree(responseBody);
JsonNode result = resultNode.get("result");
String base64Image = result.get("image").asText();
JsonNode categories = result.get("categories");
byte[] imageBytes = Base64.getDecoder().decode(base64Image);
try (FileOutputStream fos = new FileOutputStream(outputImagePath)) {
fos.write(imageBytes);
}
System.out.println("Output image saved at " + outputImagePath);
System.out.println("\nCategories: " + categories.toString());
} else {
System.err.println("Request failed with code: " + response.code());
}
}
}
}
Go
package main
import (
"bytes"
"encoding/base64"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
func main() {
API_URL := "http://localhost:8080/image-classification"
imagePath := "./demo.jpg"
outputImagePath := "./out.jpg"
// 对本地图像进行Base64编码
imageBytes, err := ioutil.ReadFile(imagePath)
if err != nil {
fmt.Println("Error reading image file:", err)
return
}
imageData := base64.StdEncoding.EncodeToString(imageBytes)
payload := map[string]string{"image": imageData} // Base64编码的文件内容或者图像URL
payloadBytes, err := json.Marshal(payload)
if err != nil {
fmt.Println("Error marshaling payload:", err)
return
}
// 调用API
client := &http.Client{}
req, err := http.NewRequest("POST", API_URL, bytes.NewBuffer(payloadBytes))
if err != nil {
fmt.Println("Error creating request:", err)
return
}
res, err := client.Do(req)
if err != nil {
fmt.Println("Error sending request:", err)
return
}
defer res.Body.Close()
// 处理接口返回数据
body, err := ioutil.ReadAll(res.Body)
if err != nil {
fmt.Println("Error reading response body:", err)
return
}
type Response struct {
Result struct {
Image string `json:"image"`
Categories []map[string]interface{} `json:"categories"`
} `json:"result"`
}
var respData Response
err = json.Unmarshal([]byte(string(body)), &respData)
if err != nil {
fmt.Println("Error unmarshaling response body:", err)
return
}
outputImageData, err := base64.StdEncoding.DecodeString(respData.Result.Image)
if err != nil {
fmt.Println("Error decoding base64 image data:", err)
return
}
err = ioutil.WriteFile(outputImagePath, outputImageData, 0644)
if err != nil {
fmt.Println("Error writing image to file:", err)
return
}
fmt.Printf("Image saved at %s.jpg\n", outputImagePath)
fmt.Println("\nCategories:")
for _, category := range respData.Result.Categories {
fmt.Println(category)
}
}
C#
using System;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
class Program
{
static readonly string API_URL = "http://localhost:8080/image-classification";
static readonly string imagePath = "./demo.jpg";
static readonly string outputImagePath = "./out.jpg";
static async Task Main(string[] args)
{
var httpClient = new HttpClient();
// 对本地图像进行Base64编码
byte[] imageBytes = File.ReadAllBytes(imagePath);
string image_data = Convert.ToBase64String(imageBytes);
var payload = new JObject{ { "image", image_data } }; // Base64编码的文件内容或者图像URL
var content = new StringContent(payload.ToString(), Encoding.UTF8, "application/json");
// 调用API
HttpResponseMessage response = await httpClient.PostAsync(API_URL, content);
response.EnsureSuccessStatusCode();
// 处理接口返回数据
string responseBody = await response.Content.ReadAsStringAsync();
JObject jsonResponse = JObject.Parse(responseBody);
string base64Image = jsonResponse["result"]["image"].ToString();
byte[] outputImageBytes = Convert.FromBase64String(base64Image);
File.WriteAllBytes(outputImagePath, outputImageBytes);
Console.WriteLine($"Output image saved at {outputImagePath}");
Console.WriteLine("\nCategories:");
Console.WriteLine(jsonResponse["result"]["categories"].ToString());
}
}
Node.js
const axios = require('axios');
const fs = require('fs');
const API_URL = 'http://localhost:8080/image-classification'
const imagePath = './demo.jpg'
const outputImagePath = "./out.jpg";
let config = {
method: 'POST',
maxBodyLength: Infinity,
url: API_URL,
data: JSON.stringify({
'image': encodeImageToBase64(imagePath) // Base64编码的文件内容或者图像URL
})
};
// 对本地图像进行Base64编码
function encodeImageToBase64(filePath) {
const bitmap = fs.readFileSync(filePath);
return Buffer.from(bitmap).toString('base64');
}
// 调用API
axios.request(config)
.then((response) => {
// 处理接口返回数据
const result = response.data["result"];
const imageBuffer = Buffer.from(result["image"], 'base64');
fs.writeFile(outputImagePath, imageBuffer, (err) => {
if (err) throw err;
console.log(`Output image saved at ${outputImagePath}`);
});
console.log("\nCategories:");
console.log(result["categories"]);
})
.catch((error) => {
console.log(error);
});
PHP
<?php
$API_URL = "http://localhost:8080/image-classification"; // 服务URL
$image_path = "./demo.jpg";
$output_image_path = "./out.jpg";
// 对本地图像进行Base64编码
$image_data = base64_encode(file_get_contents($image_path));
$payload = array("image" => $image_data); // Base64编码的文件内容或者图像URL
// 调用API
$ch = curl_init($API_URL);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
// 处理接口返回数据
$result = json_decode($response, true)["result"];
file_put_contents($output_image_path, base64_decode($result["image"]));
echo "Output image saved at " . $output_image_path . "\n";
echo "\nCategories:\n";
print_r($result["categories"]);
?>