YOLOv8 segmentation 안드로이드 -2

알로에·2023년 10월 11일
2

YOLOv8-Segmentation

목록 보기
2/6
post-thumbnail

이번에도 마찬가지로 모델을 .pt 파일 자체로 사용하지 않고, .onnx 파일로 변환 후 사용한다. 또한 COCO 데이터로 학습된 디폴트 모델을 사용할 예정이다.

✔ 1. YOLOv8n-seg 모델 onnx 변환

변환 방식은 매우 간단하다.
우선 디폴트 모델을 아래 사이트를 통해 다운 받는다.
https://github.com/ultralytics/ultralytics

Segmentation 버튼을 클릭하고 가장 위쪽의 nano 모델을 다운 받으면 된다.
다운 받은 폴더에 아래와 같은 .py 파일을 생성한다.

from ultralytics import YOLO
from PIL import Image

model = YOLO('./yolov8n-seg.pt')
model.export(format='onnx')

실행을 하게 되면 yolov8n-seg.onnx 파일이 생성되게 된다.
https://netron.app/ 이곳을 통해서 쉽게 모델의 구조를 알 수 있다.

model의 input은 이전 모델과 같이 [640, 640] 크기의 RGB 3차원 float 형태이다. output은 2개를 가지며 output0는 xywh, 각 클래스의 신뢰값, 마스크 가중치 값들을 가진다. output1은 프로토 타입 마스크 값들을 가진다. 추후 후처리 과정에서 자세히 다루게 될 것이다.

✔ 2. 새 프로젝트 생성

이 글은 Kotlin으로 작성했으며 compose를 이용해 UI를 만들었다.
Java를 사용하거나 xml로 UI를 작성한 경우, 적절히 변환하면 된다.
1. assets 폴더에 위에서 변환했던 onnx 파일과 coco 모델이 라벨링된 txt 파일을 추가한다.
좌측 상단에 Android 버튼을 눌러 Project로 변환 한 후, assets 폴더를 아래와 같이 생성한다.

src -> main -> 우클릭 -> New -> Directory 클릭 -> assets 생성
assets 폴더에 onnx 파일과 txt 파일을 추가한다.

txt 파일은 COCO 데이터가 하나씩 쓰여있는 txt 파일이다. 아래와 같이 쓰여있다.

person
bicycle
car
motorcycle
airplane
bus
train
truck
boat
traffic light
fire hydrant
stop sign
parking meter
bench
bird
cat
dog
horse
sheep
cow
elephant
bear
zebra
giraffe
backpack
umbrella
handbag
tie
suitcase
frisbee
skis
snowboard
sports ball
kite
baseball bat
baseball glove
skateboard
surfboard
tennis racket
bottle
wine glass
cup
fork
knife
spoon
bowl
banana
apple
sandwich
orange
broccoli
carrot
hot dog
pizza
donut
cake
chair
couch
potted plant
bed
dining table
toilet
tv
laptop
mouse
remote
keyboard
cell phone
microwave
oven
toaster
sink
refrigerator
book
clock
vase
scissors
teddy bear
hair drier
toothbrush

마지막으로 다시 좌상단의 Project -> Android로 변경한다.

  1. 권한 부여 및 가로모드
    manifests.xml 파일에 아래 코드를 추가한다.
<uses-feature
        android:name="android.hardware.camera"
        android:required="false" />
    <uses-permission android:name="android.permission.CAMERA" />

또한 아래와 같이 가로모드로 고정한다.

android:configChanges="keyboardHidden|orientation"
android:screenOrientation="landscape"

편의를 위해 전체화면으로 사용할 예정이다.
res -> values -> themes.xml에 아래 코드를 추가한다.

 <item name="android:windowFullscreen">true</item>

✔ 3. OpenCV 라이브러리 적용

이제는 OpenCV 라이브러리를 안드로이드에 적용하는 방법이다.
https://opencv.org/releases/ 이곳에서 가장 최신 버전의 안드로이드 버튼을 누르면 저장할 수 있게 된다.

작성한 날짜 기준으로는 4.8.0이 가장 최신 버전이였다.
압축을 해제하면 opencv-4.8.0-android-sdk 폴더가 나오게 된다.

바로 해당 sdk를 안드로이드 모듈에 추가하면 에러가 나오게 된다.
이제는 더이상 manifest에 package명을 넣지 않는다. opencv-4.8.0-android-sdk 폴더에서 sdk -> java -> AndroidManifest.xml 에서 package가 있는 부분을 지워야 한다.

그럼 이 package명을 어디서 추가해야 하나면, build.gradle 에서 추가한다. opencv-4.8.0-android-sdk -> sdk -> build.gradle 부분에 아래와 같이 패키지 명을 추가한다.

그 외의 sdk 버전은 위에서 생성했던 프로젝트와 동일하게 작성한다.

마지막으로 빌드 시 aidl, buildConfig를 허용하게 아래와 같이 코드를 추가한다.

 buildFeatures{
        aidl = true
        buildConfig = true
    }

OpenCV sdk에서 전체 build.gradle 파일은 아래와 같다.

apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'

def openCVersionName = "4.8.0"
def openCVersionCode = ((4 * 100 + 8) * 100 + 0) * 10 + 0

println "OpenCV: " +openCVersionName + " " + project.buildscript.sourceFile

android {
    namespace "org.opencv"
    compileSdk 34

    defaultConfig {
        minSdkVersion 24
        targetSdkVersion 34

        versionCode openCVersionCode
        versionName openCVersionName

        externalNativeBuild {
            cmake {
                arguments "-DANDROID_STL=c++_shared"
                targets "opencv_jni_shared"
            }
        }
    }

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_17
        targetCompatibility JavaVersion.VERSION_17
    }
    buildFeatures{
        aidl = true
        buildConfig = true
    }


    buildTypes {
        debug {
            packagingOptions {
                doNotStrip '**/*.so'  // controlled by OpenCV CMake scripts
            }
        }
        release {
            packagingOptions {
                doNotStrip '**/*.so'  // controlled by OpenCV CMake scripts
            }
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
        }
    }

    sourceSets {
        main {
            jniLibs.srcDirs = ['native/libs']
            java.srcDirs = ['java/src']
            aidl.srcDirs = ['java/src']
            res.srcDirs = ['java/res']
            manifest.srcFile 'java/AndroidManifest.xml'
        }
    }

    externalNativeBuild {
        cmake {
            path (project.projectDir.toString() + '/libcxx_helper/CMakeLists.txt')
        }
    }
}

dependencies {
}

자바 버전, sdk 버전은 위에서 생성했던 프로젝트와 동일하게 작성하면 된다.

이제 기존 프로젝트에 sdk 모듈을 추가한다.
좌상단에 File -> New -> Import Module

Finish 버튼을 누르면 된다.

만약 아래와 같이 에러가 난다면

settings.gradle이 추가로 생겼는지 확인해야 한다.

이와 같이 두개가 생긴 경우, 위의 settings.gradle 파일을 삭제하고, 아래 settings.gradle.kts에 아래와 같이 변환해야 한다.

include(":app", ":sdk")

마지막으로 app 수준에도 모듈을 추가하면 된다.

좌상단에서 File -> Project Structure -> Dependencies -> app ->
Module Dependency

sdk를 선택하고 ok 버튼을 누르면 된다.

0개의 댓글

관련 채용 정보