图像特征提取 API:时尚单品检测与视觉特征向量生成
在数百万商品中找到视觉上相似的产品,是电商领域最具挑战的问题之一。用户在街上拍到一双鞋,想知道在哪里可以买到。卖家想监控竞争对手是否在用不同名称销售外观相同的产品。传统的文本搜索在这里无能为力——你无法用关键词搜索一种视觉风格。
我们的图像特征提取接口通过两个端点解决了这个问题:一个用于检测图片中的时尚单品,另一个用于生成视觉特征向量以进行相似搜索。两者均由 GensmoRetro Pro(GR-Pro) 驱动,这是 LookBench 技术报告中描述的模型的持续优化生产版本。
视觉搜索为何对电商至关重要
消费者所见与所能搜索之间的鸿沟,一直是文本搜索产品发现的核心局限。用户在 Instagram 上看到一款手袋、在杂志上看到一件夹克、在街头看到一双运动鞋——唯一的选择就是猜测关键词,然后在数百个不相关的结果中滚动翻找。这道鸿沟每年让零售商损失数十亿美元的转化机会。
对卖家而言,问题同样严峻。假冒检测、商品目录去重、竞品监控都需要大规模比对商品图片。人工审核成千上万的商品列表来判断视觉相似性并不现实,而当不同卖家为外观相同的产品使用不同的标题和描述时,基于文本的匹配也会失效。
视觉特征向量技术通过将图片转换为捕捉感知相似性的数值向量来弥合这一鸿沟。同一双红色运动鞋的两张图片——不同角度拍摄、不同背景、来自不同卖家——会生成在向量空间中彼此接近的特征向量。这使得在数百万商品中进行最近邻搜索既快速又准确。
关键挑战在于领域专用性。通用视觉模型(如 CLIP)在广泛的互联网数据上训练,缺乏对时尚属性的细粒度理解——面料纹理、轮廓线条、五金细节、色彩渐变——而这些正是区分不同产品的关键。专门在时尚图像上训练的模型能够捕捉这些细微差别,这也是为什么专用时尚特征向量在检索基准测试中持续优于通用模型。
模型介绍
GR-Pro 是一个高容量视觉 Transformer(ViT),拥有约 3 亿参数,在 650 万张精选时尚图片(涵盖 190 万个独立商品身份)上训练。它生成 L2 归一化的特征向量,能够捕捉对时尚检索至关重要的细粒度视觉特征——纹理、图案、轮廓、配饰等。
在 LookBench 基准测试上,GR-Pro 取得了 67.4% Fine Recall@1 的整体成绩,显著超越最佳公开基线(Marqo-FashionCLIP 63.2%、SigLIP2 59.4%)。在真实街拍图片(最难的子集)上,领先幅度扩大到 5.5 个百分点。在经典 Fashion200K 基准上,GR-Pro 达到了 88.7% Recall@1。
核心技术亮点:
- ArcFace 训练 + Partial FC,在 190 万类别上实现可扩展的基于身份的度量学习
- 纯视觉编码器 — 无需文本输入,却在时尚检索任务上超越多模态 CLIP 系列模型
- 10 个时尚品类 — 包、帽子、羽绒服、眼镜、首饰、其他、鞋、袜子、上衣、手表
- 持续优化 — API 提供的生产版本会定期更新,性能持续超越论文发表时的结果
两个端点
1. 图像特征提取 — 生成视觉特征向量
从图片中检测到的时尚单品提取特征向量。这些向量可用于相似搜索、商品去重、视觉推荐或聚类分析。
端点: POST https://api.apiclaw.io/openapi/v2/model/image-embedding
积分: 每次请求消耗 1 积分。
请求
{
"image": "https://example.com/photo.jpg",
"withTag": true,
"withEmbedding": true,
"text": ["红色连衣裙"]
}
字段说明:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
image | 字符串 | 是 | 待分析图片的公开访问链接 |
topK | 整数 | 否 | 最多检测多少个单品 |
boundingBoxes | 整数数组 | 否 | 手动指定感兴趣区域的像素坐标 [[x1,y1,x2,y2], ...],不传则自动检测 |
text | 字符串或字符串数组 | 否 | 搜索文本,用于评估每个检测单品与文本的匹配程度 |
withTag | 布尔值 | 否 | 是否返回品类标签(如"鞋"、"包"等),默认不返回 |
withEmbedding | 布尔值 | 否 | 是否返回特征向量(用于相似搜索),默认返回 |
响应
{
"success": true,
"data": {
"boundingBoxes": [[120, 45, 380, 520]],
"tags": [["Up-Clothing", 0.92]],
"embeddings": [[0.0312, -0.0156, 0.0478, ...]],
"textRelevanceScores": [0.847]
},
"meta": {
"requestId": "req_a1b2c3d4e5f67890",
"timestamp": "2026-04-22T10:30:00.000000Z",
"creditsRemaining": 998,
"creditsConsumed": 1
}
}
2. 图像检测 — 定位时尚单品
检测并分类图片中的时尚单品,返回边界框和置信度分数。可按品类过滤,仅检测特定类型的单品。
端点: POST https://api.apiclaw.io/openapi/v2/model/image-detection
积分: 每次请求消耗 1 积分。
请求
{
"image": "https://example.com/street-photo.jpg",
"topK": 5,
"classes": [6, 8],
"returnImage": false
}
字段说明:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
image | 字符串 | 是 | 待分析图片的公开访问链接 |
topK | 整数 | 是 | 最多检测多少个单品(1-50) |
classes | 整数数组 | 否 | 指定要检测的品类编号(不传则检测所有品类),见下方品类编号表 |
returnImage | 布尔值 | 否 | 是否返回标注了检测框的图片,默认不返回 |
品类编号: 0=包, 1=帽子, 2=羽绒服, 3=眼镜, 4=首饰, 5=其他, 6=鞋, 7=袜子, 8=上衣, 9=手表
响应
{
"success": true,
"data": {
"detections": [
{
"areaRatio": 0.15,
"centerDistanceRatio": 0.08,
"classId": 8,
"score": 0.96,
"boundingBox": [120, 45, 380, 520]
},
{
"areaRatio": 0.07,
"centerDistanceRatio": 0.35,
"classId": 6,
"score": 0.91,
"boundingBox": [200, 480, 350, 620]
}
],
"annotatedImage": null
},
"meta": {
"requestId": "req_b2c3d4e5f6789012",
"timestamp": "2026-04-22T10:30:00.000000Z",
"creditsRemaining": 997,
"creditsConsumed": 1
}
}
代码示例
示例 1:检测时尚单品(curl)
curl -s -X POST https://api.apiclaw.io/openapi/v2/model/image-detection \
-H "Authorization: Bearer hms_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"image": "https://example.com/outfit.jpg",
"topK": 10
}'
示例 2:Python — 视觉相似搜索
import httpx
import numpy as np
APICLAW_URL = "https://api.apiclaw.io/openapi/v2/model/image-embedding"
APICLAW_KEY = "hms_live_YOUR_API_KEY"
def get_fashion_embeddings(image_url: str) -> list[list[float]]:
"""从图片中提取时尚单品特征向量。"""
resp = httpx.post(
APICLAW_URL,
headers={"Authorization": f"Bearer {APICLAW_KEY}"},
json={"image": image_url, "withEmbedding": True, "withTag": True},
timeout=30.0,
)
result = resp.json()
if not result["success"]:
raise RuntimeError(f"特征提取失败:{result}")
return result["data"]["embeddings"]
def cosine_similarity(a: list[float], b: list[float]) -> float:
"""计算两个特征向量的余弦相似度。"""
a, b = np.array(a), np.array(b)
return float(np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b)))
# 获取查询图片和商品图片的特征向量
query_embeds = get_fashion_embeddings("https://example.com/query-shoe.jpg")
catalog_embeds = get_fashion_embeddings("https://example.com/catalog-shoe.jpg")
# 比较各自检测到的第一个单品
similarity = cosine_similarity(query_embeds[0], catalog_embeds[0])
print(f"视觉相似度:{similarity:.3f}")
# => 视觉相似度:0.927
示例 3:Python — 检测 + 特征提取流水线
import httpx
BASE_URL = "https://api.apiclaw.io/openapi/v2/model"
HEADERS = {"Authorization": "Bearer hms_live_YOUR_API_KEY"}
def detect_and_embed(image_url: str, categories: list[int] | None = None):
"""先检测时尚单品,再生成对应的特征向量。"""
# 第 1 步:检测单品
detect_resp = httpx.post(
f"{BASE_URL}/image-detection",
headers=HEADERS,
json={"image": image_url, "topK": 10, "classes": categories},
timeout=30.0,
)
detections = detect_resp.json()["data"]["detections"]
if not detections:
return []
# 第 2 步:用检测到的边界框生成特征向量
bboxes = [d["boundingBox"] for d in detections]
embed_resp = httpx.post(
f"{BASE_URL}/image-embedding",
headers=HEADERS,
json={
"image": image_url,
"boundingBoxes": [[int(x) for x in bb] for bb in bboxes],
"withEmbedding": True,
"withTag": True,
},
timeout=30.0,
)
embed_data = embed_resp.json()["data"]
# 合并检测元数据与特征向量
results = []
for i, det in enumerate(detections):
results.append({
"classId": det["classId"],
"score": det["score"],
"boundingBox": det["boundingBox"],
"tag": embed_data["tags"][i] if embed_data.get("tags") else None,
"embedding": embed_data["embeddings"][i],
})
return results
# 检测街拍照片中的鞋和上衣
items = detect_and_embed(
"https://example.com/street-fashion.jpg",
categories=[6, 8], # 鞋 + 上衣
)
for item in items:
print(f" 品类 {item['classId']}(置信度={item['score']:.2f}):{item['tag']}")
示例 4:TypeScript — 视觉搜索 API 路由
import { NextRequest, NextResponse } from "next/server";
const BASE_URL = "https://api.apiclaw.io/openapi/v2/model";
const APICLAW_KEY = process.env.APICLAW_API_KEY!;
interface Detection {
areaRatio: number;
centerDistanceRatio: number;
classId: number;
score: number;
boundingBox: number[];
}
interface EmbeddingResult {
boundingBoxes: number[][];
tags: [string, number][] | null;
embeddings: number[][] | null;
textRelevanceScores: number[] | null;
}
async function detectFashionItems(imageUrl: string, topK: number = 10): Promise<Detection[]> {
const res = await fetch(`${BASE_URL}/image-detection`, {
method: "POST",
headers: {
Authorization: `Bearer ${APICLAW_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ image: imageUrl, topK }),
});
const data = await res.json();
if (!data.success) throw new Error("检测失败");
return data.data.detections;
}
async function getEmbeddings(imageUrl: string, text?: string): Promise<EmbeddingResult> {
const res = await fetch(`${BASE_URL}/image-embedding`, {
method: "POST",
headers: {
Authorization: `Bearer ${APICLAW_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
image: imageUrl,
withEmbedding: true,
withTag: true,
text: text ? [text] : undefined,
}),
});
const data = await res.json();
if (!data.success) throw new Error("特征提取失败");
return data.data;
}
// 使用示例:查找视觉相似商品
export async function POST(req: NextRequest) {
const { imageUrl, query } = await req.json();
const embeddings = await getEmbeddings(imageUrl, query);
// 用 embeddings.embeddings[0] 在向量数据库中进行最近邻搜索
return NextResponse.json({ embeddings });
}
适用场景
| 场景 | 端点 | 方式 |
|---|---|---|
| 以图搜商品 | 两者 | 检测查询图片中的单品,生成特征向量,在商品库中搜索最近邻 |
| 竞品监控 | 特征提取 | 对自有商品和竞品图片生成特征向量,标记高相似度配对 |
| 商品目录去重 | 特征提取 | 按特征向量相似度聚类,发现重复商品 |
| 时尚趋势分析 | 检测 | 对社交媒体图片批量检测,统计品类频次 |
| 穿搭推荐 | 两者 | 检测穿搭中所有单品,对每个生成特征向量,推荐互补单品 |
| 内容审核 | 检测 | 验证商品列表是否包含所声称的时尚品类 |
参考文献
- Gao, C.*, Xue, S.*, et al. "LookBench: A Live and Holistic Open Benchmark for Fashion Image Retrieval". arXiv:2601.14706, 2026.
- Oquab, M., et al. "DINOv2: Learning Robust Visual Features without Supervision". arXiv:2304.07193, 2023.
- Deng, J., et al. "ArcFace: Additive Angular Margin Loss for Deep Face Recognition". arXiv:1801.07698, 2018.