ตรวจจับออบเจ็กต์ในรูปภาพด้วยโมเดลที่ฝึกด้วย AutoML ใน Android

หลังจากฝึกโมเดลของคุณเองโดยใช้ AutoML Vision Edge แล้ว คุณจะใช้โมเดลดังกล่าวในแอปเพื่อตรวจจับออบเจ็กต์ในรูปภาพได้

การผสานรวมโมเดลที่ฝึกจาก AutoML Vision Edge ทำได้ 2 วิธีคือ คุณสามารถรวมโมเดลโดยใส่ไว้ในโฟลเดอร์เนื้อหาของแอป หรือจะดาวน์โหลดโมเดลแบบไดนามิกจาก Firebase ก็ได้

ตัวเลือกการรวมโมเดล
รวมกลุ่มในแอปของคุณ
  • โมเดลนี้เป็นส่วนหนึ่งของ APK ของแอป
  • โมเดลดังกล่าวจะพร้อมใช้งานทันที แม้ว่าอุปกรณ์ Android จะออฟไลน์อยู่
  • ไม่จำเป็นต้องมีโปรเจ็กต์ Firebase
โฮสต์ด้วย Firebase
  • โฮสต์โมเดลโดยการอัปโหลดไปยัง Firebase Machine Learning
  • ลดขนาด APK
  • ระบบจะดาวน์โหลดโมเดลตามคําขอ
  • พุชการอัปเดตโมเดลโดยไม่ต้องเผยแพร่แอปอีกครั้ง
  • การทดสอบ A/B ที่ง่ายดายด้วย Firebase Remote Config
  • ต้องมีโปรเจ็กต์ Firebase

ก่อนเริ่มต้น

  1. หากต้องการดาวน์โหลดโมเดล โปรดตรวจสอบว่าคุณได้เพิ่ม Firebase ลงในโปรเจ็กต์ Android แล้ว หากยังไม่ได้ดำเนินการดังกล่าว ซึ่งไม่จําเป็นเมื่อคุณรวมโมเดล

  2. เพิ่มทรัพยากร Dependency สำหรับคลังงาน TensorFlow Lite ลงในไฟล์ Gradle ระดับแอปของโมดูล ซึ่งโดยปกติจะเป็น app/build.gradle

    สำหรับการรวมโมเดลกับแอป ให้ทำดังนี้

    dependencies {
      // ...
      // Object detection with a bundled Auto ML model
      implementation 'org.tensorflow:tensorflow-lite-task-vision:0.0.0-nightly-SNAPSHOT'
    }
    

    หากต้องการดาวน์โหลดโมเดลจาก Firebase แบบไดนามิก ให้เพิ่มข้อกําหนดของ Firebase ML ดังนี้

    dependencies {
      // ...
      // Object detection with an Auto ML model deployed to Firebase
      implementation platform('com.google.firebase:firebase-bom:26.1.1')
      implementation 'com.google.firebase:firebase-ml-model-interpreter'
    
      implementation 'org.tensorflow:tensorflow-lite-task-vision:0.0.0-nightly'
    }
    

1. โหลดโมเดล

กำหนดค่าแหล่งข้อมูลโมเดลในเครื่อง

วิธีการรวมโมเดลกับแอปมีดังนี้

  1. แตกไฟล์โมเดลจากไฟล์ ZIP ที่คุณดาวน์โหลดจากคอนโซล Google Cloud
  2. ใส่ข้อมูลรุ่นของคุณในแพ็กเกจแอป โดยทำดังนี้
    1. หากไม่มีโฟลเดอร์ชิ้นงานในโปรเจ็กต์ ให้สร้างโฟลเดอร์โดยคลิกขวาที่โฟลเดอร์ app/ แล้วคลิกใหม่ > โฟลเดอร์ > โฟลเดอร์ชิ้นงาน
    2. คัดลอกไฟล์โมเดล tflite ที่มีข้อมูลเมตาที่ฝังไว้ไปยังโฟลเดอร์เนื้อหา
  3. เพิ่มโค้ดต่อไปนี้ลงในไฟล์ build.gradle ของแอปเพื่อให้แน่ใจว่า Gradle จะไม่บีบอัดไฟล์โมเดลเมื่อสร้างแอป

    android {
        // ...
        aaptOptions {
            noCompress "tflite"
        }
    }
    

    ไฟล์โมเดลจะรวมอยู่ในแพ็กเกจแอปและพร้อม อยู่ในรูปแบบเนื้อหาดิบ

กำหนดค่าแหล่งข้อมูลรูปแบบที่โฮสต์ใน Firebase

หากต้องการใช้โมเดลที่โฮสต์จากระยะไกล ให้สร้างออบเจ็กต์ RemoteModel โดยระบุชื่อที่คุณกำหนดให้กับโมเดลเมื่อเผยแพร่

Java

// Specify the name you assigned when you deployed the model.
FirebaseCustomRemoteModel remoteModel =
        new FirebaseCustomRemoteModel.Builder("your_model").build();

Kotlin

// Specify the name you assigned when you deployed the model.
val remoteModel =
    FirebaseCustomRemoteModel.Builder("your_model_name").build()

จากนั้นเริ่มงานการดาวน์โหลดโมเดลโดยระบุเงื่อนไขที่คุณต้องการอนุญาตให้ดาวน์โหลด หากโมเดลไม่อยู่ในอุปกรณ์ หรือหากมีโมเดลเวอร์ชันใหม่กว่า แท็บจะดาวน์โหลดโมเดลจาก Firebase แบบไม่พร้อมกัน โดยทำดังนี้

Java

DownloadConditions downloadConditions = new DownloadConditions.Builder()
        .requireWifi()
        .build();
RemoteModelManager.getInstance().download(remoteModel, downloadConditions)
        .addOnSuccessListener(new OnSuccessListener<Void>() {
            @Override
            public void onSuccess(@NonNull Task<Void> task) {
                // Success.
            }
        });

Kotlin

val downloadConditions = DownloadConditions.Builder()
    .requireWifi()
    .build()
RemoteModelManager.getInstance().download(remoteModel, downloadConditions)
    .addOnSuccessListener {
        // Success.
    }

แอปจำนวนมากเริ่มงานดาวน์โหลดในโค้ดเริ่มต้น แต่คุณทำได้ทุกเมื่อก่อนที่จะต้องใช้โมเดลดังกล่าว

สร้างตัวตรวจจับวัตถุจากโมเดล

หลังจากกําหนดค่าแหล่งที่มาของโมเดลแล้ว ให้สร้างออบเจ็กต์ ObjectDetector จากแหล่งที่มาแหล่งใดแหล่งหนึ่ง

หากคุณมีเพียงโมเดลที่รวมอยู่ในเครื่อง ให้สร้างตัวตรวจจับวัตถุจากไฟล์โมเดลและกำหนดเกณฑ์คะแนนความเชื่อมั่นที่ต้องการ (ดูประเมินโมเดล)

Java

// Initialization
ObjectDetectorOptions options = ObjectDetectorOptions.builder()
    .setScoreThreshold(0)  // Evaluate your model in the Google Cloud console
                           // to determine an appropriate value.
    .build();
ObjectDetector objectDetector = ObjectDetector.createFromFileAndOptions(context, modelFile, options);

Kotlin

// Initialization
val options = ObjectDetectorOptions.builder()
    .setScoreThreshold(0)  // Evaluate your model in the Google Cloud console
                           // to determine an appropriate value.
    .build()
val objectDetector = ObjectDetector.createFromFileAndOptions(context, modelFile, options)

หากมีโมเดลที่โฮสต์จากระยะไกล คุณจะต้องตรวจสอบว่าได้ดาวน์โหลดโมเดลแล้วก่อนที่จะเรียกใช้ คุณตรวจสอบสถานะของงานดาวน์โหลดรูปแบบได้โดยใช้isModelDownloaded()วิธีการของตัวจัดการรูปแบบ

แม้คุณจะต้องยืนยันเรื่องนี้ก่อนเรียกใช้ตัวตรวจจับวัตถุเท่านั้น แต่ถ้าคุณมีทั้งโมเดลที่โฮสต์จากระยะไกลและโมเดลที่รวมไว้ในเครื่อง ก็อาจจะเหมาะแก่การตรวจสอบนี้เมื่อเริ่มต้นตัวตรวจจับวัตถุ โดยสร้างตัวตรวจจับวัตถุจากโมเดลระยะไกลหากดาวน์โหลดแล้ว หรือจากโมเดลในเครื่อง

Java

FirebaseModelManager.getInstance().isModelDownloaded(remoteModel)
        .addOnSuccessListener(new OnSuccessListener<Boolean>() {
            @Override
            public void onSuccess(Boolean isDownloaded) {
            }
        });

Kotlin

FirebaseModelManager.getInstance().isModelDownloaded(remoteModel)
        .addOnSuccessListener { success ->

        }

หากคุณมีเฉพาะโมเดลที่โฮสต์จากระยะไกล คุณควรปิดใช้ฟังก์ชันที่เกี่ยวข้องกับโมเดล เช่น เป็นสีเทาหรือซ่อนบางส่วนของ UI จนกว่าจะยืนยันว่าดาวน์โหลดโมเดลแล้ว ซึ่งทําได้โดยแนบโปรแกรมรับฟังกับเมธอด download() ของเครื่องมือจัดการโมเดล

เมื่อทราบว่าระบบดาวน์โหลดโมเดลแล้ว ให้สร้างตัวตรวจจับวัตถุจากไฟล์โมเดลโดยทำดังนี้

Java

FirebaseModelManager.getInstance().getLatestModelFile(remoteModel)
        .addOnCompleteListener(new OnCompleteListener<File>() {
            @Override
            public void onComplete(@NonNull Task<File> task) {
                File modelFile = task.getResult();
                if (modelFile != null) {
                    ObjectDetectorOptions options = ObjectDetectorOptions.builder()
                            .setScoreThreshold(0)
                            .build();
                    objectDetector = ObjectDetector.createFromFileAndOptions(
                            getApplicationContext(), modelFile.getPath(), options);
                }
            }
        });

Kotlin

FirebaseModelManager.getInstance().getLatestModelFile(remoteModel)
        .addOnSuccessListener { modelFile ->
            val options = ObjectDetectorOptions.builder()
                    .setScoreThreshold(0f)
                    .build()
            objectDetector = ObjectDetector.createFromFileAndOptions(
                    applicationContext, modelFile.path, options)
        }

2. เตรียมรูปภาพอินพุต

จากนั้นสร้างออบเจ็กต์ TensorImage จากรูปภาพแต่ละรูปที่ต้องการติดป้ายกำกับ คุณสร้างออบเจ็กต์ TensorImage จาก Bitmap ได้โดยใช้เมธอด fromBitmap ดังนี้

Java

TensorImage image = TensorImage.fromBitmap(bitmap);

Kotlin

val image = TensorImage.fromBitmap(bitmap)

หากข้อมูลรูปภาพไม่ได้อยู่ใน Bitmap คุณสามารถโหลดอาร์เรย์พิกเซลตามที่แสดงในเอกสารประกอบของ TensorFlow Lite

3. เรียกใช้ตัวตรวจจับวัตถุ

หากต้องการตรวจหาวัตถุในรูปภาพ ให้ส่งออบเจ็กต์ TensorImage ไปยังเมธอด detect() ของ ObjectDetector

Java

List<Detection> results = objectDetector.detect(image);

Kotlin

val results = objectDetector.detect(image)

4. ดูข้อมูลเกี่ยวกับวัตถุที่ติดป้ายกำกับ

หากการดำเนินการตรวจหาวัตถุสำเร็จ ระบบจะแสดงรายการDetection วัตถุ ออบเจ็กต์ Detection แต่ละรายการแสดงถึงสิ่งที่ตรวจพบในรูปภาพ คุณสามารถดูกล่องขอบเขตและป้ายกำกับของวัตถุแต่ละรายการได้

เช่น

Java

for (Detection result : results) {
    RectF bounds = result.getBoundingBox();
    List<Category> labels = result.getCategories();
}

Kotlin

for (result in results) {
    val bounds = result.getBoundingBox()
    val labels = result.getCategories()
}

เคล็ดลับในการปรับปรุงประสิทธิภาพแบบเรียลไทม์

หากต้องการติดป้ายกำกับรูปภาพในแอปพลิเคชันแบบเรียลไทม์ ให้ทำตามหลักเกณฑ์ต่อไปนี้เพื่อให้ได้อัตราเฟรมที่ดีที่สุด

  • จำกัดการเรียกใช้โปรแกรมติดป้ายกำกับรูปภาพ หากเฟรมวิดีโอใหม่พร้อมใช้งานขณะที่โปรแกรมติดป้ายกำกับรูปภาพทำงานอยู่ ให้วางเฟรมนั้น ดูตัวอย่างได้จากคลาส VisionProcessorBase ในแอปตัวอย่างการเริ่มต้นใช้งาน
  • หากคุณใช้เอาต์พุตของเครื่องติดป้ายกำกับรูปภาพเพื่อวางกราฟิกซ้อนทับบนรูปภาพอินพุต ให้รับผลลัพธ์ก่อน จากนั้นจึงแสดงผลรูปภาพและวางซ้อนในขั้นตอนเดียว ซึ่งจะทำให้คุณแสดงผลไปยังพื้นผิวการแสดงผลเพียงครั้งเดียวสำหรับเฟรมอินพุตแต่ละเฟรม ดูตัวอย่างได้จากคลาส CameraSourcePreview และ GraphicOverlay ในแอปตัวอย่างการเริ่มต้นใช้งาน
  • หากคุณใช้ Camera2 API ให้จับภาพในรูปแบบ ImageFormat.YUV_420_888

    หากคุณใช้ Camera API เวอร์ชันเก่า ให้ถ่ายภาพในรูปแบบ ImageFormat.NV21