로고이미지
TOP

API 개발 가이드

얼굴 비식별화 API

얼굴 비식별화 API 란?

영상 내에 존재하는 얼굴 영역을 자동으로 검출하고 얼굴 영역 영상처리를 수행하여 개인 정보인 얼굴을 비식별화 처리를 하게 됩니다. 본 기술은 타인이 포함된 영상을 외부에 공유 시 개인 정보를 보호할 수 있는 목적으로 활용될 수 있으며, 모든 얼굴이 아닌 특정 얼굴을 제외한 비식별화 용도로 응용될 수 있습니다. 얼굴 비식별화 API는 HTTP 기반의 REST API 인터페이스로 JSON 포맷 기반의 입력 및 출력을 지원하며 ETRI에서 제공하는 API Key 인증을 통해 사용할 수 있는 Open API입니다.

API 호출 1일 허용량

기술명 API명 1일 허용량

얼굴 비식별화 API 사용하기

얼굴 비식별화 API는 REST API이며, 이미지 파일과 확장자를 HTTP 통신으로 ETRI Open API 서버에 전달하면 됩니다. 서버가 제공하는 REST API의 URI는 다음과 같으며 POST 방식으로 호출해야 합니다.

http://aiopen.etri.re.kr:8000/FaceDeID

HTTP 요청으로 사람속성 검출 분석을 요청할 때 사전 준비 사항에서 발급받은 API Key정보를 요청 본문에 포함시켜야 합니다. 다음은 HTTP 요청 메시지 예입니다.


[HTTP Request Header]
"Authorization" : "YOUR_ACCESS_KEY"

[HTTP Request Body]
{
    "request_id": "reserved field", 
    "argument": {
        "file": "BASE64_STRING_IMAGE",
        "type": "FUNCTION_TYPE"
    }
}

위와 같은 HTTP 요청을 ETRI Open API 서버로 전달하면 ETRI Open API 서버는 JSON 형태의 Text 데이터를 HTTP 응답 메시지로 반환합니다. 다음은 HTTP 응답 예제 입니다.


[HTTP Respone Header]
Access-Control-Allow-Origin:*
Connection:close
Content-Length:0
Content-Type:application/json; charset=UTF-8

[HTTP Respone Body]
{
    "request_id": "reserved field",
    "result": 0,
    "return_type": "com.google.gson.internal.LinkedTreeMap",
    "return_object": {얼굴 비식별화 결과 JSON}
}

구현 예제

  • JAVA
  • PHP
  • C++
  • Python
  • Node.js

JSON parsing을 위해 Gson 라이브러리를 사용하여 제공하고 있습니다. Gson 라이브러리에 대한 자세한 설명은 https://github.com/google/gson 에서 확인 하실 수 있습니다.


  import java.io.DataOutputStream;
  import java.io.IOException;
  import java.io.InputStream;
  import java.net.HttpURLConnection;
  import java.net.MalformedURLException;
  import java.net.URL;
  import java.util.HashMap;
  import java.util.Map;
  import java.nio.file.Files;
  import java.nio.file.Path;
  import java.nio.file.Paths;
  import java.util.Base64;
  
  import com.google.gson.Gson;
  
  public class Example {
  
    static public void main ( String[] args ) {
      String openApiURL = "http://aiopen.etri.re.kr:8000/FaceDeID";
      String accessKey = "YOUR_ACCESS_KEY";    // 발급받은 API Key
      String type = "1";     // 얼굴 비식별화 기능 "1"로 설정
      String file = "IMAGE_FILE_PATH";  	// 이미지 파일 경로
      String imageContents = "";
      Gson gson = new Gson();
  
      Map<String, Object> request = new HashMap<>();
      Map<String, String> argument = new HashMap<>();
  
      try {
        Path path = Paths.get(file);
        byte[] imageBytes = Files.readAllBytes(path);
        imageContents = Base64.getEncoder().encodeToString(imageBytes);
      } catch (IOException e) {
        e.printStackTrace();
      }
  
      argument.put("type", type);
      argument.put("file", imageContents);
  
      request.put("argument", argument);
  
      URL url;
      Integer responseCode = null;
      String responBody = null;
      try {
        url = new URL(openApiURL);
        HttpURLConnection con = (HttpURLConnection)url.openConnection();
        con.setRequestMethod("POST");
        con.setDoOutput(true);
        con.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
        con.setRequestProperty("Authorization", accessKey);
  
        DataOutputStream wr = new DataOutputStream(con.getOutputStream());
        wr.write(gson.toJson(request).getBytes("UTF-8"));
        wr.flush();
        wr.close();
  
        responseCode = con.getResponseCode();
        InputStream is = con.getInputStream();
        byte[] buffer = new byte[is.available()];
        int byteRead = is.read(buffer);
        responBody = new String(buffer);
  
        System.out.println("[responseCode] " + responseCode);
        System.out.println("[responBody]");
        System.out.println(responBody);
  
      } catch (MalformedURLException e) {
        e.printStackTrace();
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
  }
<?php
	$openApiURL = "http://aiopen.etri.re.kr:8000/FaceDeID";
	$accessKey = "YOUR_ACCESS_KEY";
	$type = "1";     // 얼굴 비식별화 기능 "1"로 설정
	$filePath = "IMAGE_FILE_PATH";
	$imageContents = base64_encode( file_get_contents($filePath ) );

	$request = array(	
		"argument" => array (
			"type" => $type,
			"file" => $imageContents
		)
	);

	try {
		$server_output = "";
		$ch = curl_init();
		$header = array(
			"Content-Type:application/json; charset=UTF-8",
			"Authorization":{$accessKey}
		);
		curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
		curl_setopt($ch, CURLOPT_URL, $openApiURL);
		curl_setopt($ch, CURLOPT_VERBOSE, true);
		
		curl_setopt($ch, CURLOPT_POST, 1);
		curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode ( $request) );

		$server_output = curl_exec ($ch);
		if($server_output === false) {
			echo "Error Number:".curl_errno($ch)."\n";
			echo "Error String:".curl_error($ch)."\n";
		}

		curl_close ($ch);
	} catch ( Exception $e ) {
		echo $e->getMessage ();
	}

	echo "result = " . var_dump($server_output);
?>

JSON parsing을 위해 jsoncpp 라이브러리를 사용하여 제공하고 있습니다. jsoncpp 라이브러리에 대한 자세한 설명은 https://github.com/open-source-parsers/jsoncpp 에서 확인 하실 수 있습니다.

HTTP 통신을 위해 curl 라이브러리를 사용하여 제공하고 있습니다. curl 라이브러리에 대한 자세한 설명은 https://curl.haxx.se/libcurl 에서 확인 하실 수 있습니다.

컴파일을 위해서는 아래와 같이 추가된 LIB에 대한 옵션을 추가해야 합니다.

g++ (c++파일명) (JSONCPP)/json/json.h (JSONCPP)/json/json-forwards.h (JSONCPP)/jsoncpp.cpp -I(CURL)/include -lcurl
  
#include <curl/curl.h>
#include <json/json.h>
#include <iostream>
#include <string>
#include <memory.h>
#include <fstream>
#include <math.h>


#define LENFRAME  800

using namespace std;

size_t writeDataFunc(void *ptr, size_t size, size_t nmemb, string stream);
string base64_encode(unsigned char const* , unsigned int len);

static const string base64_chars =
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        "abcdefghijklmnopqrstuvwxyz"
        "0123456789+/";
int main() {
  char* openApiURL = (char*)"http://aiopen.etri.re.kr:8000/FaceDeID";
  char* imageFilePath = (char*)"IMAGE_FILE_PATH";
  string accessKey = "YOUR_ACCESS_KEY";
  string type = "1";     // 얼굴 비식별화 기능 "1"로 설정

  Json::Value request;
  Json::Value argument;
  FILE* fp = fopen(imageFilePath, "rt" );
  unsigned char sbuf[LENFRAME];
  unsigned int nRead = 0;
  unsigned int nWrite = 0;

  unsigned char* imageBytes;
  unsigned char* newimageBytes;
  while ( 0 < ( nRead = fread( sbuf, sizeof( char ), LENFRAME, fp ) ) ) {
    newimageBytes = new unsigned char[nWrite + nRead];
    if ( 0 < nWrite ) {
      memcpy(newimageBytes, imageBytes, nWrite * sizeof(char));
    }
    memcpy(newimageBytes + nWrite, sbuf, nRead * sizeof(char));
    nWrite = nWrite + nRead;
    imageBytes = new unsigned char[nWrite];
    memcpy(imageBytes, newimageBytes, nWrite * sizeof(char));
  }
  fclose(fp);

  argument["type"] = type;
  argument["file"] = base64_encode( imageBytes , nWrite);

  request["argument"] = argument;

  CURL *curl;
  curl_slist* responseHeaders = NULL;
  curl = curl_easy_init();

  if( curl == NULL ) {
  } else {
                responseHeaders = curl_slist_append( responseHeaders , "Content-Type: application/json; charset=UTF-8" ) ;
                responseHeaders = curl_slist_append( responseHeaders , ("Authorization: " + accessKey).c_str() ) ; 
    string requestJson = request.toStyledString();
    long statusCode;
    string response;

    curl_easy_setopt(curl, CURLOPT_URL, openApiURL);
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, responseHeaders ) ;
    curl_easy_setopt(curl, CURLOPT_TIMEOUT, 60);
    curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, requestJson.c_str());
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeDataFunc);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);

    curl_easy_perform(curl);

    curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &statusCode);
    curl_easy_cleanup(curl);

    cout << "[responseCode] " << statusCode << endl;
    cout << "[responBody]" << endl;
    cout << response << endl;
  }

  return 0;
}

size_t writeDataFunc(void *ptr, size_t size, size_t nmemb, string stream) {
  size_t realsize = size * nmemb;
  string temp(static_cast<const char*>(ptr), realsize);
  stream.append(temp);
  return realsize;
}

string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) {
  string ret;
  int i = 0;
  int j = 0;
  unsigned char char_array_3[3];
  unsigned char char_array_4[4];

  while (in_len--) {
  char_array_3[i++] = *(bytes_to_encode++);
  if (i == 3) {
    char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
    char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
    char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
    char_array_4[3] = char_array_3[2] & 0x3f;

    for(i = 0; (i <4) ; i++)
      ret += base64_chars[char_array_4[i]];
    i = 0;
  }
}

  if (i) {
  for(j = i; j < 3; j++)
    char_array_3[j] = '\0';

  char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
  char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
  char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
  char_array_4[3] = char_array_3[2] & 0x3f;

  for (j = 0; (j < i + 1); j++)
    ret += base64_chars[char_array_4[j]];

  while((i++ < 3))
    ret += '=';
  }
  return ret;
    
}

python 3.0을 기준으로 작성되었습니다.

HTTP 통신을 위해 urllib3 라이브러리를 사용하여 제공하고 있습니다. Python 3.0 이하의 버전에서 예제를 실행하기 위해서는 별도로 urllib3의 설치가 필요합니다. 설치에 대한 설명은 https://pypi.python.org/pypi/urllib3 를 참고하시기 바랍니다. urllib3 라이브러리에 대한 자세한 설명은 https://urllib3.readthedocs.io/en/latest/ 에서 확인 하실 수 있습니다.

#-*- coding:utf-8 -*-
  import urllib3
  import json
  import base64
  openApiURL = "http://aiopen.etri.re.kr:8000/FaceDeID"
  accessKey = "YOUR_ACCESS_KEY"
  imageFilePath = "IMAGE_FILE_PATH"
  type = "1";     # 얼굴 비식별화 기능 "1"로 설정
  
  file = open(imageFilePath, "rb")
  imageContents = base64.b64encode(file.read()).decode("utf8")
  file.close()
  
  requestJson = {
    "argument": {
      "type": type,
      "file": imageContents
    }
  }
  
  http = urllib3.PoolManager()
  response = http.request(
    "POST",
    openApiURL,
    headers={"Content-Type": "application/json; charset=UTF-8","Authorization": accessKey},
    body=json.dumps(requestJson)
  )
  
  print("[responseCode] " + str(response.status))
  print("[responBody]")
  print(response.data)
var fs = require('fs');
var openApiURL = 'http://aiopen.etri.re.kr:8000/FaceDeID';
var accessKey = 'YOUR_ACCESS_KEY';
var type = '1';     // 얼굴 비식별화 기능 '1'로 설정
var imageFilePath = 'IMAGE_FILE_PATH';
var imageData;

var imageData = fs.readFileSync(imageFilePath);

var requestJson = {
	'argument': {
		'type': type,
		'file': imageData.toString('base64')
	}
};

var request = require('request');
var options = {
	url: openApiURL,
	body: JSON.stringify(requestJson),
	headers: {'Content-Type':'application/json','Authorization':access_key}
};
request.post(options, function (error, response, body) {
	console.log('responseCode = ' + response.statusCode);
	console.log('responseBody = ' + body);
});

얼굴 비식별화 API 레퍼런스

  • 요청 파라미터
  • 응답
  • 오류코드

얼굴 비식별화 API에 필요한 요청 본문에 다음과 같은 파라미터를 작성해야 합니다.


[HTTP Request Header] 
"Authorization" : "YOUR_ACCESS_KEY"

[HTTP Request Body]
{
    "argument": {
        "file": "YOUR_file",
        "type": "YOUR_type"
    }
}

다음은 파라미터에 대한 설명입니다.

Field 명 타입 필수 여부 설명
access_key String API 사용을 위해 ETRI에서 발급한 사용자 API Key
argument Object API 사용 요청 시 분석을 위해 전달할 내용
file String 얼굴 비식별화를 적용하고자 하는 이미지의 경로

 이미지 내 얼굴 크기가 20x20 픽셀 이하로 작게 나타나거나 얼굴의 회전 정도가 클 경우 또는 입력 영상의 해상도가 Full HD 이상일 경우 비식별화 결과가 불안정할 수 있습니다.

type String 비식별화 기능 타입 ( 얼굴 비식별화 타입 = "1" )

얼굴 비식별화 API는 요청된 입력 이미지에 대해 얼굴 비식별화를 수행한 결과를 JSON 형태의 Text 데이터로 반환합니다.

다음은 정상적인 요청 처리에 대한 HTTP 응답 예입니다.


[HTTP Respone Header]
Access-Control-Allow-Origin:*
Connection:close
Content-Length:50783
Content-Type:application/json; charset=UTF-8

[HTTP Respone Body]
{
    "request_id": "reserved field",
    "result": 0,
    "return_type": "com.google.gson.internal.LinkedTreeMap",
    "return_object": {얼굴 비식별화 결과 JSON}
}

다음은 오류가 발생한 요청 처리에 대한 HTTP 응답 예입니다.


[HTTP Respone Header]
Access-Control-Allow-Origin:*
Connection:close
Content-Length:0
Content-Type:application/json; charset=UTF-8

[HTTP Respone Body]
{
    "request_id": "reserved field",
    "result": -1,
    "reason": {오류 메시지}
}

분석된 결과는 다음과 같은 내용이 포함되어 있습니다.

구분 JSON Key 이름 설명
속성검출
기본정보
bbox 얼굴 비식별화를 위해 검출된 얼굴 영역의 bounding box 좌표
(예) bbox: [55, 45, 205, 232], [x좌표1, y좌표1, x좌표2, y좌표2]
conf 얼굴 영역 검출에 대한 신뢰도

얼굴 비식별화 검출이 제대로 이루어지지 않았을 경우에는 얼굴 비식별화 검출 결과 대신 오류 메시지가 반환됩니다.

JSON Key 오류 메시지 설명
error This file is not allowed file type 파일 타입(확장자)이 ‘jpg’, ‘jpeg’, ‘png’, ‘bmp’가 아닐 경우
This file is not image contents 파일 타입(확장자)은 맞지만 입력된 파일이 실제 이미지파일이 아닐 경우
This file has no faces 비식별화를 위한 얼굴이 검출되지 않은 경우

얼굴 비식별화 API의 오류 코드 목록은 다음과 같습니다.

http status code result reason 설명
403 -1 Empty Auth Header Authorization 헤더가 없는 경우
403 -1 Invalid Key KEY API 키가 없는 경우
403
-1 Blocked KEY API 키가 관리자에 의해서 차단된 경우
403
-1 Daily Limit Exceeded 일간 호출 제한에 걸린 경우
403
-1 Monthly Limit Exceeded
월간 호출 제한에 걸린 경우
403
-1 Yearly Limit Exceeded
연간 호출 제한에 걸린 경우
403
-1 Too Many Keys 같은 IP에서 여러 API 키가 사용된 경우
403
-1 Too Many IPs 하나의 API 키를 여러 IP 에서 사용한 경우
403
-1 Not Allowed IP API 호출 가능한 IP 가 아닌경우
(API 설정에서 허용된 IP가 아닌경우)
403
-1 Not Allowed Subpath 하위경로 접근 제한이 되어 있는 경우
403 -1 Invalid API
등록되지 않은 API를 요청한 경우
408 -1
Request Timeout
서버의 요청 대기가 시간을 초과한 경우
413
-1 Body Size Limit Exceeded
요청 바디가 설정된 값보다 큰 경우
429
-1 Concurrent Limit Exceeded
연속호출 허용 범위를 넘어서 호출한 경우
500 -1 Internal Server Error 내부 오류 발생한 경우