diff --git a/swagger/docs.go b/swagger/docs.go index 9d0367d69..d4a927a2c 100644 --- a/swagger/docs.go +++ b/swagger/docs.go @@ -1672,6 +1672,165 @@ const docTemplate = `{ } } }, + "/v1/face/analyze": { + "post": { + "tags": [ + "face-recognition" + ], + "summary": "Analyze demographic attributes (age, gender, ...) of faces.", + "parameters": [ + { + "description": "query params", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.FaceAnalyzeRequest" + } + } + ], + "responses": { + "200": { + "description": "Response", + "schema": { + "$ref": "#/definitions/schema.FaceAnalyzeResponse" + } + } + } + } + }, + "/v1/face/embed": { + "post": { + "tags": [ + "face-recognition" + ], + "summary": "Extract a face embedding from an image.", + "parameters": [ + { + "description": "query params", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.FaceEmbedRequest" + } + } + ], + "responses": { + "200": { + "description": "Response", + "schema": { + "$ref": "#/definitions/schema.FaceEmbedResponse" + } + } + } + } + }, + "/v1/face/forget": { + "post": { + "tags": [ + "face-recognition" + ], + "summary": "Remove a previously-registered face by ID.", + "parameters": [ + { + "description": "query params", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.FaceForgetRequest" + } + } + ], + "responses": { + "204": { + "description": "No Content" + } + } + } + }, + "/v1/face/identify": { + "post": { + "tags": [ + "face-recognition" + ], + "summary": "Identify a face against the registered database (1:N recognition).", + "parameters": [ + { + "description": "query params", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.FaceIdentifyRequest" + } + } + ], + "responses": { + "200": { + "description": "Response", + "schema": { + "$ref": "#/definitions/schema.FaceIdentifyResponse" + } + } + } + } + }, + "/v1/face/register": { + "post": { + "tags": [ + "face-recognition" + ], + "summary": "Register a face for 1:N identification.", + "parameters": [ + { + "description": "query params", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.FaceRegisterRequest" + } + } + ], + "responses": { + "200": { + "description": "Response", + "schema": { + "$ref": "#/definitions/schema.FaceRegisterResponse" + } + } + } + } + }, + "/v1/face/verify": { + "post": { + "tags": [ + "face-recognition" + ], + "summary": "Verify that two images depict the same person.", + "parameters": [ + { + "description": "query params", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.FaceVerifyRequest" + } + } + ], + "responses": { + "200": { + "description": "Response", + "schema": { + "$ref": "#/definitions/schema.FaceVerifyResponse" + } + } + } + } + }, "/v1/images/generations": { "post": { "tags": [ @@ -3069,6 +3228,293 @@ const docTemplate = `{ } } }, + "schema.FaceAnalysis": { + "type": "object", + "properties": { + "age": { + "type": "number" + }, + "antispoof_score": { + "type": "number" + }, + "dominant_emotion": { + "type": "string" + }, + "dominant_gender": { + "type": "string" + }, + "dominant_race": { + "type": "string" + }, + "emotion": { + "type": "object", + "additionalProperties": { + "type": "number", + "format": "float32" + } + }, + "face_confidence": { + "type": "number" + }, + "gender": { + "type": "object", + "additionalProperties": { + "type": "number", + "format": "float32" + } + }, + "is_real": { + "type": "boolean" + }, + "race": { + "type": "object", + "additionalProperties": { + "type": "number", + "format": "float32" + } + }, + "region": { + "$ref": "#/definitions/schema.FacialArea" + } + } + }, + "schema.FaceAnalyzeRequest": { + "type": "object", + "properties": { + "actions": { + "description": "subset of {\"age\",\"gender\",\"emotion\",\"race\"}", + "type": "array", + "items": { + "type": "string" + } + }, + "anti_spoofing": { + "type": "boolean" + }, + "img": { + "type": "string" + }, + "model": { + "type": "string" + } + } + }, + "schema.FaceAnalyzeResponse": { + "type": "object", + "properties": { + "faces": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.FaceAnalysis" + } + } + } + }, + "schema.FaceEmbedRequest": { + "type": "object", + "properties": { + "img": { + "type": "string" + }, + "model": { + "type": "string" + } + } + }, + "schema.FaceEmbedResponse": { + "type": "object", + "properties": { + "dim": { + "type": "integer" + }, + "embedding": { + "type": "array", + "items": { + "type": "number" + } + }, + "model": { + "type": "string" + } + } + }, + "schema.FaceForgetRequest": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "model": { + "type": "string" + }, + "store": { + "type": "string" + } + } + }, + "schema.FaceIdentifyMatch": { + "type": "object", + "properties": { + "confidence": { + "type": "number" + }, + "distance": { + "type": "number" + }, + "id": { + "type": "string" + }, + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "match": { + "description": "true when distance \u003c= threshold", + "type": "boolean" + }, + "name": { + "type": "string" + } + } + }, + "schema.FaceIdentifyRequest": { + "type": "object", + "properties": { + "img": { + "type": "string" + }, + "model": { + "type": "string" + }, + "store": { + "type": "string" + }, + "threshold": { + "description": "optional cutoff on distance", + "type": "number" + }, + "top_k": { + "type": "integer" + } + } + }, + "schema.FaceIdentifyResponse": { + "type": "object", + "properties": { + "matches": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.FaceIdentifyMatch" + } + } + } + }, + "schema.FaceRegisterRequest": { + "type": "object", + "properties": { + "img": { + "type": "string" + }, + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "model": { + "type": "string" + }, + "name": { + "type": "string" + }, + "store": { + "description": "vector store model; empty = local-store default", + "type": "string" + } + } + }, + "schema.FaceRegisterResponse": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "registered_at": { + "type": "string" + } + } + }, + "schema.FaceVerifyRequest": { + "type": "object", + "properties": { + "anti_spoofing": { + "type": "boolean" + }, + "img1": { + "type": "string" + }, + "img2": { + "type": "string" + }, + "model": { + "type": "string" + }, + "threshold": { + "type": "number" + } + } + }, + "schema.FaceVerifyResponse": { + "type": "object", + "properties": { + "confidence": { + "type": "number" + }, + "distance": { + "type": "number" + }, + "img1_area": { + "$ref": "#/definitions/schema.FacialArea" + }, + "img2_area": { + "$ref": "#/definitions/schema.FacialArea" + }, + "model": { + "type": "string" + }, + "processing_time_ms": { + "type": "number" + }, + "threshold": { + "type": "number" + }, + "verified": { + "type": "boolean" + } + } + }, + "schema.FacialArea": { + "type": "object", + "properties": { + "h": { + "type": "number" + }, + "w": { + "type": "number" + }, + "x": { + "type": "number" + }, + "y": { + "type": "number" + } + } + }, "schema.FunctionCall": { "type": "object", "properties": { diff --git a/swagger/swagger.json b/swagger/swagger.json index 4aa7df7ab..471a3a659 100644 --- a/swagger/swagger.json +++ b/swagger/swagger.json @@ -1669,6 +1669,165 @@ } } }, + "/v1/face/analyze": { + "post": { + "tags": [ + "face-recognition" + ], + "summary": "Analyze demographic attributes (age, gender, ...) of faces.", + "parameters": [ + { + "description": "query params", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.FaceAnalyzeRequest" + } + } + ], + "responses": { + "200": { + "description": "Response", + "schema": { + "$ref": "#/definitions/schema.FaceAnalyzeResponse" + } + } + } + } + }, + "/v1/face/embed": { + "post": { + "tags": [ + "face-recognition" + ], + "summary": "Extract a face embedding from an image.", + "parameters": [ + { + "description": "query params", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.FaceEmbedRequest" + } + } + ], + "responses": { + "200": { + "description": "Response", + "schema": { + "$ref": "#/definitions/schema.FaceEmbedResponse" + } + } + } + } + }, + "/v1/face/forget": { + "post": { + "tags": [ + "face-recognition" + ], + "summary": "Remove a previously-registered face by ID.", + "parameters": [ + { + "description": "query params", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.FaceForgetRequest" + } + } + ], + "responses": { + "204": { + "description": "No Content" + } + } + } + }, + "/v1/face/identify": { + "post": { + "tags": [ + "face-recognition" + ], + "summary": "Identify a face against the registered database (1:N recognition).", + "parameters": [ + { + "description": "query params", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.FaceIdentifyRequest" + } + } + ], + "responses": { + "200": { + "description": "Response", + "schema": { + "$ref": "#/definitions/schema.FaceIdentifyResponse" + } + } + } + } + }, + "/v1/face/register": { + "post": { + "tags": [ + "face-recognition" + ], + "summary": "Register a face for 1:N identification.", + "parameters": [ + { + "description": "query params", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.FaceRegisterRequest" + } + } + ], + "responses": { + "200": { + "description": "Response", + "schema": { + "$ref": "#/definitions/schema.FaceRegisterResponse" + } + } + } + } + }, + "/v1/face/verify": { + "post": { + "tags": [ + "face-recognition" + ], + "summary": "Verify that two images depict the same person.", + "parameters": [ + { + "description": "query params", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.FaceVerifyRequest" + } + } + ], + "responses": { + "200": { + "description": "Response", + "schema": { + "$ref": "#/definitions/schema.FaceVerifyResponse" + } + } + } + } + }, "/v1/images/generations": { "post": { "tags": [ @@ -3066,6 +3225,293 @@ } } }, + "schema.FaceAnalysis": { + "type": "object", + "properties": { + "age": { + "type": "number" + }, + "antispoof_score": { + "type": "number" + }, + "dominant_emotion": { + "type": "string" + }, + "dominant_gender": { + "type": "string" + }, + "dominant_race": { + "type": "string" + }, + "emotion": { + "type": "object", + "additionalProperties": { + "type": "number", + "format": "float32" + } + }, + "face_confidence": { + "type": "number" + }, + "gender": { + "type": "object", + "additionalProperties": { + "type": "number", + "format": "float32" + } + }, + "is_real": { + "type": "boolean" + }, + "race": { + "type": "object", + "additionalProperties": { + "type": "number", + "format": "float32" + } + }, + "region": { + "$ref": "#/definitions/schema.FacialArea" + } + } + }, + "schema.FaceAnalyzeRequest": { + "type": "object", + "properties": { + "actions": { + "description": "subset of {\"age\",\"gender\",\"emotion\",\"race\"}", + "type": "array", + "items": { + "type": "string" + } + }, + "anti_spoofing": { + "type": "boolean" + }, + "img": { + "type": "string" + }, + "model": { + "type": "string" + } + } + }, + "schema.FaceAnalyzeResponse": { + "type": "object", + "properties": { + "faces": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.FaceAnalysis" + } + } + } + }, + "schema.FaceEmbedRequest": { + "type": "object", + "properties": { + "img": { + "type": "string" + }, + "model": { + "type": "string" + } + } + }, + "schema.FaceEmbedResponse": { + "type": "object", + "properties": { + "dim": { + "type": "integer" + }, + "embedding": { + "type": "array", + "items": { + "type": "number" + } + }, + "model": { + "type": "string" + } + } + }, + "schema.FaceForgetRequest": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "model": { + "type": "string" + }, + "store": { + "type": "string" + } + } + }, + "schema.FaceIdentifyMatch": { + "type": "object", + "properties": { + "confidence": { + "type": "number" + }, + "distance": { + "type": "number" + }, + "id": { + "type": "string" + }, + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "match": { + "description": "true when distance \u003c= threshold", + "type": "boolean" + }, + "name": { + "type": "string" + } + } + }, + "schema.FaceIdentifyRequest": { + "type": "object", + "properties": { + "img": { + "type": "string" + }, + "model": { + "type": "string" + }, + "store": { + "type": "string" + }, + "threshold": { + "description": "optional cutoff on distance", + "type": "number" + }, + "top_k": { + "type": "integer" + } + } + }, + "schema.FaceIdentifyResponse": { + "type": "object", + "properties": { + "matches": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.FaceIdentifyMatch" + } + } + } + }, + "schema.FaceRegisterRequest": { + "type": "object", + "properties": { + "img": { + "type": "string" + }, + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "model": { + "type": "string" + }, + "name": { + "type": "string" + }, + "store": { + "description": "vector store model; empty = local-store default", + "type": "string" + } + } + }, + "schema.FaceRegisterResponse": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "registered_at": { + "type": "string" + } + } + }, + "schema.FaceVerifyRequest": { + "type": "object", + "properties": { + "anti_spoofing": { + "type": "boolean" + }, + "img1": { + "type": "string" + }, + "img2": { + "type": "string" + }, + "model": { + "type": "string" + }, + "threshold": { + "type": "number" + } + } + }, + "schema.FaceVerifyResponse": { + "type": "object", + "properties": { + "confidence": { + "type": "number" + }, + "distance": { + "type": "number" + }, + "img1_area": { + "$ref": "#/definitions/schema.FacialArea" + }, + "img2_area": { + "$ref": "#/definitions/schema.FacialArea" + }, + "model": { + "type": "string" + }, + "processing_time_ms": { + "type": "number" + }, + "threshold": { + "type": "number" + }, + "verified": { + "type": "boolean" + } + } + }, + "schema.FacialArea": { + "type": "object", + "properties": { + "h": { + "type": "number" + }, + "w": { + "type": "number" + }, + "x": { + "type": "number" + }, + "y": { + "type": "number" + } + } + }, "schema.FunctionCall": { "type": "object", "properties": { diff --git a/swagger/swagger.yaml b/swagger/swagger.yaml index e46ce10c8..ce9206169 100644 --- a/swagger/swagger.yaml +++ b/swagger/swagger.yaml @@ -615,6 +615,195 @@ definitions: vocal_language: type: string type: object + schema.FaceAnalysis: + properties: + age: + type: number + antispoof_score: + type: number + dominant_emotion: + type: string + dominant_gender: + type: string + dominant_race: + type: string + emotion: + additionalProperties: + format: float32 + type: number + type: object + face_confidence: + type: number + gender: + additionalProperties: + format: float32 + type: number + type: object + is_real: + type: boolean + race: + additionalProperties: + format: float32 + type: number + type: object + region: + $ref: '#/definitions/schema.FacialArea' + type: object + schema.FaceAnalyzeRequest: + properties: + actions: + description: subset of {"age","gender","emotion","race"} + items: + type: string + type: array + anti_spoofing: + type: boolean + img: + type: string + model: + type: string + type: object + schema.FaceAnalyzeResponse: + properties: + faces: + items: + $ref: '#/definitions/schema.FaceAnalysis' + type: array + type: object + schema.FaceEmbedRequest: + properties: + img: + type: string + model: + type: string + type: object + schema.FaceEmbedResponse: + properties: + dim: + type: integer + embedding: + items: + type: number + type: array + model: + type: string + type: object + schema.FaceForgetRequest: + properties: + id: + type: string + model: + type: string + store: + type: string + type: object + schema.FaceIdentifyMatch: + properties: + confidence: + type: number + distance: + type: number + id: + type: string + labels: + additionalProperties: + type: string + type: object + match: + description: true when distance <= threshold + type: boolean + name: + type: string + type: object + schema.FaceIdentifyRequest: + properties: + img: + type: string + model: + type: string + store: + type: string + threshold: + description: optional cutoff on distance + type: number + top_k: + type: integer + type: object + schema.FaceIdentifyResponse: + properties: + matches: + items: + $ref: '#/definitions/schema.FaceIdentifyMatch' + type: array + type: object + schema.FaceRegisterRequest: + properties: + img: + type: string + labels: + additionalProperties: + type: string + type: object + model: + type: string + name: + type: string + store: + description: vector store model; empty = local-store default + type: string + type: object + schema.FaceRegisterResponse: + properties: + id: + type: string + name: + type: string + registered_at: + type: string + type: object + schema.FaceVerifyRequest: + properties: + anti_spoofing: + type: boolean + img1: + type: string + img2: + type: string + model: + type: string + threshold: + type: number + type: object + schema.FaceVerifyResponse: + properties: + confidence: + type: number + distance: + type: number + img1_area: + $ref: '#/definitions/schema.FacialArea' + img2_area: + $ref: '#/definitions/schema.FacialArea' + model: + type: string + processing_time_ms: + type: number + threshold: + type: number + verified: + type: boolean + type: object + schema.FacialArea: + properties: + h: + type: number + w: + type: number + x: + type: number + "y": + type: number + type: object schema.FunctionCall: properties: arguments: @@ -2822,6 +3011,106 @@ paths: by machine learning models and algorithms. tags: - embeddings + /v1/face/analyze: + post: + parameters: + - description: query params + in: body + name: request + required: true + schema: + $ref: '#/definitions/schema.FaceAnalyzeRequest' + responses: + "200": + description: Response + schema: + $ref: '#/definitions/schema.FaceAnalyzeResponse' + summary: Analyze demographic attributes (age, gender, ...) of faces. + tags: + - face-recognition + /v1/face/embed: + post: + parameters: + - description: query params + in: body + name: request + required: true + schema: + $ref: '#/definitions/schema.FaceEmbedRequest' + responses: + "200": + description: Response + schema: + $ref: '#/definitions/schema.FaceEmbedResponse' + summary: Extract a face embedding from an image. + tags: + - face-recognition + /v1/face/forget: + post: + parameters: + - description: query params + in: body + name: request + required: true + schema: + $ref: '#/definitions/schema.FaceForgetRequest' + responses: + "204": + description: No Content + summary: Remove a previously-registered face by ID. + tags: + - face-recognition + /v1/face/identify: + post: + parameters: + - description: query params + in: body + name: request + required: true + schema: + $ref: '#/definitions/schema.FaceIdentifyRequest' + responses: + "200": + description: Response + schema: + $ref: '#/definitions/schema.FaceIdentifyResponse' + summary: Identify a face against the registered database (1:N recognition). + tags: + - face-recognition + /v1/face/register: + post: + parameters: + - description: query params + in: body + name: request + required: true + schema: + $ref: '#/definitions/schema.FaceRegisterRequest' + responses: + "200": + description: Response + schema: + $ref: '#/definitions/schema.FaceRegisterResponse' + summary: Register a face for 1:N identification. + tags: + - face-recognition + /v1/face/verify: + post: + parameters: + - description: query params + in: body + name: request + required: true + schema: + $ref: '#/definitions/schema.FaceVerifyRequest' + responses: + "200": + description: Response + schema: + $ref: '#/definitions/schema.FaceVerifyResponse' + summary: Verify that two images depict the same person. + tags: + - face-recognition /v1/images/generations: post: parameters: