Face tagging services is a collection of APIs that allow you to build photo sharing services where you can find your registered persons among uploaded photos easily. It is full serverless services built using Azure functions, CosmosDB, Azure Blob Storage for backend.
Table of Contents
- Train faces of a person
- Uploading photos
- Identify faces of a person in uploaded photos
- Management APIs for Users, Assets, Persons, and Photos
Data flows of major operations
Azure functions proxies: URI path and function mapping
Concept of user, person, and asset in facetag_services
Operation | Example |
---|---|
1. Register user using Regist User API (Only if not yet registerd user) | Regist a user with user_id "nogizaka46" |
2. Create a person for the user using Create Person API. The API response contains person_id and asset_id_for_train . You'll use person_id for identifying the person, and asset_id_for_train for uploading photos of the person in order to train the face of the person. So please don't forget to get both info! |
Create a person named "Mai Shiraishi", and get "063aa8ac-c9b3-4969-952f-26388ab67726" for person_id and "c4baf03e-1eb0-4dde-b0e6-b1d68e1f5df3" for asset_id_for_train |
3. Upload photos of the person to the prepared container ( container name == asset_id_for_train ) in Azure blob storage |
Upload photos of a person "Mai Shiraishi" to the container named "c4baf03e-1eb0-4dde-b0e6-b1d68e1f5df3" (= asset_id_for_train , the one you got previously) |
4. Trigger training of the person's face using Trigger Train API. The training will be done asynchronously as a backgroud job | Trigger the training of a person "Mai Shiraishi" (person_id : "063aa8ac-c9b3-4969-952f-26388ab67726")'s faces |
Operation | Example |
---|---|
1. Create an asset for a certain category of photos that you want to upload using Create Asset API. The API response contains asset_id for the created asset. You'll use the asset_id for uploading photos of a certain category |
Create an asset named "Album 2019" and you'll get an asset_id "52edcedb-f4c8-4ef5-8e16-9b56ab28346b" for the asset. |
2. Upload photos of the certain cateogry to the prepared container ( container name == asset_id) in Azure blob storage. As soon as the photos are uploaded, event-driven functions are triggerred to run in order to detect, identify, and tag faces of the persons that you created/trained. Identified face info is stored persistently in backend databases. |
Add API Key for functions in HTTP header in REST API requests
x-functions-key: {API_KEY}
Example request for getperson API:
API_KEY="abcdefgxxxxxxxxxyyyyyyyyzzzzzzzz******=="
curl -s \
-H "Content-Type: application/json"\
-H "x-functions-key: ${API_KEY}"\
-XPOST https://myfacetagsvc.azurewebsites.net/person -d'
{
"person_name": "Mai Shiaishi"
}'
Regist a user
POST /user
Request
Name | Type | Requred | Description |
---|---|---|---|
user_id |
string | Yes | User ID. It has to be unique across the whole service. Only allow only alphanumeric and underscore in user_id. |
user_name |
string | Name of User |
Example Body
{
"user_id": "nogizaka46",
"user_name": "Nogizaka 46 Group"
}
Response
Status: 200 OK
<user_id>
Delete a user
DELETE /user/{user_id}
Response
Status: 200 OK
<user_id>
Create a new person for a user. A created person ID will be returned as reseponse body.
POST /user/{user_id}/person
Request
Name | Type | Requred | Description |
---|---|---|---|
person_name |
string | Name of Person |
Example Body
{
"person_name": "Mai Shiraishi"
}
Response
Status: 200 OK
{
"person_id": "063aa8ac-c9b3-4969-952f-26388ab67726",
"person_name": "Mai Shiraishi",
"asset_id_for_train": "c4baf03e-1eb0-4dde-b0e6-b1d68e1f5df3"
}
Delete person from a person group of a user
DELETE /api/deleteperson?user_id={user_id}&person_id={person_id} Response
Status: 200 OK
<deleted_person_id>
Get the list of persons for a user
GET /user/{user_id}/persons
Response
Status: 200 OK
[
{
"person_id": "a654f4c2-dc7d-43dc-a95a-8819da69587a",
"person_name": "Mai Shiraishi",
"asset_id_for_train": "4119ad84-2e9d-463e-8c66-1f049fa4afc1"
},
{
"person_id": "3dad91b4-fa4c-4c11-b9c0-e240a579c253",
"person_name": "Erika Ikuta",
"asset_id_for_train": "ef57792e-ec97-4584-8090-7d2f3eb680cd"
},
{
"person_id": "25eba549-fa9e-493d-a754-af2eb1aff735",
"person_name": "Manatsu Akimoto",
"asset_id_for_train": "b89387bf-5a0e-48a2-bf58-49b6f1f78982"
},
...
]
Create an asset of a user
Create a new asset for a user. A created asset ID will be returned as reseponse body.
POST /user/{user_id}/asset
Request
Name | Type | Requred | Description |
---|---|---|---|
asset_name |
string | Name of asset |
Example Body
{
"asset_name": "Album 2019"
}
Response
Status: 200 OK
<created_asset_id>
Delete an asset of a user
DELETE /api/deleteasset?user_id={user_id}&asset_id={asset_id}
Response
Status: 200 OK
<deleted_asset_id>
Get the list of assets of a user
GET /user/{user_id}/assets
Response
Status: 200 OK
[
{
"asset_id": "5x472930-x3c6-55df-93x2-z9900a2b2300",
"asset_name": "Album 2017",
"user_id": "nogizaka46"
},
{
"asset_id": "2d447b84-e2c4-4eed-93b6-e6600a2b5608",
"asset_name": "Album 2018",
"user_id": "nogizaka46"
},
{
"asset_id": "2b48152d-02b1-443f-9617-eaa499fb0a93",
"asset_name": "Album 2019",
"user_id": "nogizaka46"
},
...
]
Get the list of photos of a user. You can filter photos by a Person ID, Asset ID, and a User ID.
POST /photos
Request
Name | Type | Requred | Description |
---|---|---|---|
user_id |
string | Yes | User ID |
person_id |
string | Person ID | |
asset_id |
string | Asset ID | |
order |
string | ASC or DESC (default) | |
offset |
number | Offset position of result items(Default 0) | |
limit |
number | limit number of result items (Default 100) |
Example 1: Get photos of a person in a user group (user_id + person_id)
{
"user_id": "nogizaka46",
"person_id": "a654f4c2-dc7d-43dc-a95a-8819da69587a",
"order": "DESC",
"offset": "0",
"limit": "50"
}
Example 2: Get photos stored in a asset (user_id + asset_id)
{
"user_id": "nogizaka46",
"person_id": "a654f4c2-dc7d-43dc-a95a-8819da69587a",
"order": "DESC",
"offset": "0",
"limit": "50"
}
Example 3: Get photos in a user group (user_id)
{
"user_id": "nogizaka46",
"order": "DESC",
"offset": "0",
"limit": "50"
}
Response
Status: 200 OK
[
{
"photo_id": "114a2d4a36340e0726e1079145d8e8c6794b8b7541c334edae997691248b01e7",
"asset_id": "2d447b84-e2c4-4eed-93b6-e6600a2b5608",
"blob_name": "mai-shiraishi-0.jpg",
"user_id": "nogizaka46",
"persons": [
{
"person_id": "a654f4c2-dc7d-43dc-a95a-8819da69587a"
}
],
"blob_url": "https://facetagservice.blob.core.windows.net/ef57792e-ec97-4584-8090-7d2f3eb680cd/mai-shiraishi-0.jpg?sv=2018-03-28&ss=b&srt=o&sp=rl&se=2019-10-12T08%3A01%3A53Z&st=2019-10-12T06%3A56%3A53Z&spr=https&sig=%2FrxQ7P3UlasoXqk9mfIgr0uRBQQQPmmKhvKJN%2Bteisc%3D",
"last_updated": 1569808309
},
{
"photo_id": "4369e41be321894298ed3188f715dc4f14a8ae51d1bcd1dcd21c2dc2ce162af9",
"asset_id": "2d447b84-e2c4-4eed-93b6-e6600a2b5608",
"blob_name": "mai-shiraishi-1.jpg",
"user_id": "nogizaka46",
"persons": [
{
"person_id": "a654f4c2-dc7d-43dc-a95a-8819da69587a"
}
],
"blob_url": "https://facetagservice.blob.core.windows.net/ef57792e-ec97-4584-8090-7d2f3eb680cd/mai-shiraishi-1.jpg?sv=2018-03-28&ss=b&srt=o&sp=rl&se=2019-10-12T08%3A01%3A53Z&st=2019-10-12T06%3A56%3A53Z&spr=https&sig=%2FrxQ7P3UlasoXqk9mfIgr0uRBQQQPmmKhvKJN%2Bteisc%3D",
"last_updated": 1569808315
},
{
"photo_id": "0321b08d15c1065569b0bcda5bc726ea9473b3107f78d15c323b0bf621add9f4",
"asset_id": "2d447b84-e2c4-4eed-93b6-e6600a2b5608",
"blob_name": "nobody-0.jpg",
"user_id": "nogizaka46",
"persons": [],
"blob_url": "https://facetagservice.blob.core.windows.net/ef57792e-ec97-4584-8090-7d2f3eb680cd/nobody-0.jpg?sv=2018-03-28&ss=b&srt=o&sp=rl&se=2019-10-12T08%3A01%3A53Z&st=2019-10-12T06%3A56%3A53Z&spr=https&sig=%2FrxQ7P3UlasoXqk9mfIgr0uRBQQQPmmKhvKJN%2Bteisc%3D",
"last_updated": 1569808340
}
...
]
Trigger training of a person's faces
PUT /user/{user_id}/person/{person_id}/trigger
Request
Name | Type | Requred | Description |
---|---|---|---|
user_id |
string | Yes | User ID |
person_id |
string | Yes | Person ID |
Response
Status: 200 OK
Get a SAS token for Azure Storage for the specified container and blob name. You can also specify access permissions for the container/blob name and optionally its token time-to-live period. The SAS token expires in an hour by default.
POST /blobsastoken
Request
Name | Type | Requred | Description |
---|---|---|---|
permission |
string | Yes | Signed permission for shared access signature. See Note below for the detai) |
container |
string | Yes | Container name to access |
blobname |
string | Blob object name to access | |
ttl |
string | Token time to live period in hours. 1hour by default |
NOTE for permission param:
- The following values can be used for permissions:
a
(Add),r
(Read),w
(Write),d
(Delete),l
(List)- Concatenate multiple permissions, such as
rwa
= Read, Write, Add
Sample Request Body
{
'permission': "rl",
'container': "functions",
'blobname': "yokawasa.png"
}
Response Response body format
HTTP response body format is:
{
'token': '<Shared Access Signature Token string>',
'url' : '<SAS resource URI>'
}
Sample Response Body
{
"token": "sv=2018-03-28&ss=b&srt=o&sp=rl&se=2019-03-29T14%3A02%3A37Z&st=2019-03-29T11%3A57%3A37Z&spr=https&sig=Sh7RAa5MZBk7gfv0haCbEbllFXoiOWJDK9itzPeqURE%3D",
"url": "https://azfuncv2linuxstore.blob.core.windows.net/functiontest/sample.jpg?sv=2018-03-28&ss=b&srt=o&sp=rl&se=2019-03-29T14%3A02%3A37Z&st=2019-03-29T11%3A57%3A37Z&spr=https&sig=Sh7RAa5MZBk7gfv0haCbEbllFXoiOWJDK9itzPeqURE%3D"
}