Intelligent Background Removal
Description
This API performs saliency detection in the cloud and automatically identifies salient regions in an image. It supports saliency detection for portraits, products, and graphics, and can return either the processed result image or a mask image. Advanced capabilities such as edge-detail refinement are also supported.
Version
1.0
Image Requirements
- Image formatsJPG, PNG, HEIC
- Image dimensionsMinimum 224×224 pixels; maximum 3000×3000 pixels
- Image file sizeRecommended to be within 3 MB
API URL
Production environment: https://openapi.meitu.com
Task submission endpoint: https://openapi.meitu.com/api/v1/sdk/sync/push
Task name (task): /v1/photo_scissors/sod
Task type (task_type): mtlabMethod
POST
Content-Type: application/json
Authentication
Request Parameters
| Required | Parameter | Type | Description |
|---|---|---|---|
| Yes | params | string | Algorithm parameters (JSON string) |
| Yes | init_images | object[] | Media file list |
| Yes | task | string | Fixed value: /v1/photo_scissors/sod |
| Yes | task_type | string | Fixed value: mtlab |
| No | sync_timeout | int | Synchronization timeout; default: 30 |
The structure of each media file in init_images is described below.
| Required | Parameter | Type | Description |
|---|---|---|---|
| Yes | url | string | Media URL or base64-encoded data |
| Yes | profile | object | Media attributes |
profile attributes
| Required | Parameter | Type | Description |
|---|---|---|---|
| Yes | media_profiles | object | Media profile information |
| Yes | version | string | Fixed value: v1 |
media_profiles attributes
| Required | Parameter | Type | Description |
|---|---|---|---|
| Yes | media_data_type | string | Media data type: url indicates a URL; jpg indicates base64-encoded data |
The inference parameter params is a JSON string with the following structure.
| Required | Field | Type | Description |
|---|---|---|---|
| No | rsp_media_type | string | Default: url; jpg indicates base64-encoded data |
| Yes | parameter | object | Core algorithm parameters |
parameter details
| Required | Parameter | Type | Description |
|---|---|---|---|
| No | nMask | bool | Whether to return a mask image. True returns only the mask image; False returns the processed result image. |
| No | model_type | int | Background-removal model to use:0: Portrait background removal1: Product background removal2: Graphic background removalIf omitted, the model automatically determines which model to use. |
| No | userboxes | string | For graphic images, user interaction boxes can be provided. Coordinates must be relative and the four points must be supplied clockwise starting from the upper-left corner (upper-left, upper-right, lower-right, lower-left). Example: [[[0.01, 0.814], [0.12, 0.814], [0.12, 0.96], [0.01, 0.96]]] |
| No | blackwhite | bool | Whether to return a black-and-white image. True returns only a black-and-white mask image; False returns a four-channel mask image. Default: False. |
| No | nbox | bool | Whether to return the target position. True returns top_x, top_y, bottom_x, and bottom_y. Default: False. |
| No | post_matting | bool | Product images only. Whether to apply the edge post-processing algorithm. Default: False. When set to True, it produces more refined edge details but increases processing time by 0.2–1 second. |
| No | use_fe_rgba | bool | Whether to use foreground estimation. Default: False. Set this to True to use foreground estimation if the extracted image has white or black fringes around its edges. |
Request Example
{
"task": "/v1/photo_scissors/sod",
"task_type": "mtlab",
"init_images": [
{
"url": "https://example.com/image.jpg",
"profile": {
"media_profiles": {
"media_data_type": "url"
},
"version": "v1"
}
}
],
"params": "{\"rsp_media_type\":\"url\",\"parameter\":{\"nMask\":false,\"model_type\":0}}",
"sync_timeout": 30
}Response Fields
Note: Generated results are periodically deleted. Download and save them promptly.| Field | Type | Description |
|---|---|---|
| request_id | string | Request identifier |
| trace_id | string | Trace identifier |
| code | int | Business status code; 0 indicates that the request was accepted successfully |
| error_code | int | Error code; 0 on success |
| message | string | Business message |
| tips | any | Additional information; may be null |
| data | object | Task status and algorithm result |
Fields in data
| Field | Type | Description |
|---|---|---|
| status | int | Status code: -1, task not found; 0, created; 1, processing; 2, failed; 9, timed out—use the Query API; 10, succeeded |
| result | object | Algorithm result |
| progress | number | Task progress |
| predict_elapsed | int | Estimated processing time, in milliseconds |
| create_time | int64 | Creation timestamp, in milliseconds |
| task_id | string | Task ID |
| custom_task_id | string | Custom task ID supplied by the client |
| trace_id | string | Trace identifier |
| client_info | string | Client information |
| init_images | object[]/null | Echoed input media |
Fields in result
| Field | Type | Description |
|---|---|---|
| parameter | object | Algorithm parameter information |
| media_info_list | array | Media file list |
| msg | string | Status message |
| msg_id | string | Message ID |
| code | int | Algorithm status code |
| error_code | int | Error code |
| error_msg | string | Error message |
| data | object | Algorithm response data |
Response Examples
Successful Response
Response Status: 200
Content-Type: application/json; charset=utf-8
{
"request_id": "req_123456789",
"trace_id": "trace_987654321",
"code": 0,
"error_code": 0,
"message": "success",
"tips": null,
"data": {
"status": 10,
"result": {
"parameter": {
"version": "1.0",
"exist_salient": true,
"Kind": 0
},
"media_info_list": [
{
"media_data": "https://example.com/result.jpg",
"media_profiles": {
"media_data_type": "url"
}
}
],
"msg": "success",
"msg_id": "msg_123456",
"code": 0,
"error_code": 0,
"error_msg": ""
},
"progress": 100,
"predict_elapsed": 5000,
"create_time": 1640995200000,
"task_id": "task_1234567890",
"custom_task_id": "",
"trace_id": "trace_987654321",
"client_info": "",
"init_images": null
}
}Response Requiring a Query
Use the Query API to retrieve the result.
Response Status: 200
Content-Type: application/json; charset=utf-8
{
"request_id": "",
"trace_id": "",
"code": 0,
"error_code": 0,
"message": "success",
"tips": null,
"data": {
"status": 9,
"result": {
"id": "t_mt1a3i5n7b3da6d589-46b5-4f66-a0bb-8dd22f2a172e"
},
"progress": 0,
"predict_elapsed": 10000,
"create_time": 1759202368761,
"task_id": "t_mt1a3i5n7b3da6d589-46b5-4f66-a0bb-8dd22f2a172e",
"custom_task_id": "",
"trace_id": "9129a3a2-99c4-46ce-8731-0e100e2fbee7",
"client_info": "",
"init_images": null
}
}Failed Response
Response Status: 400
Content-Type: application/json; charset=utf-8
{
"request_id": "req_error_123456",
"trace_id": "trace_error_789012",
"code": 20003,
"error_code": 20003,
"message": "ALGO_ERROR",
"tips": null,
"data": {
"status": 2,
"result": {
"id": "t_mt1a3i5n7be8d575cc-2ffb-4e0c-85a8-1824110e31b8",
"code": 20003,
"data": {
"duration": {
"alg_process_time": 0,
"created_timestamp": 1759201989,
"pull_timestamp": 1759201989,
"repost_time": 0,
"upload_time": 0,
"waiting_time": 0
},
"error_code": 20003,
"error_msg": "DETECT_NOT_FACE",
"extra": {},
"media_info_list": [],
"msg_id": "c1b09cb2-6e05-4d21-55ab-r007b1f21bec",
"parameter": null
},
"msg": "DETECT_NOT_FACE",
"msg_id": "c1b09cb2-6e05-4d21-55ab-r007b1f21bec"
},
"progress": 1,
"predict_elapsed": 10000,
"create_time": 1759201989444,
"task_id": "t_mt1a3i5n7be8d575cc-2ffb-4e0c-85a8-1824110e31b8",
"custom_task_id": "",
"trace_id": "",
"client_info": "",
"init_images": null
}
}General Error Codes and Messages
See API Error Codes.
SDK Examples
Python
import requests
import json
from sign_sdk import sign
def api_call_example():
key = "your_api_key"
secret = "your_api_secret"
url = "https://openapi.meitu.com/api/v1/sdk/sync/push"
method = "POST"
headers = {
"Content-Type": "application/json",
sign.HeaderHost: "openapi.meitu.com",
}
inner_params = {
"rsp_media_type": "url",
"parameter": {
"nMask": False,
"model_type": 0,
},
}
payload_dict = {
"task": "/v1/photo_scissors/sod",
"task_type": "mtlab",
"init_images": [{
"url": "https://example.com/image.jpg",
"profile": {
"media_profiles": {"media_data_type":"url"},
"version": "v1"
}
}],
"params": json.dumps(inner_params, ensure_ascii=False),
"sync_timeout": 30,
}
body = json.dumps(payload_dict, ensure_ascii=False)
try:
signer = sign.Signer(key, secret)
signed_request = signer.sign(url, method, headers, body)
session = requests.Session()
response = session.send(signed_request)
print(f"Status: {response.status_code}")
print(f"Response: {response.text}")
except Exception as e:
print(f"Error: {str(e)}")
if __name__ == "__main__":
api_call_example()Go
package main
import (
"fmt"
"io"
"net/http"
"github.com/mtlab/api/signer"
)
func main() {
key := "your_api_key"
secret := "your_api_secret"
signObj := signer.NewSigner(key, secret)
url := "https://openapi.meitu.com/api/v1/sdk/sync/push"
method := "POST"
headers := make(http.Header)
headers.Set(signer.HeaderHost, "openapi.meitu.com")
headers.Set("Content-Type", "application/json")
body := `{
"task": "/v1/photo_scissors/sod",
"task_type": "mtlab",
"init_images": [{
"url": "https://example.com/image.jpg",
"profile": {
"media_profiles": {"media_data_type":"url"},
"version": "v1"
}
}],
"params": "{\"rsp_media_type\":\"url\",\"parameter\":{\"nMask\":false,\"model_type\":0}}",
"sync_timeout": 30
}`
req, err := signObj.Sign(url, method, headers, body)
if err != nil {
fmt.Println("Failed to sign request:", err)
return
}
client := http.DefaultClient
resp, err := client.Do(req)
if err != nil {
fmt.Println("Failed to send request:", err)
return
}
defer resp.Body.Close()
bodyBytes, err := io.ReadAll(resp.Body)
if err != nil {
fmt.Println("Read response failed:", err)
return
}
fmt.Println("Response:", resp.StatusCode, string(bodyBytes))
}PHP
<?php
require 'signer.php';
$key = 'your_api_key';
$secret = 'your_api_secret';
$signer = new Signer($key, $secret);
$url = 'https://openapi.meitu.com/api/v1/sdk/sync/push';
$method = 'POST';
$headers = [
'Content-Type' => 'application/json'
];
$innerParams = json_encode([
"rsp_media_type" => "url",
"parameter" => [
"nMask" => false,
"model_type" => 0
]
]);
$body = json_encode([
"task" => "/v1/photo_scissors/sod",
"task_type" => "mtlab",
"init_images" => [
[
"url" => "https://example.com/image.jpg",
"profile" => [
"media_profiles" => ["media_data_type" => "url"],
"version" => "v1"
]
]
],
"params" => $innerParams,
"sync_timeout" => 30
]);
$curl = $signer->sign($url, $method, $headers, $body);
$response = curl_exec($curl);
$status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
if ($status == 0) {
echo "Error: " . curl_error($curl);
} else {
echo "Status: " . $status . "\n";
echo "Response: " . $response;
}
curl_close($curl);
?>Java
package com.meitu.openai.common;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import com.meitu.openai.common.Signer;
public class Main {
public static void main(String[] args) throws Exception {
Signer signer = new Signer("your_api_key", "your_api_secret");
String url = "https://openapi.meitu.com/api/v1/sdk/sync/push";
String method = "POST";
Map<String, String> headers = new HashMap<>();
headers.put("Content-Type", "application/json");
headers.put(Signer.HeaderHost, "openapi.meitu.com");
String body = "{\n" +
" \"task\": \"/v1/photo_scissors/sod\",\n" +
" \"task_type\": \"mtlab\",\n" +
" \"init_images\": [\n" +
" {\n" +
" \"url\": \"https://example.com/image.jpg\",\n" +
" \"profile\": {\n" +
" \"media_profiles\": {\n" +
" \"media_data_type\": \"url\"\n" +
" },\n" +
" \"version\": \"v1\"\n" +
" }\n" +
" }\n" +
" ],\n" +
" \"params\": \"{\\\"rsp_media_type\\\":\\\"url\\\",\\\"parameter\\\":{\\\"nMask\\\":false,\\\"model_type\\\":0}}\",\n" +
" \"sync_timeout\": 30\n" +
"}";
Map<String,String> signedHeaders = signer.sign(url, method, headers, body);
System.out.println("signedHeader: "+signedHeaders);
try {
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
connection.setRequestMethod(method);
for (Map.Entry<String,String> entry : signedHeaders.entrySet()) {
connection.setRequestProperty(entry.getKey(), entry.getValue());
}
connection.setDoOutput(true);
if (body!=null){
connection.getOutputStream().write(body.getBytes(StandardCharsets.UTF_8));
}
int status = connection.getResponseCode();
System.out.println(status);
InputStream inputStream;
if (status >= 400) {
inputStream = connection.getErrorStream();
} else {
inputStream = connection.getInputStream();
}
BufferedReader in = new BufferedReader(new InputStreamReader(inputStream));
String inputLine;
StringBuilder response = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
System.out.println("======");
System.out.println(response.toString());
System.out.println("======");
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
}