ตรวจจับวัตถุในภาพด้วยโมเดลที่ได้รับการฝึก AutoML บน Android

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

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

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

ก่อนที่คุณจะเริ่ม

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

  2. เพิ่มการพึ่งพาสำหรับไลบรารีงาน 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 โดยระบุชื่อที่คุณกำหนดให้กับโมเดลเมื่อคุณเผยแพร่:

ชวา

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

คอตลิน

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

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

ชวา

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.
            }
        });

คอตลิน

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

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

สร้างเครื่องตรวจจับวัตถุจากแบบจำลองของคุณ

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

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

ชวา

// 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);

คอตลิน

// 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() ของตัวจัดการโมเดล

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

ชวา

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

คอตลิน

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

        }

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

เมื่อคุณทราบว่าโมเดลของคุณถูกดาวน์โหลดแล้ว ให้สร้างตัวตรวจจับวัตถุจากไฟล์โมเดล:

ชวา

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);
                }
            }
        });

คอตลิน

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 ดังนี้

ชวา

TensorImage image = TensorImage.fromBitmap(bitmap);

คอตลิน

val image = TensorImage.fromBitmap(bitmap)

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

3. เรียกใช้เครื่องตรวจจับวัตถุ

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

ชวา

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

คอตลิน

val results = objectDetector.detect(image)

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

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

ตัวอย่างเช่น:

ชวา

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

คอตลิน

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

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

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

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

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