Android용 Java에서 Face API 시작 자습서Getting Started with Face API in Java for Android Tutorial

이 자습서에서는 Face API를 호출하는 간단한 Android 응용 프로그램을 개발하여 이미지에서 사람 얼굴을 감지하는 방법을 알아봅니다.In this tutorial, you will learn to create and develop a simple Android application that invokes the Face API to detect human faces in an image. 응용 프로그램에서는 감지하는 얼굴을 포착하여 결과를 보여줍니다.The application shows the result by framing the faces that it detects.

GettingStartedAndroid

준비Preparation

자습서를 사용하려면 다음 필수 조건이 필요합니다.To use the tutorial, you will need the following prerequisites:

  • Android Studio 및 SDK 설치Android Studio and SDK installed
  • Android 장치(테스트의 경우 선택 사항)Android device (optional for testing).

1단계: Face API 구독 및 구독 키 받기Step 1: Subscribe for Face API and get your subscription key

Face API를 사용하려면 먼저 Microsoft Cognitive Services 포털에서 등록하여 Face API를 구독해야 합니다.Before using any Face API, you must sign up to subscribe to Face API in the Microsoft Cognitive Services portal. 구독을 참조하세요.See subscriptions. 기본 키와 보조 키 모두 이 자습서에서 사용할 수 있습니다.Both primary and secondary key can be used in this tutorial.

2단계: 응용 프로그램 프레임워크 만들기Step 2: Create the application framework

이 단계에서는 이미지를 선택하고 표시할 기본 UI를 구현하도록 Android 응용 프로그램 프로젝트를 만듭니다.In this step you will create an Android application project to implement the basic UI for picking up and displaying an image. 아래의 지침을 따르면 됩니다.Simply follow the instructions below:

  1. Android Studio를 엽니다.Open Android Studio.
  2. 파일 메뉴에서 새 프로젝트... 를 클릭합니다.From the File menu, click New Project...
  3. 응용 프로그램 이름을 MyFirstApp으로 지정한 다음, 다음을 클릭합니다.Name the application MyFirstApp, and then click Next.

    GettingStartAndroidNewProject

  4. 필요에 따라 대상 플랫폼을 선택한 다음, 다음을 클릭합니다.Choose target platform as required, and then click Next.

    GettingStartAndroidNewProject2

  5. 기본 작업을 선택한 다음, 다음을 클릭합니다.Select Basic Activity and then click Next.

  6. 다음과 같이 작업 이름을 지정한 다음, 마침을 클릭합니다.Name the activity as follows, and then click Finish.

    GettingStartAndroidNewProject4

  7. activity_main.xml을 열면 이 작업의 레이아웃 편집기가 표시됩니다.Open activity_main.xml, you should see the Layout Editor of this activity.

  8. 다음과 같이 텍스트 원본 파일을 확인한 다음, 작업 레이아웃을 편집합니다.View Text source file and then edit the activity layout as follows:

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
        android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">
    
        <ImageView
            android:layout_width="match_parent"
            android:layout_height="fill_parent"
            android:id="@+id/imageView1"
            android:layout_above="@+id/button1" />
    
        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Browse"
            android:id="@+id/button1"
            android:layout_alignParentBottom="true" />
    </RelativeLayout>
    
  9. MainActivity.java를 열고 파일의 시작 부분에 다음 import 지시문을 삽입합니다.Open MainActivity.java and insert the following import directives at the beginning of the file:

    import java.io.*; 
    import android.app.*; 
    import android.content.*; 
    import android.net.*; 
    import android.os.*; 
    import android.view.*; 
    import android.graphics.*; 
    import android.widget.*; 
    import android.provider.*;
    

    둘째, 클래스를 다음과 같이 수정합니다.Secondly, modify the class as follows:

    private final int PICK_IMAGE = 1;
    private ProgressDialog detectionProgressDialog;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
           super.onCreate(savedInstanceState);
           setContentView(R.layout.activity_main);
           Button button1 = (Button)findViewById(R.id.button1);
           button1.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                Intent gallIntent = new Intent(Intent.ACTION_GET_CONTENT);
                gallIntent.setType("image/*");
                startActivityForResult(Intent.createChooser(gallIntent, "Select Picture"), PICK_IMAGE);
            }
        });
    
        detectionProgressDialog = new ProgressDialog(this);
    }
    
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == PICK_IMAGE && resultCode == RESULT_OK && data != null && data.getData() != null) {
            Uri uri = data.getData();
            try {
                Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
                ImageView imageView = (ImageView) findViewById(R.id.imageView1);
                imageView.setImageBitmap(bitmap);
                } catch (IOException e) {
                e.printStackTrace();
                }
        }
    }
    

이제 앱은 갤러리에서 사진을 찾아보고 아래 이미지와 비슷하게 창에 표시될 수 있습니다.Now your app can browse for a photo from the gallery and display it in the window similar to the image below:

GettingStartAndroidUI

3단계: Face API 클라이언트 라이브러리 구성Step 3: Configure the Face API client library

Face API는 HTTPS 요청을 사용하여 호출할 수 있는 클라우드 API입니다.The Face API is a cloud API which you can invoke using HTTPS requests. .NET 플랫폼 응용 프로그램에서 Face API를 사용하는 편리한 방법으로 클라이언트 라이브러리도 제공되어 웹 요청을 캡슐화합니다.For a more convenient way of using the Face API in .NET platform applications, a client library is also provided to encapsulate the web requests. 이 예제에서는 클라이언트 라이브러리를 사용하여 작업을 간소화합니다.In this example, we use the client library to simplify our work.

클라이언트 라이브러리를 구성하려면 아래 지침을 따르세요.Follow the instructions below to configure the client library:

  1. 예제에서 보여준 대로 프로젝트 패널에서 프로젝트의 최상위 build.gradle 파일을 찾습니다.Locate the top-level build.gradle file of your project from the Project panel shown in the example. 프로젝트 트리에 여러 다른 build.gradle 파일이 있지만 처음에 최상위 build.gradle 파일을 열어야 합니다.Note that there are several other build.gradle files in your project tree, and you need to open the top-level build.gradle file at first.
  2. mavenCentral() 을 프로젝트의 리포지토리에 추가합니다.Add mavenCentral() to your projects' repositories. jcenter()가 mavenCentral()의 상위 집합이므로 Android Studio의 기본 리포지토리인 jcenter()를 사용할 수도 있습니다.You can also use jcenter(), which is the default repository of Android Studio, since jcenter() is a superset of mavenCentral().
    allprojects {
        repositories {
            ...
            mavenCentral()
        }
    }
  1. '앱' 프로젝트에서 build.gradle 파일을 엽니다.Open the build.gradle file in your 'app' project.
  2. Maven 중앙 리포지토리에 저장된 클라이언트 라이브러리의 종속성을 추가합니다.Add a dependency for our client library stored in the Maven Central Repository:
    dependencies {  
        ...  
        implementation 'com.microsoft.projectoxford:face:1.4.3'  
    }
  1. '앱' 프로젝트에서 MainActivity.java를 열고 다음 import 지시문을 삽입합니다.Open MainActivity.java in your 'app' project and insert the following import directives:

    import com.microsoft.projectoxford.face.*;  
    import com.microsoft.projectoxford.face.contract.*;  
    

    그런 다음, 클래스에 다음 코드를 삽입합니다.Then, insert the following code in the class:

    private FaceServiceClient faceServiceClient = new FaceServiceRestClient("your API endpoint", "<Subscription Key>");
    

    위의 첫 번째 매개 변수를 1단계에서 키에 할당된 API 엔드포인트로 바꿉니다.Replace the first parameter above with the API endpoint that was assigned to your key in step 1. 예: For example:

     https://eastus2.api.cognitive.microsoft.com/face/v1.0
    

    두 번째 매개 변수를 1단계에서 얻은 구독 키로 바꿉니다.Replace the second parameter with the subscription key that you obtained in step 1.

  2. '앱' 프로젝트에서 AndroidManifest.xml 파일을 엽니다.Open the file AndroidManifest.xml in your 'app' project. 다음 요소를 매니페스트 요소의 자식으로 삽입합니다.Insert the following element as child of the manifest element:

    <uses-permission android:name="android.permission.INTERNET" />  
    
  3. 이제 응용 프로그램에서 Face API를 호출할 준비가 되었습니다.Now you are ready to call the Face API from your application.

4단계: 이미지를 업로드하여 얼굴 감지Step 4: Upload images to detect faces

얼굴을 감지하는 가장 간단한 방법은 이미지 파일을 직접 업로드하여 얼굴 - 감지 API를 호출하는 것입니다.The most straightforward way to detect faces is by calling the Face – Detect API by uploading the image file directly. 클라이언트 라이브러리를 사용하는 경우 FaceServiceClient 클래스의 비동기 메서드 DetectAsync를 사용하여 이 작업을 수행할 수 있습니다.When using the client library, this can be done by using the asynchronous method DetectAsync of the FaceServiceClient class. 반환된 각 얼굴에는 해당 위치를 표시하는 사각형이 일련의 선택적 얼굴 특성과 함께 포함되어 있습니다.Each returned face contains a rectangle to indicate its location, combined with a series of optional face attributes. 이 예제에서는 얼굴 위치를 검색해야 합니다.In this example, we only need to retrieve the face location. 여기서 얼굴 감지를 위해 MainActivity 클래스에 메서드를 삽입해야 합니다.Here we need to insert a method into the MainActivity class for face detection:


    // Detect faces by uploading face images
    // Frame faces after detection

    private void detectAndFrame(final Bitmap imageBitmap)
    {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        imageBitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
        ByteArrayInputStream inputStream = 
            new ByteArrayInputStream(outputStream.toByteArray());
        AsyncTask<InputStream, String, Face[]> detectTask =
            new AsyncTask<InputStream, String, Face[]>() {
                @Override
                protected Face[] doInBackground(InputStream... params) {
                    try {
                        publishProgress("Detecting...");
                        Face[] result = faceServiceClient.detect(
                                params[0], 
                                true,         // returnFaceId
                                false,        // returnFaceLandmarks
                                null           // returnFaceAttributes: a string like "age, gender"
                /* If you want value of FaceAttributes, try adding 4th argument like below.
                            new FaceServiceClient.FaceAttributeType[] {
                    FaceServiceClient.FaceAttributeType.Age,
                    FaceServiceClient.FaceAttributeType.Gender }
                */              
                        );
                        if (result == null)
                        {
                            publishProgress("Detection Finished. Nothing detected");
                            return null;
                        }
                        publishProgress(
                                String.format("Detection Finished. %d face(s) detected",
                                        result.length));
                        return result;
                    } catch (Exception e) {
                        publishProgress("Detection failed");
                        return null;
                    }
                }
                @Override
                protected void onPreExecute() {
                    //TODO: show progress dialog
                }
                @Override
                protected void onProgressUpdate(String... progress) {
                    //TODO: update progress
                }
                @Override
                protected void onPostExecute(Face[] result) {
                    //TODO: update face frames
                }
            };
        detectTask.execute(inputStream);
    }

5단계: 이미지에서 얼굴 표시Step 5: Mark faces in the image

이 마지막 단계에서는 위의 모든 단계를 함께 결합하고 이미지의 프레임을 사용하여 감지된 얼굴을 표시합니다.In this last step, we combine all the above steps together and mark the detected faces with frames in the image. 먼저 MainActivity.java를 열고 사각형을 그리는 도우미 메서드를 삽입합니다.First, open MainActivity.java and insert a helper method to draw rectangles:

    private static Bitmap drawFaceRectanglesOnBitmap(Bitmap originalBitmap, Face[] faces) {
        Bitmap bitmap = originalBitmap.copy(Bitmap.Config.ARGB_8888, true);
        Canvas canvas = new Canvas(bitmap);
        Paint paint = new Paint();
        paint.setAntiAlias(true);
        paint.setStyle(Paint.Style.STROKE);
        paint.setColor(Color.RED);
        int stokeWidth = 2;
        paint.setStrokeWidth(stokeWidth);
        if (faces != null) {
            for (Face face : faces) {
                FaceRectangle faceRectangle = face.faceRectangle;
                canvas.drawRect(
                        faceRectangle.left,
                        faceRectangle.top,
                        faceRectangle.left + faceRectangle.width,
                        faceRectangle.top + faceRectangle.height,
                        paint);
            }
        }
        return bitmap;
    }

이제 얼굴을 포착하고 상태를 보고하기 위해 detectAndFrame 메서드에서 TODO 파트를 마무리합니다.Now finish the TODO parts in the detectAndFrame method in order to frame faces and report status.

    @Override
    protected void onPreExecute() {
        detectionProgressDialog.show();
    }
    @Override
    protected void onProgressUpdate(String... progress) {
        detectionProgressDialog.setMessage(progress[0]);
    }
    @Override
    protected void onPostExecute(Face[] result) {
        detectionProgressDialog.dismiss();
        if (result == null) return;
        ImageView imageView = (ImageView)findViewById(R.id.imageView1);
        imageView.setImageBitmap(drawFaceRectanglesOnBitmap(imageBitmap, result));
        imageBitmap.recycle();
    }

마지막으로 다음과 같이 onActivityResult 메서드에서 detectAndFrame 메서드에 대한 호출을 추가합니다.Finally, add a call to the detectAndFrame method from the onActivityResult method, as shown below.

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == PICK_IMAGE && resultCode == RESULT_OK && data != null && data.getData() != null) {
            Uri uri = data.getData();
            try {
                Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
                ImageView imageView = (ImageView) findViewById(R.id.imageView1);
                imageView.setImageBitmap(bitmap);

                // This is the new addition.
                // detectAndFrame(bitmap);

            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

이 응용 프로그램을 실행하고 얼굴이 포함된 이미지를 찾습니다.Run this application and browse for an image containing a face. 클라우드 API가 응답할 수 있도록 몇 초 동안 기다리세요.Please wait for a few seconds to allow the cloud API to respond. 그러면 아래 이미지와 비슷한 결과가 나타납니다.After that, you will get a result similar to the image below:

GettingStartAndroid

요약Summary

이 자습서에서는 Face API를 사용하는 기본 프로세스를 배웠으며, 이미지에 얼굴 표식을 표시하는 응용 프로그램을 만들었습니다.In this tutorial, you learned the basic process for using the Face API and created an application to display face marks in images. Face API에 대한 자세한 내용은 방법 및 API 참조를 참조하세요.For more information on the Face API, refer to the How-To and API Reference.