[Tutorial][MediaPipe] 221018 WSL Ubuntu 20.04 MediaPipe - Hello world
이번 시간에는 MediaPipe 공식 홈페이지에 나와있는 Hello world 예제를 하나하나 따라하며 Bazel 빌드까지 완료합니다. MediaPipe 공식 홈페이지 Android용 튜토리얼은 아래 링크를 통해 확인할 수 있습니다.
링크: https://google.github.io/mediapipe/getting_started/hello_world_android.html
(1) 프로젝트 준비
프로젝트를 진행하기 위해서 아래와 같이 환경이 구성되어 있어야 합니다.
(2) Workspace 만들기
(2-1) 프로젝트 폴더를 만듭니다. 저는 편의를 위하여 폴더명을 “mediapipe-hello-world”로 정했습니다.
1
sudo mkdir mediapipe-hello-world
(2-2) 이전에 MediaPipe를 설치할 때 MediaPipe GitHub Repository를 클론해둔 곳으로 이동합니다. MediaPipe는 Workspace 구성에 필요한 파일과 소스를 공식 Repository에서 제공합니다. 필요한 파일과 폴더를 프로젝트 폴더로 옮깁니다. 필요한 파일/폴더 목록은 아래에 정리했습니다.
파일명 | 설명 |
---|---|
thrid_party | 빌드 스크립트를 모아둔 폴더. |
.bazelrc | Run Command 파일. 빌드 시 자동 실행될 스크립트. |
.bazelversion | 빌드에 사용할 버전을 명시한 파일. |
.gitignore | (선택) Git 업로드 시 무시할 파일 목록. |
LICENSE | 라이선스 관련 파일. |
requirements.txt | 빌드에 필요한 Python 패키지를 명시한 파일. |
setup.py | 빌드에 필요한 개발 환경을 구축해주는 Python 파일. |
setup_android_sdk_and_ndk.sh | Android SDK와 NDK를 설정하는 쉘스크립트 파일 |
setup_opencv.sh | OpenCV를 설정하는 쉘스크립트 파일 |
WORKSPACE | 개발에 필요한 패키지를 자동으로 다운로드 받아 개발 환경을 구축해주는 파일 |
(2-3) 안드로이드 SDK와 NDK 개발환경을 설정합니다. 환경 설정에는 경로 내의 setup_android_sdk_and_ndk.sh 파일을 사용합니다.
1
bash setup_android_sdk_and_ndk.sh
(3) 프로젝트 구조 만들기
(3-1) 프로젝트 폴더에 “app” 폴더를 만듭니다.
1
sudo mkdir app
(3-2) “app” 폴더 안에 “java” 폴더와 “res” 폴더를 생성합니다.
1
2
cd app
sudo mkdir java res
(3-3) “java” 폴더 안에는 “com/example/mediapipe/helloworld” 경로를 생성합니다.
1
2
cd java
sudo mkdir -p com/example/mediapipe/helloworld
(3-4) “res” 폴더 안에는 “layout” 폴더와 “values” 폴더를 생성합니다.
1
2
3
cd ..
cd res
sudo mkdir layout values
(4) 소스 코드 작성
(4-1) “app/java/com/example/mediapipe/helloworld” 경로 안에 “MainActivity.java”라는 파일 생성 후 아래 코드를 작성합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
package com.example.mediapipe.helloworld;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
(4-2) “app/res/layout” 경로 안에 “activity_main.xml”라는 파일 생성 후 아래 코드를 작성합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
(4-3) “app” 경로 안에 “AndroidManifest.xml”라는 파일 생성 후 아래 코드를 작성합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.mediapipe.helloworld">
<uses-sdk
android:minSdkVersion="19"
android:targetSdkVersion="31" />
<application
android:allowBackup="true"
android:label="${appName}"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name="${mainActivity}"
android:exported="true"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
(4-4) “app” 경로 안에 “BUILD”라는 파일 생성 후 아래 코드를 작성합니다. “BUILD” 파일은 빌드 시 타겟을 명시해주는 파일입니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
android_library(
name = "basic_lib",
custom_package = "com.example.mediapipe.helloworld",
srcs = ["java/com/example/mediapipe/helloworld/MainActivity.java"],
manifest = "AndroidManifest.xml",
resource_files = glob(["res/**"]),
deps = [
"//third_party:androidx_constraint_layout",
"//third_party:androidx_appcompat",
],
)
android_binary(
name = "helloworld",
custom_package = "com.example.mediapipe.helloworld",
manifest = "AndroidManifest.xml",
manifest_values = {
"appName": "MediaPipe Hello World",
"mainActivity": ".MainActivity",
},
multidex = "native",
deps = [
":basic_lib",
],
)
(4-5) 마지막으로 아래 두 파일을 “app/res/values” 디렉토리에 생성합니다.
colors.xml
1
2
3
4
5
6
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#008577</color>
<color name="colorPrimaryDark">#00574B</color>
<color name="colorAccent">#D81B60</color>
</resources>
styles.xml
1
2
3
4
5
6
7
8
9
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
</resources>
(5) 앱 빌드
(5-1) 아래와 같이 명령어를 입력하여 앱을 빌드합니다.
1
bazel build -c opt --define MEDAPIPE_DISABLE_GPU=1 //app:helloworld
(6) 앱 설치
(6-1) 프로젝트 폴더에 “bazel-bin/app” 경로로 들어가면 helloworld.apk 파일을 확인할 수 있습니다.
(6-2) “bazel-bin/app” 디렉토리로 이동한 뒤 아래 명령어로 모바일 디바이스에 앱을 설치합니다.
1
adb install helloworld.apk
(6-3) 아래처럼 BUILD 파일에 설정한 이름대로 앱이 설치된 것을 확인할 수 있고 설치된 앱을 실행해보면 Hellow World가 정상적으로 출력되는 것 또한 확인할 수 있습니다.