---
comments: true
---
# 通用语义分割产线使用教程
## 1. 通用语义分割产线介绍
语义分割是一种计算机视觉技术,旨在将图像中的每个像素分配到特定的类别,从而实现对图像内容的精细化理解。语义分割不仅要识别出图像中的物体类型,还要对每个像素进行分类,这样使得同一类别的区域能够被完整标记。例如,在一幅街景图像中,语义分割可以将行人、汽车、天空和道路等不同类别的部分逐像素区分开来,形成一个详细的标签图。通用语义分割产线用于解决像素级别的图像理解问题,这项技术广泛应用于自动驾驶、医学影像分析和人机交互等领域,通常依赖于深度学习模型(如SegFormer等),通过卷积神经网络(CNN)或视觉变换器(Transformer)来提取特征并实现高精度的像素级分类,从而为进一步的智能分析提供基础。本产线同时提供了灵活的服务化部署方式,支持在多种硬件上使用多种编程语言调用。不仅如此,本产线也提供了二次开发的能力,您可以基于本产线在您自己的数据集上训练调优,训练后的模型也可以无缝集成。
通用语义分割产线中包含了语义分割模块,该模块都包含多个模型,您可以根据下方的基准测试数据选择使用的模型。
如果您更注重模型的精度,请选择精度较高的模型;如果您更在意模型的推理速度,请选择推理速度较快的模型;如果您关注模型的存储大小,请选择存储体积较小的模型。
> 推理耗时仅包含模型推理耗时,不包含前后处理耗时。
通用图像语义分割模块(可选):
| 模型名称 | 模型下载链接 | mloU(%) | GPU推理耗时(ms) [常规模式 / 高性能模式] |
CPU推理耗时(ms) [常规模式 / 高性能模式] |
模型存储大小(MB) |
|---|---|---|---|---|---|
| OCRNet_HRNet-W48 | 推理模型/训练模型 | 82.15 | 582.92 / 536.28 | 3513.72 / 2543.10 | 270 |
| PP-LiteSeg-T | 推理模型/训练模型 | 73.10 | 28.12 / 23.84 | 398.31 / 398.31 | 28.5 |
注:以上模型精度指标测量自Cityscapes数据集。GPU 推理耗时基于 NVIDIA Tesla T4 机器,精度类型为 FP32, CPU 推理速度基于 Intel(R) Xeon(R) Gold 5117 CPU @ 2.00GHz,线程数为 8,精度类型为 FP32。
>❗ 以上列出的是语义分割模块重点支持的2个核心模型,该模块总共支持18个模型,完整的模型列表如下:| 模型名称 | 模型下载链接 | mloU(%) | GPU推理耗时(ms) [常规模式 / 高性能模式] |
CPU推理耗时(ms) [常规模式 / 高性能模式] |
模型存储大小(MB) |
|---|---|---|---|---|---|
| Deeplabv3_Plus-R50 | 推理模型/训练模型 | 80.36 | 481.33 / 446.18 | 2952.95 / 1907.07 | 94.9 |
| Deeplabv3_Plus-R101 | 推理模型/训练模型 | 81.10 | 766.70 / 194.42 | 4441.56 / 2984.19 | 162.5 |
| Deeplabv3-R50 | 推理模型/训练模型 | 79.90 | 681.65 / 602.10 | 3786.41 / 3093.10 | 138.3 |
| Deeplabv3-R101 | 推理模型/训练模型 | 80.85 | 974.62 / 896.99 | 5222.60 / 4230.79 | 205.9 |
| OCRNet_HRNet-W18 | 推理模型/训练模型 | 80.67 | 271.02 / 221.38 | 1791.52 / 1061.62 | 43.1 |
| OCRNet_HRNet-W48 | 推理模型/训练模型 | 82.15 | 582.92 / 536.28 | 3513.72 / 2543.10 | 270 |
| PP-LiteSeg-T | 推理模型/训练模型 | 73.10 | 28.12 / 23.84 | 398.31 / 398.31 | 28.5 |
| PP-LiteSeg-B | 推理模型/训练模型 | 75.25 | 35.69 / 35.69 | 485.10 / 485.10 | 47.0 |
| SegFormer-B0 (slice) | 推理模型/训练模型 | 76.73 | 11.1946 | 268.929 | 13.2 |
| SegFormer-B1 (slice) | 推理模型/训练模型 | 78.35 | 17.9998 | 403.393 | 48.5 |
| SegFormer-B2 (slice) | 推理模型/训练模型 | 81.60 | 48.0371 | 1248.52 | 96.9 |
| SegFormer-B3 (slice) | 推理模型/训练模型 | 82.47 | 64.341 | 1666.35 | 167.3 |
| SegFormer-B4 (slice) | 推理模型/训练模型 | 82.38 | 82.4336 | 1995.42 | 226.7 |
| SegFormer-B5 (slice) | 推理模型/训练模型 | 82.58 | 97.3717 | 2420.19 | 229.7 |
注:以上模型精度指标测量自Cityscapes数据集。GPU 推理耗时基于 NVIDIA Tesla T4 机器,精度类型为 FP32, CPU 推理速度基于 Intel(R) Xeon(R) Gold 5117 CPU @ 2.00GHz,线程数为 8,精度类型为 FP32。
| 模型名称 | 模型下载链接 | mloU(%) | GPU推理耗时(ms) [常规模式 / 高性能模式] |
CPU推理耗时 | 模型存储大小(MB) |
|---|---|---|---|---|---|
| SeaFormer_base(slice) | 推理模型/训练模型 | 40.92 | 24.4073 | 397.574 | 30.8 |
| SeaFormer_large (slice) | 推理模型/训练模型 | 43.66 | 27.8123 | 550.464 | 49.8 |
| SeaFormer_small (slice) | 推理模型/训练模型 | 38.73 | 19.2295 | 358.343 | 14.3 |
| SeaFormer_tiny (slice) | 推理模型/训练模型 | 34.58 | 13.9496 | 330.132 | 6.1 |
注:SeaFormer系列模型的精度指标测量自ADE20k数据集。GPU 推理耗时基于 NVIDIA Tesla T4 机器,精度类型为 FP32, CPU 推理速度基于 Intel(R) Xeon(R) Gold 5117 CPU @ 2.00GHz,线程数为 8,精度类型为 FP32。
测试环境说明:| 模式 | GPU配置 | CPU配置 | 加速技术组合 |
|---|---|---|---|
| 常规模式 | FP32精度 / 无TRT加速 | FP32精度 / 8线程 | PaddleInference |
| 高性能模式 | 选择先验精度类型和加速策略的最优组合 | FP32精度 / 8线程 | 选择先验最优后端(Paddle/OpenVINO/TRT等) |
如果您对产线运行的效果满意,可以直接进行集成部署。您可以选择从云端下载部署包,也可以参考[2.2节本地体验](#22-本地体验)中的方法进行本地部署。如果对效果不满意,您可以利用私有数据对产线中的模型进行微调训练。如果您具备本地训练的硬件资源,可以直接在本地开展训练;如果没有,星河零代码平台提供了一键式训练服务,无需编写代码,只需上传数据后,即可一键启动训练任务。
### 2.2 本地体验
>❗ 在本地使用通用语义分割产线前,请确保您已经按照[PaddleX本地安装教程](../../../installation/installation.md)完成了PaddleX的wheel包安装。如果您希望选择性安装依赖,请参考安装教程中的相关说明。该产线对应的依赖分组为 `cv`。
#### 2.2.1 命令行方式体验
* 一行命令即可快速体验语义分割产线效果,使用 [测试文件](https://paddle-model-ecology.bj.bcebos.com/paddlex/PaddleX3.0/application/semantic_segmentation/makassaridn-road_demo.png),并将 `--input` 替换为本地路径,进行预测
```bash
paddlex --pipeline semantic_segmentation \
--input makassaridn-road_demo.png \
--target_size -1 \
--save_path ./output \
--device gpu:0 \
```
相关的参数说明可以参考[2.2.2 Python脚本方式集成](#222-python脚本方式集成)中的参数说明。支持同时指定多个设备以进行并行推理,详情请参考 [产线并行推理](../../instructions/parallel_inference.md#指定多个推理设备)。
运行后,会将结果打印到终端上,结果如下:
```bash
{'res': {'input_path': 'makassaridn-road_demo.png', 'page_index': None, 'pred': '...'}}
```
运行结果参数说明可以参考[2.2.2 Python脚本方式集成](#222-python脚本方式集成)中的结果解释。
可视化结果保存在`save_path`下,其中语义分割的可视化结果如下:
#### 2.2.2 Python脚本方式集成
* 上述命令行是为了快速体验查看效果,一般来说,在项目中,往往需要通过代码集成,您可以通过几行代码即可完成产线的快速推理,推理代码如下:
```python
from paddlex import create_pipeline
pipeline = create_pipeline(pipeline="semantic_segmentation")
output = pipeline.predict(input="makassaridn-road_demo.png", target_size = -1)
for res in output:
res.print()
res.save_to_img(save_path="./output/")
res.save_to_json(save_path="./output/")
```
在上述 Python 脚本中,执行了如下几个步骤:
(1)通过 `create_pipeline()` 实例化 语义分割 产线对象,具体参数说明如下:
| 参数 | 参数说明 | 参数类型 | 默认值 | |
|---|---|---|---|---|
pipeline |
产线名称或是产线配置文件路径。如为产线名称,则必须为 PaddleX 所支持的产线。 | str |
None |
|
config |
产线具体的配置信息(如果和pipeline同时设置,优先级高于pipeline,且要求产线名和pipeline一致)。 |
dict[str, Any] |
None |
|
device |
产线推理设备。支持指定GPU具体卡号,如“gpu:0”,其他硬件具体卡号,如“npu:0”,CPU如“cpu”。支持同时指定多个设备以进行并行推理,详情请参考产线并行推理文档。 | str |
None |
|
use_hpip |
是否启用高性能推理插件。如果为 None,则使用配置文件或 config 中的配置。 |
bool | None |
无 | None |
hpi_config |
高性能推理配置 | dict | None |
无 | None |
| 参数 | 参数说明 | 参数类型 | 可选项 | 默认值 |
|---|---|---|---|---|
input |
待预测数据,支持多种输入类型,必填 | Python Var|str|list |
|
None |
target_size |
模型推理时实际使用的图像分辨率 | int|-1|None|tuple[int,int] |
|
None |
| 方法 | 方法说明 | 参数 | 参数类型 | 参数说明 | 默认值 |
|---|---|---|---|---|---|
print() |
打印结果到终端 | format_json |
bool |
是否对输出内容进行使用 JSON 缩进格式化 |
True |
indent |
int |
指定缩进级别,以美化输出的 JSON 数据,使其更具可读性,仅当 format_json 为 True 时有效 |
4 | ||
ensure_ascii |
bool |
控制是否将非 ASCII 字符转义为 Unicode。设置为 True 时,所有非 ASCII 字符将被转义;False 则保留原始字符,仅当format_json为True时有效 |
False |
||
save_to_json() |
将结果保存为json格式的文件 | save_path |
str |
保存的文件路径,当为目录时,保存文件命名与输入文件类型命名一致 | 无 |
indent |
int |
指定缩进级别,以美化输出的 JSON 数据,使其更具可读性,仅当 format_json 为 True 时有效 |
4 | ||
ensure_ascii |
bool |
控制是否将非 ASCII 字符转义为 Unicode。设置为 True 时,所有非 ASCII 字符将被转义;False 则保留原始字符,仅当format_json为True时有效 |
False |
||
save_to_img() |
将结果保存为图像格式的文件 | save_path |
str |
保存的文件路径,支持目录或文件路径 | 无 |
| 属性 | 属性说明 |
|---|---|
json |
获取预测的 json 格式的结果 |
img |
获取格式为 dict 的可视化图像 |
对于服务提供的主要操作:
200,响应体的属性如下:| 名称 | 类型 | 含义 |
|---|---|---|
logId |
string |
请求的UUID。 |
errorCode |
integer |
错误码。固定为0。 |
errorMsg |
string |
错误说明。固定为"Success"。 |
result |
object |
操作结果。 |
| 名称 | 类型 | 含义 |
|---|---|---|
logId |
string |
请求的UUID。 |
errorCode |
integer |
错误码。与响应状态码相同。 |
errorMsg |
string |
错误说明。 |
服务提供的主要操作如下:
infer对图像进行语义分割。
POST /semantic-segmentation
| 名称 | 类型 | 含义 | 是否必填 |
|---|---|---|---|
image |
string |
服务器可访问的图像文件的URL或图像文件内容的Base64编码结果。 | 是 |
targetSize |
integer | array | null |
请参阅产线对象中 predict 方法的 target_size 参数相关说明。 |
否 |
visualize |
boolean | null |
是否返回可视化结果图以及处理过程中的中间图像等。
例如,在产线配置文件中添加如下字段:
将默认不返回图像,通过请求体中的visualize参数可以覆盖默认行为。如果请求体和配置文件中均未设置(或请求体传入null、配置文件中未设置),则默认返回图像。
|
否 |
result具有如下属性:| 名称 | 类型 | 含义 |
|---|---|---|
labelMap |
array |
记录图像中每个像素的类别标签(按照行优先顺序排列)。 |
size |
array |
图像形状。数组中元素依次为图像的高度和宽度。 |
image |
string | null |
语义分割结果图。图像为JPEG格式,使用Base64编码。 |
result示例如下:
{
"labelMap": [
0,
0,
1,
2
],
"size": [
2,
2
],
"image": "xxxxxx"
}
import base64
import requests
API_URL = "http://localhost:8080/semantic-segmentation" # 服务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}")
# result.labelMap 记录图像中每个像素的类别标签(按照行优先顺序排列)详见API参考文档
#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("/semantic-segmentation", 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;
// result.labelMap 记录图像中每个像素的类别标签(按照行优先顺序排列)详见API参考文档
} else {
std::cerr << "Unable to open file for writing: " << outPutImagePath << std::endl;
}
} else {
std::cout << "Failed to send HTTP request." << std::endl;
return 1;
}
return 0;
}
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/semantic-segmentation"; // 服务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 labelMap = result.get("labelMap");
byte[] imageBytes = Base64.getDecoder().decode(base64Image);
try (FileOutputStream fos = new FileOutputStream(outputImagePath)) {
fos.write(imageBytes);
}
System.out.println("Output image saved at " + outputImagePath);
// result.labelMap 记录图像中每个像素的类别标签(按照行优先顺序排列)详见API参考文档
} else {
System.err.println("Request failed with code: " + response.code());
}
}
}
}
package main
import (
"bytes"
"encoding/base64"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
func main() {
API_URL := "http://localhost:8080/semantic-segmentation"
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"`
Labelmap []map[string]interface{} `json:"labelMap"`
} `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)
// result.labelMap 记录图像中每个像素的类别标签(按照行优先顺序排列)详见API参考文档
}
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/semantic-segmentation";
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}");
// result.labelMap 记录图像中每个像素的类别标签(按照行优先顺序排列)详见API参考文档
}
}
const axios = require('axios');
const fs = require('fs');
const API_URL = 'http://localhost:8080/semantic-segmentation'
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}`);
});
// result.labelMap 记录图像中每个像素的类别标签(按照行优先顺序排列)详见API参考文档
})
.catch((error) => {
console.log(error);
});
<?php
$API_URL = "http://localhost:8080/semantic-segmentation"; // 服务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_HTTPHEADER, array('Content-Type: application/json'));
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";
// result.labelMap 记录图像中每个像素的类别标签(按照行优先顺序排列)详见API参考文档
?>
| 情形 | 微调模块 | 微调参考链接 |
|---|---|---|
| 预测结果不达预期 | 语义分割模块 | 链接 |