Created
December 8, 2016 14:15
-
-
Save alexanderk23/8cde2992d53951c51cc67651c5e2a4ab to your computer and use it in GitHub Desktop.
FindFace API example (PHP)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
define('DATEFMT', 'Y-m-d\TH:i:s.u'); | |
/* Bounded box from "Common objects" */ | |
class BBox { | |
var $x1, $y1, $x2, $y2; | |
function __construct($x1, $y1, $x2, $y2) { | |
$this->x1 = $x1; | |
$this->y1 = $y1; | |
$this->x2 = $x2; | |
$this->y2 = $y2; | |
} | |
/* from JSON object or array */ | |
static function fromJSON($json) { | |
if (is_array($json)) { | |
return new BBox($json[0], $json[1], $json[2], $json[3]); | |
} else if (is_object($json)) { | |
return new BBox($json->x1, $json->y1, $json->x2, $json->y2); | |
} | |
} | |
function toJSON() { | |
return array("x1" => $this->x1, "y1" => $this->y1, | |
"x2" => $this->x2, "y2" => $this->y2); | |
} | |
} | |
/* Face from "Common objects" */ | |
class Face { | |
var $id, $timestamp, $photo, $photo_hash, $bbox, $meta, $galleries; | |
static function fromJSON($json) { | |
$face = new Face(); | |
foreach (array('id', 'timestamp', 'photo', 'photo_hash', 'meta', 'galleries') as $f) { | |
$face->{$f} = $json->{$f}; | |
} | |
$face->timestamp = DateTime::createFromFormat(DATEFMT, $json->timestamp); | |
$face->bbox = BBox::fromJSON($json); | |
return $face; | |
} | |
} | |
/* FacenAPI wrapper */ | |
class FacenAPI { | |
private $base_url, $token; | |
private $ch; | |
private function do_post($method, $rq) { | |
$body = json_encode($rq); | |
curl_reset($this->ch); | |
curl_setopt($this->ch, CURLOPT_POST, true); | |
curl_setopt($this->ch, CURLOPT_URL, $this->base_url . $method); | |
curl_setopt($this->ch, CURLOPT_POSTFIELDS, $body); | |
curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, true); | |
curl_setopt($this->ch, CURLOPT_HTTPHEADER, array( | |
'Content-Type: application/json', | |
'Authorization: Token ' . $this->token, | |
'Content-Length: ' . strlen($body))); | |
$result = curl_exec($this->ch); | |
$status = curl_getinfo($this->ch, CURLINFO_HTTP_CODE); | |
$response = json_decode($result); | |
if ((int)($status / 100) == 2) | |
return $response; | |
if ($response && property_exists($response, 'reason')) { | |
throw new Exception($response->code . ': ' . $response->reason); | |
} elseif ($status == 403) { | |
throw new Exception('AUTH error'); | |
} elseif ($status == 400) { | |
throw new Exception('BAD request'); | |
} | |
throw new Exception('BAD facenapi response code: ' . $status); | |
} | |
function __construct($base_url, $token) { | |
$this->base_url = $base_url; | |
$this->token = $token; | |
$this->ch = curl_init(); | |
} | |
/* Detect faces found on image */ | |
function detect($photo_url, $bbox = NULL) { | |
$rq = array("photo" => $photo_url); | |
if ($bbox) { | |
if (is_array($bbox)) { | |
if (count($bbox) != 4) { | |
throw new Exception('Invalid bbox size (' . count($bbox) . ')'); | |
} | |
$rq['bbox'] = $bbox; | |
} else { | |
$rq['bbox'] = $bbox->toJSON(); | |
} | |
} | |
$r = $this->do_post('/v0/detect', $rq); | |
$faces = array(); | |
foreach ($r->faces as $box) { | |
$faces[] = BBox::fromJSON($box); | |
} | |
return $faces; | |
} | |
/* Check similarity of two faces | |
* @param optvars is an associative array with the following keys: | |
* "threshold" => float or string | |
* "mf_selector" => string | |
* limitations: bbox input parameter is not supported | |
*/ | |
function verify($url1, $url2, $optvars = NULL) { | |
$rq = array("photo1" => $url1, "photo2" => $url2); | |
if (is_array($optvars)) { | |
$rq = array_merge($rq, | |
array_intersect_key($optvars, | |
array("threshold" => 0, "mf_selector" => 0))); | |
} | |
$rs = $this->do_post('/v0/verify', $rq); | |
$out = array(); | |
foreach ($rs->results as $r) { | |
$out[] = (object)array("bbox1" => BBox::fromJSON($r->bbox1), | |
"bbox2" => BBox::fromJSON($r->bbox2), | |
"confidence" => (float)$r->confidence); | |
} | |
return $out; | |
} | |
/* Returns array of identified faces: | |
* [ { box: $src_match, matches: [ {confidence: $confidence, face: Face_Object} ] } | |
* limitations: bbox input parameter is not supported | |
*/ | |
function identify($photo_url, $n = 1, $optvars = NULL) { | |
$rq = array("photo" => $photo_url, "n" => $n); | |
if (is_array($optvars)) { | |
$rq = array_merge($rq, | |
array_intersect_key($optvars, | |
array("threshold" => 0, "mf_selector" => 0))); | |
} | |
$rs = $this->do_post('/v0/identify', $rq); | |
$out = array(); | |
foreach ($rs->results as $b => $faces) { // iterate over all boxes | |
$box = BBox::fromJSON(json_decode($b)); | |
$matched = array(); | |
foreach ($faces as $f) { | |
$matched[] = (object)array("confidence" => $f->confidence, "face" => Face::fromJSON($f->face)); | |
} | |
$out[] = (object)array("box" => $box, "matches" => $matched); | |
} | |
return $out; | |
} | |
/* Enroll photo to the server | |
* Returns array of enrolled faces | |
*/ | |
function enroll($photo_url, $optvars = NULL) { | |
$rq = array("photo" => $photo_url); | |
if (is_array($optvars)) { | |
$rq = array_merge($rq, | |
array_intersect_key($optvars, | |
array("mf_selector" => 0))); | |
} | |
print_r($rq); | |
$rs = $this->do_post('/v0/face', $rq); | |
$out = array(); | |
foreach ($rs->results as $face) { // iterate over all faces | |
$out[] = Face::fromJSON($face); | |
} | |
return $out; | |
} | |
} | |
$api = new FacenAPI('https://api.findface.pro', 'YOUR_API_TOKEN'); | |
$photos = array( | |
"http://static.findface.pro/sample.jpg", | |
"http://static.findface.pro/sample2.jpg" | |
// ... | |
); | |
// enrolls each of your photo URIs to the server | |
foreach($photos as $photo) { | |
$faces = $api->enroll($photo); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment