人脸检测

namifusion/detect_faces

人脸检测模型, 用于检测输入元素中包含的人脸信息

示例

人脸检测 example 1

参数

名称类型默认约束说明
url媒体URLtext图片或视频URL。url 与 img 至少提供一个;若同时提供则优先使用 url。
imgBase64图片textareaBase64 编码图片输入(未提供 url 时使用)。
num_frames抽帧数量number5视频输入时采样的帧数。
return_face_url返回人脸URLbooleantrue是否返回裁剪后的人脸图片URL。
single_face仅返回最大人脸booleanfalse是否只返回检测到的最大人脸。
deduplicate人脸去重booleantrue是否对视频采样帧中的人脸做跨帧去重。
similarity_threshold相似度阈值number0.45去重相似度阈值(0.0-1.0);值越高越严格。
time_range时间区间object{}可选的视频处理时间区间(秒);仅对视频输入生效。
start起始number≥ 0
end终止number≥ 0

API

通过统一 REST API 调用本模型;在 API Keys 页获取密钥。

cURL
# 1) Submit — returns { "task_uuid": "..." }
curl -X POST "https://www.namifusion.com/api/v1/marketplace/run/namifusion/detect_faces" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "input": {
    "url": "https://assets-public.namifusion.com/marketplace/thumbnails/2026-02-25/fb559d5bc3dc.png",
    "num_frames": 5,
    "return_face_url": true,
    "single_face": false,
    "deduplicate": true,
    "similarity_threshold": 0.45,
    "time_range": {}
  }
}'

# 2) Poll until status is "completed", then read the output URLs
curl "https://www.namifusion.com/api/v1/marketplace/run/tasks/TASK_UUID" \
  -H "Authorization: Bearer YOUR_API_KEY"
Python
import time, requests

API_KEY = "YOUR_API_KEY"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}

# 1) Submit
resp = requests.post(
    "https://www.namifusion.com/api/v1/marketplace/run/namifusion/detect_faces",
    headers=HEADERS,
    json={
        "input": {
            "url": "https://assets-public.namifusion.com/marketplace/thumbnails/2026-02-25/fb559d5bc3dc.png",
            "num_frames": 5,
            "return_face_url": True,
            "single_face": False,
            "deduplicate": True,
            "similarity_threshold": 0.45,
            "time_range": {}
        }
    },
)
resp.raise_for_status()  # 401/402/429/5xx stop here instead of polling a bad task
task = resp.json()

# 2) Poll until a terminal state (completed / failed / cancelled).
#    This model is allowed up to 30s server-side.
deadline = time.time() + 90
while task.get("status") not in ("completed", "failed", "cancelled"):
    if time.time() > deadline:
        raise TimeoutError(f"still {task.get('status')} — keep the task_uuid and poll later")
    time.sleep(3)
    poll = requests.get(f"https://www.namifusion.com/api/v1/marketplace/run/tasks/{task['task_uuid']}", headers=HEADERS)
    poll.raise_for_status()
    task = poll.json()

print(task["status"], task.get("output"))
JavaScript
const API_KEY = "YOUR_API_KEY";
const HEADERS = { Authorization: `Bearer ${API_KEY}` };

// 1) Submit
const resp = await fetch("https://www.namifusion.com/api/v1/marketplace/run/namifusion/detect_faces", {
  method: "POST",
  headers: { ...HEADERS, "Content-Type": "application/json" },
  body: JSON.stringify({
    "input": {
      "url": "https://assets-public.namifusion.com/marketplace/thumbnails/2026-02-25/fb559d5bc3dc.png",
      "num_frames": 5,
      "return_face_url": true,
      "single_face": false,
      "deduplicate": true,
      "similarity_threshold": 0.45,
      "time_range": {}
    }
  }),
});
if (!resp.ok) throw new Error(`submit failed: ${resp.status} ${await resp.text()}`);
let task = await resp.json();

// 2) Poll until a terminal state (completed / failed / cancelled).
//    This model is allowed up to 30s server-side.
const deadline = Date.now() + 90 * 1000;
while (!["completed", "failed", "cancelled"].includes(task.status)) {
  if (Date.now() > deadline) throw new Error(`still ${task.status} — keep the task_uuid and poll later`);
  await new Promise((r) => setTimeout(r, 3000));
  const poll = await fetch(`https://www.namifusion.com/api/v1/marketplace/run/tasks/${task.task_uuid}`, { headers: HEADERS });
  if (!poll.ok) throw new Error(`poll failed: ${poll.status}`);
  task = await poll.json();
}

console.log(task.status, task.output);

文档

NamiFusion 视频换脸

AI 视频换脸:支持单人自动换脸和多人精准映射,结合人脸检测实现完整的视频换脸工作流。

NamiFusion 视频换脸是一项高质量 AI 视频换脸服务,可将源人脸替换到目标视频中。提供两种模式:单人换脸(自动模式)和多人换脸(精准映射模式),并可结合 NamiFusion 人脸检测实现从检测到换脸的完整工作流。


核心功能

  • 单人换脸: 开启 single_face_mode,无需任何额外配置即可自动完成换脸。
  • 多人精准映射: 使用 face_mapping 精准指定源人脸与目标人脸的对应关系,支持一对一及多对多映射。
  • 人脸增强: 可选的高级美化功能,自动平滑皮肤、去除瑕疵,提升换脸后的人脸质量。
  • 异步任务: 提交后返回 task_uuid,通过轮询或 Webhook 获取结果。

技术规格

参数详情
模型 IDnamifusion/faceswap-video
请求方式异步 POST(提交任务 + 轮询/Webhook 获取结果)
输入源人脸图片 URL + 目标视频 URL
输出换脸后的视频 URL
处理时长通常 30 秒至数分钟(取决于视频时长和分辨率)
源图片格式JPG、PNG;分辨率最高支持 4K
目标视频格式MP4、MOV、WEBM、AVI;最大文件 5 GB;最长时长 2 小时;分辨率最高支持 4K

快速开始

API 端点

端点方法说明
/api/v1/marketplace/run/namifusion/faceswap-videoPOST提交视频换脸任务
/api/v1/marketplace/run/tasks/{task_uuid}GET查询任务状态和结果

鉴权

在请求头中携带 API Key:

X-API-Key: sk-your-api-key

场景一:单人换脸(最简用法)

适用于源图片和目标视频均只含一张人脸的场景。开启 single_face_mode 后无需配置 face_mapping,服务将自动完成换脸。

第一步:提交换脸任务

curl -X POST "https://www.namifusion.com/api/v1/marketplace/run/namifusion/faceswap-video" \
  -H "X-API-Key: sk-your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "input": {
      "source_url": "https://example.com/source_face.jpg",
      "target_url": "https://example.com/target_video.mp4",
      "single_face_mode": true
    }
  }'

响应示例:

{
  "task_uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "status": "pending",
  "cost_credits": 50
}

第二步:轮询任务状态

curl -X GET "https://www.namifusion.com/api/v1/marketplace/run/tasks/a1b2c3d4-e5f6-7890-abcd-ef1234567890" \
  -H "X-API-Key: sk-your-api-key"

处理中:

{
  "task_uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "status": "processing"
}

已完成:

{
  "task_uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "model_id": "namifusion/faceswap-video",
  "status": "completed",
  "output": {
    "videos": ["https://cdn.namifusion.com/result/faceswap_abc123.mp4"]
  },
  "cost_credits": 50,
  "created_at": "2026-02-27T10:00:00Z",
  "completed_at": "2026-02-27T10:01:30Z"
}

场景二:多人换脸

当目标视频包含多张人脸,且需要精准控制"哪张源人脸替换哪张目标人脸"时,需先调用人脸检测从视频中检测人脸,再构建 face_mapping 提交换脸任务。

第一步:检测目标视频中的人脸

调用 NamiFusion 人脸检测(POST /api/v1/marketplace/run/namifusion/detect_faces)直接对视频进行检测,然后轮询结果。

提交检测任务:

curl -X POST "https://www.namifusion.com/api/v1/marketplace/run/namifusion/detect_faces" \
  -H "X-API-Key: sk-your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "input": {
      "url": "https://example.com/target_video.mp4",
      "num_frames": 3,
      "return_face_url": true,
      "deduplicate": true
    }
  }'

num_frames 指定从视频中均匀采样的帧数用于人脸检测。最大值:100。值越大,检测到所有人脸的概率越高,但处理时间也会增加。对于大多数视频,3–10 帧已足够。

轮询任务结果:

curl -X GET "https://www.namifusion.com/api/v1/marketplace/run/tasks/{task_uuid}" \
  -H "X-API-Key: sk-your-api-key"

已完成响应(假设检测到 2 人):

{
  "task_uuid": "...",
  "status": "completed",
  "output": {
    "error_code": 0,
    "error_msg": "SUCCESS",
    "faces_obj": {
      "0": {
        "region": [[50, 80, 150, 200], [250, 70, 350, 190]],
        "face_urls": [
          "https://s3.amazonaws.com/faces/target_face_0.jpg",
          "https://s3.amazonaws.com/faces/target_face_1.jpg"
        ],
        "landmarks": [[[...]], [[...]]],
        "frame_time": null,
        "crop_region": [[...], [...]],
        "landmarks_str": ["...", "..."],
        "crop_landmarks": ["...", "..."]
      },
      "1": {
        "region": [],
        "face_urls": [],
        "landmarks": [],
        "frame_time": 1.0,
        "crop_region": [],
        "landmarks_str": [],
        "crop_landmarks": []
      },
      "2": {
        "region": [],
        "face_urls": [],
        "landmarks": [],
        "frame_time": 2.0,
        "crop_region": [],
        "landmarks_str": [],
        "crop_landmarks": []
      }
    }
  }
}

由此可知目标视频有 2 人(faces_obj["0"].region 长度为 2)及其 face_urls

第二步:检测源人脸图片

同样调用人脸检测提交检测任务并轮询结果(若有多张源人脸图片或需要传递精确人脸坐标信息时使用)。

提交检测任务:

curl -X POST "https://www.namifusion.com/api/v1/marketplace/run/namifusion/detect_faces" \
  -H "X-API-Key: sk-your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "input": {
      "url": "https://example.com/source_face.jpg",
      "return_face_url": true
    }
  }'

已完成响应:

{
  "task_uuid": "...",
  "status": "completed",
  "output": {
    "error_code": 0,
    "error_msg": "SUCCESS",
    "faces_obj": {
      "0": {
        "region": [[100, 50, 200, 180]],
        "face_urls": ["https://s3.amazonaws.com/faces/source_face_0.jpg"],
        "landmarks": [[[...]]],
        "frame_time": null,
        "crop_region": [[...]],
        "landmarks_str": ["..."],
        "crop_landmarks": ["..."]
      }
    }
  }
}

第三步:构建 face_mapping

根据检测结果,构建源人脸到目标人脸的映射关系。

将人脸检测返回的 face_urls 分别作为 face_mapping 中的 source_face_info.face_urltarget_face_info.face_url

"face_mapping": [
  {
    "source_face_info": {
      "face_url": "https://s3.amazonaws.com/faces/source_face_0.jpg"
    },
    "target_face_info": {
      "face_url": "https://s3.amazonaws.com/faces/target_face_0.jpg"
    }
  }
]

face_url 的值直接取自第一步和第二步人脸检测返回的 output.faces_obj["0"].face_urls[i]

face_mapping 还支持 source_face_indextarget_face_indexbbox 等参数,详见下方"face_mapping 详解"章节。

第四步:提交多人换脸任务

curl -X POST "https://www.namifusion.com/api/v1/marketplace/run/namifusion/faceswap-video" \
  -H "X-API-Key: sk-your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "input": {
      "source_url": "https://example.com/source_face.jpg",
      "target_url": "https://example.com/target_video.mp4",
      "single_face_mode": false,
      "face_mapping": [
        {
          "source_face_info": {
            "face_url": "https://s3.amazonaws.com/faces/source_face_0.jpg"
          },
          "target_face_info": {
            "face_url": "https://s3.amazonaws.com/faces/target_face_0.jpg"
          }
        }
      ]
    }
  }'

响应:

{
  "task_uuid": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
  "status": "pending",
  "cost_credits": 50
}

第五步:获取换脸结果

轮询任务状态直到 status 变为 completed

curl -X GET "https://www.namifusion.com/api/v1/marketplace/run/tasks/b2c3d4e5-f6a7-8901-bcde-f12345678901" \
  -H "X-API-Key: sk-your-api-key"

已完成响应:

{
  "task_uuid": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
  "model_id": "namifusion/faceswap-video",
  "status": "completed",
  "output": {
    "videos": ["https://cdn.namifusion.com/result/faceswap_def456.mp4"]
  },
  "cost_credits": 50,
  "created_at": "2026-02-27T10:05:00Z",
  "completed_at": "2026-02-27T10:07:30Z"
}

Python 完整示例:多人视频换脸工作流

以下示例演示从人脸检测到多人视频换脸的完整工作流:

import requests
import time

API_KEY = "sk-your-api-key"
BASE_URL = "https://www.namifusion.com/api/v1/marketplace/run"
HEADERS = {
    "X-API-Key": API_KEY,
    "Content-Type": "application/json",
}

source_url = "https://example.com/source_face.jpg"
target_url = "https://example.com/target_video.mp4"


def detect_faces(media_url, num_frames=None):
    """提交人脸检测任务并轮询结果。"""
    input_params = {"url": media_url, "return_face_url": True}
    if num_frames:
        input_params["num_frames"] = num_frames
    task = requests.post(
        f"{BASE_URL}/namifusion/detect_faces",
        headers=HEADERS,
        json={"input": input_params},
    ).json()

    while True:
        resp = requests.get(
            f"{BASE_URL}/tasks/{task['task_uuid']}",
            headers=HEADERS,
        ).json()

        if resp["status"] == "completed":
            return resp["output"]
        elif resp["status"] == "failed":
            raise Exception(resp.get("error_message", "未知错误"))

        time.sleep(3)


# 第一步:检测目标视频中的人脸
target_detect = detect_faces(target_url, num_frames=3)
target_frame = target_detect["faces_obj"]["0"]

print(f"目标视频共 {len(target_frame['face_urls'])} 张人脸")
for i, face_url in enumerate(target_frame["face_urls"]):
    print(f"  人脸 {i}: region={target_frame['region'][i]}")

# 第二步:检测源图片中的人脸
source_detect = detect_faces(source_url)
source_frame = source_detect["faces_obj"]["0"]

# 第三步:构建 face_mapping(用源人脸 0 替换目标人脸 0)
face_mapping = [
    {
        "source_face_info": {"face_url": source_frame["face_urls"][0]},
        "target_face_info": {"face_url": target_frame["face_urls"][0]},
    }
]

# 第四步:提交视频换脸任务
task_resp = requests.post(
    f"{BASE_URL}/namifusion/faceswap-video",
    headers=HEADERS,
    json={
        "input": {
            "source_url": source_url,
            "target_url": target_url,
            "single_face_mode": False,
            "face_mapping": face_mapping,
        }
    },
).json()

task_uuid = task_resp["task_uuid"]
print(f"任务已提交:{task_uuid}")

# 第五步:轮询结果
while True:
    status_resp = requests.get(
        f"{BASE_URL}/tasks/{task_uuid}",
        headers=HEADERS,
    ).json()

    status = status_resp["status"]
    print(f"状态:{status}")

    if status == "completed":
        result_url = status_resp["output"]["videos"][0]
        print(f"结果:{result_url}")
        break
    elif status == "failed":
        print(f"失败:{status_resp.get('error_message', '未知错误')}")
        break

    time.sleep(10)

参数与响应说明

请求参数

请求体为 JSON 格式,所有参数放在 input 对象内:

{
  "input": {
    "source_url": "https://...",
    "target_url": "https://...",
    "single_face_mode": true,
    "face_enhance": false,
    "face_mapping": [],
    "model_style": "realistic"
  }
}
参数类型必填默认值说明
source_urlstring-源人脸图片 URL(需要换到目标视频上的人脸)。必须可公开访问。支持 HTTP/HTTPS。支持格式:JPG、PNG,分辨率最高 4K。
target_urlstring-目标视频 URL(需要被换脸的视频)。必须可公开访问。支持 HTTP/HTTPS。支持格式:MP4、MOV、WEBM、AVI,最大 5 GB,最长 2 小时,分辨率最高 4K。
single_face_modebooleantrue单人模式。开启后无需配置 face_mapping,自动完成换脸。
face_enhancebooleanfalse是否开启人脸增强。开启后自动平滑皮肤、去除瑕疵,提升人脸质量,但会增加处理时间。
face_mappingarraynull人脸映射配置。仅在 single_face_mode: false 时生效,详见下方说明。
model_stylestring"realistic"换脸风格。可选值:"realistic""beautify""lossless",详见"参数对输出的影响"章节。

face_mapping 详解

face_mapping 是一个数组,每个元素定义一组源人脸到目标人脸的映射:

字段类型必填说明
source_face_indexinteger源图片中人脸的索引(从 0 开始,按人脸检测框左上角 x 坐标从左到右排序)。
target_face_indexinteger目标视频中人脸的索引(从 0 开始,按人脸检测框左上角 x 坐标从左到右排序)。
source_face_infoobject源人脸的坐标信息。传入后跳过内部重新检测,确保人脸顺序一致。
target_face_infoobject目标人脸的坐标信息。传入后提升匹配精度。

source_face_info 字段

字段类型说明
face_urlstring人脸检测返回的已裁剪人脸图片 URL(output.faces_obj["0"].face_urls[i])。传入后后端直接使用此裁剪图换脸,跳过内部重新检测,确保人脸身份一致。
bboxnumber[]人脸检测框坐标(像素),格式 [x1, y1, x2, y2],其中 (x1, y1) 为左上角坐标,(x2, y2) 为右下角坐标。取自人脸检测返回的 region 字段。
kpsnumber[][]5 个人脸关键点坐标,格式 [[x, y], ...],顺序依次为:左眼、右眼、鼻尖、左嘴角、右嘴角。取自人脸检测返回的 landmarks 字段。传入后后端直接使用,跳过重新检测,提升换脸对齐精度。

target_face_info 字段

字段类型说明
face_urlstring目标人脸的已裁剪图片 URL,由人脸检测返回(output.faces_obj["0"].face_urls[i])。传入后后端精准匹配目标人脸,避免内部重新检测导致人脸顺序不一致。
bboxnumber[]目标人脸检测框坐标(像素),格式 [x1, y1, x2, y2],其中 (x1, y1) 为左上角坐标,(x2, y2) 为右下角坐标。

任务状态

提交任务后轮询状态,建议轮询间隔:10 秒。

状态说明
pending任务已创建,等待处理。
processing任务处理中。
completed任务完成,从 output.videos 获取结果 URL。
failed任务失败,查看 error_message 了解原因。

响应结构

任务提交响应

字段类型说明
task_uuidstring任务唯一标识符,用于后续状态查询。
statusstring初始状态,通常为 pending
cost_creditsnumber本次任务消耗的积分。

任务完成响应

字段类型说明
task_uuidstring任务唯一标识符。
model_idstring模型 ID(namifusion/faceswap-video)。
statusstring任务状态。
output.videosstring[]换脸结果视频 URL 列表。
cost_creditsnumber消耗的积分。
created_atstring任务创建时间(ISO 8601)。
completed_atstring任务完成时间(ISO 8601)。
error_messagestring错误信息(仅在 failed 时返回)。

参数对输出的影响

参数对结果的影响
single_face_mode: true自动完成换脸,适用于单人场景,无需配置 face_mapping
single_face_mode: false + face_mapping精准控制替换哪些人脸,映射中未指定的人脸保持不变。
face_enhance: true开启人脸增强,自动平滑皮肤、去除瑕疵,效果更精致自然,但处理时间增加约 20–50%。
face_enhance: false默认模式,不做额外人脸处理,处理速度更快。
model_style: "realistic"写实风格。效果自然,接近真实人脸,保留真实肤色和纹理。
model_style: "beautify"美颜风格。自动平滑皮肤、提亮肤色,呈现精致光滑的外观。
model_style: "lossless"无损风格。极致无损模式,完美保留原始人脸所有细节,真实感最强,几乎无法分辨。

Webhook

除轮询外,你也可以在请求体中提供 webhook_url,任务完成后自动接收结果。当任务变为 completedfailed 时,服务端会向该 URL 发送 POST 请求,携带完整任务结果。

webhook_url 是与 input 并列的顶级字段,不在 input 内部:

curl -X POST "https://www.namifusion.com/api/v1/marketplace/run/namifusion/faceswap-video" \
  -H "X-API-Key: sk-your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "input": {
      "source_url": "https://example.com/source_face.jpg",
      "target_url": "https://example.com/target_video.mp4",
      "single_face_mode": true
    },
    "webhook_url": "https://your-server.com/callback"
  }'

Webhook 回调体

POST 到 webhook_url 的数据结构与任务完成响应完全一致:

{
  "task_uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "model_id": "namifusion/faceswap-video",
  "status": "completed",
  "output": {
    "videos": ["https://cdn.namifusion.com/result/faceswap_abc123.mp4"]
  },
  "cost_credits": 50,
  "created_at": "2026-02-27T10:00:00Z",
  "completed_at": "2026-02-27T10:01:30Z"
}

任务失败时,回调体包含 error_message 字段且 status"failed"

设置 webhook_url 不影响主动轮询任务状态,两者可同时使用。

Python 示例

提交带 webhook_url 的任务:

import requests

API_KEY = "sk-your-api-key"
BASE_URL = "https://www.namifusion.com/api/v1/marketplace/run"
HEADERS = {
    "X-API-Key": API_KEY,
    "Content-Type": "application/json",
}

# webhook_url 是与 input 并列的顶级字段,不能放在 input 内部
resp = requests.post(
    f"{BASE_URL}/namifusion/faceswap-video",
    headers=HEADERS,
    json={
        "input": {
            "source_url": "https://example.com/source_face.jpg",
            "target_url": "https://example.com/target_video.mp4",
            "single_face_mode": True,
        },
        "webhook_url": "https://your-server.com/callback",
    },
).json()

print(f"任务已提交:{resp['task_uuid']}")
# 无需轮询,结果将自动推送到 webhook_url

接收 Webhook 回调(Flask):

from flask import Flask, request, jsonify

app = Flask(__name__)

@app.route("/callback", methods=["POST"])
def webhook():
    payload = request.get_json()
    task_uuid = payload["task_uuid"]
    status = payload["status"]

    if status == "completed":
        video_url = payload["output"]["videos"][0]
        print(f"任务 {task_uuid} 完成:{video_url}")
    elif status == "failed":
        error = payload.get("error_message", "未知错误")
        print(f"任务 {task_uuid} 失败:{error}")

    return jsonify({"received": True}), 200

if __name__ == "__main__":
    app.run(port=8080)

注意事项

  1. URL 必须可公开访问source_urltarget_url 均须可直接下载。支持 HTTP 和 HTTPS。
  2. 人脸索引排序规则source_face_indextarget_face_index 均从 0 开始,按人脸检测框左上角 x 坐标从左到右排序。
  3. 强烈建议传入 face_info:若已调用过人脸检测,将检测到的 bbox 传入 face_mapping,可避免换脸服务内部重新检测导致人脸索引不一致的问题。
  4. 轮询间隔:建议每 10 秒轮询一次任务状态。视频换脸通常在 30 秒至数分钟内完成,具体取决于视频时长和分辨率。
  5. 结果字段名:输出字段名为 output.videos,返回换脸后的视频 URL。