이미지에서 얼굴 감지하기

등록일시: 2017-12-07 08:00,  수정일시: 2017-12-07 08:00
조회수: 4,112
이 문서는 Cognitive Services 기술을 널리 알리고자 하는 개인적인 취지로 제공되는 번역문서입니다. 이 문서에 대한 모든 저작권은 마이크로소프트에 있으며 요청이 있을 경우 언제라도 게시가 중단될 수 있습니다. 번역 내용에 오역이 존재할 수 있고 주석은 번역자 개인의 의견일 뿐이며 마이크로소프트는 이에 관한 어떠한 보장도 하지 않습니다. 번역이 완료된 이후에도 대상 제품 및 기술이 개선되거나 변경됨에 따라 원문의 내용도 변경되거나 보완되었을 수 있으므로 주의하시기 바랍니다.
본문에서는 이미지에서 얼굴을 감지하는 방법을 살펴봅니다.

본문에서는 이미지에서 얼굴을 감지하는 방법을 살펴봅니다. 이때 성별이나 나이 또는 자세 같은 얼굴 특징들을 함께 추출합니다. 본문의 예제는 Face API 클라이언트 라이브러리를 사용해서 C#으로 작성되었습니다.

개념

만약 본문에서 사용되는 다음의 개념들에 익숙하지 않다면, 언제든지 용어집의 정의를 참조하시기 바랍니다:

  • 얼굴 감지 (Face Detection)
  • 얼굴 랜드마크 (Face Landmarks)
  • 머리 자세 (Head Pose)
  • 얼굴 특징 (Face Attributes)

준비

본문의 예제에서는 다음과 같은 기능들을 살펴봅니다:

  • 이미지에서 얼굴을 감지하고 직사각형 프레임으로 표시하기
  • 눈동자, 코 또는 입의 위치를 분석하고 이미지에 표시하기
  • 얼굴의 머리 자세, 성별 및 나이 분석하기

이 기능들을 실행하려면 한 명 이상의 깨끗한 얼굴이 담긴 이미지가 필요합니다.

단계 1: API 호출 권한 부여하기

Face API를 호출할 때마다 구독 키가 필요합니다. 구독 키는 쿼리 문자열 매개 변수를 통해서 전달하거나 요청 헤더에 지정해야 합니다. 쿼리 문자열을 통해서 구독 키를 전달하는 방법은 Face - Detect API에 대한 다음의 요청 URL 사례를 참고하시기 바랍니다:

https://westus.api.cognitive.microsoft.com/face/v1.0/detect[?returnFaceId][&returnFaceLandmarks][&returnFaceAttributes]&subscription-key=<Your subscription key>

또는 HTTP 요청 헤더에 ocp-apim-subscription-key: <Your subscription key>와 같은 형태로 구독 키를 지정할 수도 있습니다. 클라이언트 라이브러리를 사용하는 경우에는 다음과 같이 FaceServiceClient 클래스의 생성자를 통해서 구독 키를 전달합니다:

faceServiceClient = new FaceServiceClient("Your subscription key");

단계 2: 이미지를 서비스에 업로드하고 얼굴 감지 수행하기

얼굴 감지를 수행하는 가장 기본적인 방법은 직접 이미지를 업로드하는 것입니다. 이 작업은 JPEG 이미지에서 읽어온 데이터를 application/octet-stream 콘텐츠 형식으로 담은 "POST" 요청을 전송하는 방식으로 수행됩니다. 이때 전송 가능한 이미지의 최대 파일 크기는 4MB입니다.

클라이언트 라이브러리를 사용할 경우, 업로드를 통한 얼굴 감지는 Stream 개체를 전달하는 방식으로 수행됩니다. 다음 예제를 살펴보시기 바랍니다:

using (Stream s = File.OpenRead(@"D:\MyPictures\image1.jpg"))
{
    var faces = await faceServiceClient.DetectAsync(s, true, true);

    foreach (var face in faces)
    {
        var rect = face.FaceRectangle;
        var landmarks = face.FaceLandmarks;
    }
}

이 예제 코드에서 FaceServiceClient의 DetectAsync 메서드는 비동기 메서드라는 점에 주의하시기 바랍니다. await 절을 사용하려면 메서드 호출 또한 async로 표시되어야 합니다. 만약 이미지가 이미 웹 상에 올라가 있고 접근 가능한 URL이 존재한다면, 해당 URL을 지정해서 얼굴을 감지할 수도 있습니다. 이 경우 요청 본문은 이미지의 URL을 포함하고 있는 JSON 문자열입니다. 클라이언트 라이브러리를 사용할 경우, DetectAsync 메서드의 또 다른 오버로드를 사용하면 URL 방식의 얼굴 감지를 손쉽게 수행할 수 있습니다.

string imageUrl = "http://news.microsoft.com/ceo/assets/photos/06_web.jpg";
var faces = await faceServiceClient.DetectAsync(imageUrl, true, true);

foreach (var face in faces)
{
    var rect = face.FaceRectangle;
    var landmarks = face.FaceLandmarks;
}

감지된 얼굴과 함께 반환되는 FaceRectangle 속성에는 기본적으로 픽셀로 표시된 얼굴의 위치가 담겨 있습니다. 일반적으로 이 직사각형에는 눈, 눈썹, 코, 그리고 입이 포함되며, 머리 상부, 귀, 턱은 포함되지 않습니다. 머리 전체 또는 초상화 형태의 세로 사진을 얻고자 할 경우, 일부 응용 프로그램에서는 얼굴의 영역이 너무 작기 때문에, 얼굴 프레임의 영역을 확대하고 싶을 수도 있습니다. 보다 정확한 얼굴의 위치를 찾아야 할 경우, 다음 절에서 살펴볼 얼굴 랜드마크를 활용하면 (얼굴의 특징을 찾거나 얼굴의 방향을 알아내는 메커니즘) 유용합니다.

단계 3: 얼굴 랜드마크 이해 및 사용하기

얼굴 랜드마크는 특정 얼굴에 대한 구체적인 일련의 세부 사항들로, 일반적으로 눈동자, 안구 또는 코 같은 얼굴 구성 요소의 위치를 말합니다. 얼굴 랜드마크는 얼굴 감지 중 분석 가능한 선택적 속성입니다. Face - Detect API를 호출할 때 returnFaceLandmarks 쿼리 매개 변수에 부울 값으로 'true'를 전달하거나, FaceServiceClient 클래스 DetectAsync 메서드에 returnFaceLandmarks 선택적 매개 변수를 지정하면 검색 결과에 얼굴 랜드마크가 포함됩니다.

기본적으로 미리 정의된 랜드마크 위치가 27 곳이 존재합니다. 다음 그림은 정의된 27 곳의 위치를 모두 보여줍니다:

HowToDetectFace

반환되는 위치들은 얼굴 사각형 프레임과 마찬가지로 픽셀 단위입니다. 따라서 이미지 상의 특정 관심 지점을 손쉽게 표시할 수 있습니다. 다음 코드는 코와 눈동자의 위치를 찾는 방법을 보여줍니다:

var faces = await faceServiceClient.DetectAsync(imageUrl, returnFaceLandmarks:true);

foreach (var face in faces)
{
    var rect = face.FaceRectangle;
    var landmarks = face.FaceLandmarks;

    double noseX = landmarks.NoseTip.X;
    double noseY = landmarks.NoseTip.Y;

    double leftPupilX = landmarks.PupilLeft.X;
    double leftPupilY = landmarks.PupilLeft.Y;

    double rightPupilX = landmarks.PupilRight.X;
    double rightPupilY = landmarks.PupilRight.Y;
}

얼굴의 특징을 이미지에 표시할 수 있을 뿐만아니라, 얼굴 랜드마크를 이용해서 얼굴의 방향을 정확하게 계산할 수도 있습니다. 가령, 입 중심에서 눈 중심까지의 벡터로 얼굴의 방향을 정의할 수 있습니다. 다음 코드는 이를 자세히 보여줍니다:

var landmarks = face.FaceLandmarks;

var upperLipBottom = landmarks.UpperLipBottom;
var underLipTop = landmarks.UnderLipTop;

var centerOfMouth = new Point(
    (upperLipBottom.X + underLipTop.X) / 2,
    (upperLipBottom.Y + underLipTop.Y) / 2);

var eyeLeftInner = landmarks.EyeLeftInner;
var eyeRightInner = landmarks.EyeRightInner;

var centerOfTwoEyes = new Point(
    (eyeLeftInner.X + eyeRightInner.X) / 2,
    (eyeLeftInner.Y + eyeRightInner.Y) / 2);

Vector faceDirection = new Vector(
    centerOfTwoEyes.X - centerOfMouth.X,
    centerOfTwoEyes.Y - centerOfMouth.Y);

얼굴이 위치한 방향을 알면, 직사각형의 얼굴 프레임을 회전해서 얼굴 방향에 맞게 회전시킬 수 있습니다. 이처럼 얼굴 랜드마크를 활용하면 더 자세한 정보와 활용성을 제공할 수 있습니다.

단계 4: 다른 얼굴 특징 이용하기

Face - Detect API는 얼굴 랜드마크 외에도 다음과 같은 얼굴의 다른 다양한 특징들을 분석할 수 있습니다:

  • 나이
  • 성별
  • 미소짓는 정도
  • 얼굴의 털
  • 3D 머리 자세

이 특징들은 통계 알고리즘을 통해서 예측되며 항상 100% 정확한 것은 아닙니다. 그러나 이런 특징들을 이용해서 얼굴을 분류하고자 하는 경우에는 여전히 유용합니다. 각각의 특징들에 관한 더 자세한 정보는 용어집을 참고하시기 바랍니다.

다음은 얼굴 감지 중 얼굴의 특징을 함께 추출하는 간단한 예제입니다:

var requiredFaceAttributes = new FaceAttributeType[] {
                FaceAttributeType.Age,
                FaceAttributeType.Gender,
                FaceAttributeType.Smile,
                FaceAttributeType.FacialHair,
                FaceAttributeType.HeadPose,
                FaceAttributeType.Glasses
            };
var faces = await faceServiceClient.DetectAsync(imageUrl,
    returnFaceLandmarks: true,
    returnFaceAttributes: requiredFaceAttributes);

foreach (var face in faces)
{
    var id = face.FaceId;
    var attributes = face.FaceAttributes;
    var age = attributes.Age;
    var gender = attributes.Gender;
    var smile = attributes.Smile;
    var facialHair = attributes.FacialHair;
    var headPose = attributes.HeadPose;
    var glasses = attributes.Glasses;
}

요약

본문에서는 Face - Detect API의 기능과 로컬에서 업로드 한 이미지나 웹 상에 위치한 이미지의 URL에서 얼굴을 감지하는 방법, 사각형 얼굴 프레임을 반환해서 얼굴을 감지하는 방법, 그리고 얼굴 랜드마크, 3D 머리 자세 및 기타 얼굴 특징들을 분석할 수 있는 방법을 살펴봤습니다.

API에 관한 보다 자세한 내용은 Face - Detect에 대한 API 참조 가이드를 참고하시기 바랍니다.