facelandmarkshttps://api.pixlab.io/facelandmarks
Description
Output the rectangle & landmarks coordinates for each detected human face in a given image. A plenty of useful endpoints can be mixed with the face landmarks endpoint such as crop for face extraction, drawrectangles for marking faces, mogrify for censoring and finally merge which can be used in combination in order to mimic the Snapchat filters effects (refer to the sample set for a concrete example).
HTTP Methods
GET, POST
Request Parameters
Required
Fields | Type | Description |
---|---|---|
img | URL | Input media URL. If you want to upload your image directly from your app, then submit a multipart/form-data POST request. |
key | String | Your PixLab API Key. You can also embed your key in the WWW-Authenticate: HTTP header and omit this parameter if you want to. |
POST Request Body (If you plan to use POST instead of a simple GET request)
Allowed Content-Type:
multipart/form-data
application/json
Use multipart/form-data if you want to upload your media file directly (refer to the sample set for a working example). If you are using JSON, then the media file must be already uploaded somewhere. Call store if you want to upload an image for example before invoking this endpoint.
Response
application/json.
This command always return a JSON object after each call. The field of interest here is the faces array which hold the rectangle & landmarks coordinates for each detected face. The following are the JSON fields returned in response body:
Fields | Type | Description |
---|---|---|
status | Integer | Status code 200 indicates success, any other code indicates failure. |
faces | Array | JSON array holding the rectangle & landmarks coordinates (See below for fields). |
error | String | Error message if status != 200. |
The following are the object fields returned for each detected face in the faces array defined above:
Fields | Type | Description |
---|---|---|
rectangle | Array | JSON array holding the rectangle coordinates for this face (See below). |
landmarks | Array | JSON array holding the landmarks coordinates for this face (See below). |
The following are the object fields returned in each rectangle array, member of the faces array defined above:
Fields | Type | Description |
---|---|---|
face_id | Integer | Detected face ID. |
left | Integer | Rectangle left coordinate: X. |
top | Integer | Rectangle top coordinate: Y. |
width | Integer | Rectangle width. |
height | Integer | Rectangle height. |
The following are the object fields returned in each landmarks array, member of the faces array defined above:
Fields | Type | Description |
---|---|---|
nose | Array | Nose coordinates for this face in the form [x: Integer, y: Integer]. |
mouth_left | Array | left most coordinates of the mouth for this face in the form [x: Integer, y: Integer]. |
mouth_right | Array | Right most coordinates of the mouth for this face in the form [x: Integer, y: Integer]. |
bottom_lip | Array | Bottom Lip coordinates for this face in the form [x: Integer, y: Integer]. |
top_lip | Array | Top Lip coordinates for this face in the form [x: Integer, y: Integer]. |
chin | Array | Chin coordinates for this face in the form [x: Integer, y: Integer]. |
eye | Array | Array holding the coordinates of the region surrounding the eyes. These includes:
|
bone | Array | Array holding the coordinates of some regions of the bone. These includes:
|
- For additional processing, feel free to adjust these coordinates for the next command such as crop for face extraction, drawrectangles for marking faces, mogrify and merge to mimic the Snapchat filters effects (refer to the sample set for a concrete example).
- If you need additional landmarks coordinates, please fill an API feature request ticket from the support tab of your dashboard.
Python Example
import requests
import json
# Mimic the two famous Snapchat filters: The flower crown & the dog parts filter.
# The target image must contain at least one human face. The more faces you got, the more funny it should be!
#
# Only three commands are actually needed in order to mimic the Snapchat filters:
# face landmarks: https://pixlab.io/cmd?id=facelandmarks
# smart resize: https://pixlab.io/cmd?id=smartresize
# merge: https://pixlab.io/cmd?id=merge
# rotate (Optionally): https://pixlab.io/cmd?id=rotate
# meme (Optionally): https://pixlab.io/cmd?id=meme Draw some funny text
# Optionally: blur, grayscale, oilpaint, etc. for cool background effects.
# Target image to composite stuff on. Must contain at least one face.
img = 'https://trekkerscrapbook.files.wordpress.com/2013/09/face-08.jpg'
# The flower crown.
flower = 'http://pixlab.xyz/images/flower_crown.png'
# The dog parts: Left & right ears, nose & optionally the tongue
dog_left_ear = 'http://pixlab.xyz/images/dog_left_ear.png'
dog_right_ear = 'http://pixlab.xyz/images/dog_right_ear.png'
dog_nose = 'http://pixlab.xyz/images/dog_nose.png'
dog_tongue = 'http://pixlab.xyz/images/dog_tongue.png'
# Your PixLab API key
key = 'My_Pix_Key'
# If set to True then composite the flower crown. Otherwise, composite the dog stuff.
draw_crown = False
# Resize an image (Dog parts or the flower crown) to fit the face dimension using smartresize.
def smart_resize(img,width,height):
print ("Resizing images...")
req = requests.get('https://api.pixlab.io/smartresize',params={
'img':img,
'key':key,
'width': width,
'height': height
})
reply = req.json()
if reply['status'] != 200:
print (reply['error'])
exit()
else:
return reply['link'] # Resized image
# First step, Detect & extract the landmarks for each human face present in the image.
req = requests.get('https://api.pixlab.io/facelandmarks',params={
'img': img,
'key': key,
})
reply = req.json()
if reply['status'] != 200:
print (reply['error'])
exit();
total = len(reply['faces']) # Total detected faces
if total < 1:
print ("No faces were detected..exiting")
exit()
print(str(total)+" faces were detected")
# This list contain all the coordinates of the regions where the flower crown or the dog parts should be
# Composited on top of the target image later using the `merge` command.
coordinates = []
# Iterate all over the detected faces and make our stuff
for face in reply['faces']:
# Show the face coordinates
print ("Coordinates...")
cord = face['rectangle']
print ('\twidth: ' + str(cord['width']) + ' height: ' + str(cord['height']) + ' x: ' + str(cord['left']) +' y: ' + str(cord['top']))
# Show landmarks of interest:
print ("Landmarks...")
landmarks = face['landmarks']
print ("\tNose: X: " + str(landmarks['nose']['x'] ) + ", Y: "+str(landmarks['nose']['y']))
print ("\tBottom Lip: X: " + str(landmarks['bottom_lip']['x'])+ ", Y: "+str(landmarks['bottom_lip']['y']))
print ("\tTop Lip: X: " + str(landmarks['top_lip']['x']) + ", Y: "+str(landmarks['top_lip']['y']))
print ("\tChin: X: " + str(landmarks['chin']['x']) + ", Y: "+str(landmarks['chin']['y']))
print ("\tMouth Left: X: " + str(landmarks['mouth_left']['x']) + ", Y: "+str(landmarks['mouth_left']['y']))
print ("\tMouth Right: X: " + str(landmarks['mouth_right']['x']) + ", Y: "+str(landmarks['mouth_right']['y']))
print ("\tBone Center: X: " + str(landmarks['bone']['center']['x']) + ", Y: "+str(landmarks['bone']['center']['y']))
print ("\tBone Outer Left: X: " + str(landmarks['bone']['outer_left']['x']) + ", Y: "+str(landmarks['bone']['outer_left']['y']))
print ("\tBone Outer Right: X: "+ str(landmarks['bone']['outer_right']['x'])+ ", Y: "+str(landmarks['bone']['outer_right']['y']))
print ("\tBone Center: X: " + str(landmarks['bone']['center']['x']) + ", Y: "+str(landmarks['bone']['center']['y']))
print ("\tEye Pupil Left: X: " + str(landmarks['eye']['pupil_left']['x']) + ", Y: "+str(landmarks['eye']['pupil_left']['y']))
print ("\tEye Pupil Right: X: " + str(landmarks['eye']['pupil_right']['x']) + ", Y: "+str(landmarks['eye']['pupil_right']['y']))
print ("\tEye Left Brown Inner: X: " + str(landmarks['eye']['left_brow_inner']['x']) + ", Y: "+str(landmarks['eye']['left_brow_inner']['y']))
print ("\tEye Right Brown Inner: X: " + str(landmarks['eye']['right_brow_inner']['x']) + ", Y: "+str(landmarks['eye']['right_brow_inner']['y']))
print ("\tEye Left Outer: X: " + str(landmarks['eye']['left_outer']['x']) + ", Y: "+str(landmarks['eye']['left_outer']['y']))
print ("\tEye Right Outer: X: " + str(landmarks['eye']['right_outer']['x']) + ", Y: "+str(landmarks['eye']['right_outer']['y']))
draw_crown = not draw_crown
if draw_crown:
# Resize the flower crown to fit the face width
fit_crown = smart_resize(
flower,
20 + cord['width'], # Face width
0 # Let Pixlab decide the best height for this picture
)
# Composite the flower crown on top of the bone most left region.
print ("\tCrown flower at: X: " + str(landmarks['bone']['outer_left']['x']) + ", Y: "+str(landmarks['bone']['outer_left']['y']))
coordinates.append({
'img': fit_crown, # The resized flower crown
'x': landmarks['bone']['outer_left']['x'],
'y': landmarks['bone']['outer_left']['y']
})
else:
# Do the dog parts using the bone left & right regions and the nose coordinates.
print ("\tDog Parts Regions...")
coordinates.append({
'img': smart_resize(dog_left_ear, cord['width']/2,cord['height']/2),
'x': landmarks['bone']['outer_left']['x'], # Adjust to get optimal effect
'y': landmarks['bone']['outer_left']['y'] # Adjust to get optimal effect
})
coordinates.append({
'img': smart_resize(dog_right_ear, cord['width']/2,cord['height']/2),
'x': landmarks['bone']['outer_right']['x'], # Adjust to get optimal effect
'y': landmarks['bone']['outer_right']['y'] # Adjust to get optimal effect
})
coordinates.append({
'img': smart_resize(dog_nose, cord['width']/2,cord['height']/2),
'x': landmarks['nose']['x'] - 18, # Adjust to get optimal effect
'y': landmarks['nose']['y'] - 10 # Adjust to get optimal effect
})
# Finally, Perform the composite operation when we exit the loop
print ("Composite operation...")
req = requests.post('https://api.pixlab.io/merge',
headers={'Content-Type':'application/json'},
data=json.dumps({
'src':img, # The target image.
'key':key,
'cord': coordinates # The coordinates list filled earlier with the resized images (flower crown & dog members) and the regions of interest
})
)
reply = req.json()
if reply['status'] != 200:
print (reply['error'])
else:
# Optionally call blur, oilpaint, grayscale for cool background effects..
print ("Snap Filter Effect: "+ reply['link'])
See Also
header, nsfw, sfw, ocr, crop, imgdiff, grayscale, drawrectangles, mogrify, meme, tagimg, facecompare, facelookup, screencapture, merge, smartresize, composite