คุณใช้ ML Kit เพื่อจดจําเอนทิตีในรูปภาพและติดป้ายกํากับได้ API นี้รองรับโมเดลการแยกประเภทรูปภาพที่กําหนดเองที่หลากหลาย โปรดดูโมเดลที่กําหนดเองที่มี ML Kit เพื่อดูคําแนะนําเกี่ยวกับข้อกําหนดความเข้ากันได้ของโมเดล วิธีค้นหาโมเดลที่ฝึกล่วงหน้า และวิธีฝึกโมเดลของคุณเอง
คุณผสานรวมป้ายกํากับรูปภาพกับโมเดลที่กําหนดเองได้ 2 วิธี ได้แก่ การรวมไปป์ไลน์เป็นส่วนหนึ่งของแอป หรือการใช้ไปป์ไลน์ที่ไม่ได้รวมกลุ่มโดยขึ้นอยู่กับบริการ Google Play หากเลือกไปป์ไลน์ที่ไม่ได้จัดกลุ่ม แอปจะมีขนาดเล็กลง ดูรายละเอียดได้ในตารางด้านล่าง
รวมกลุ่ม | เลิกรวมกลุ่มแล้ว | |
---|---|---|
ชื่อคลัง | com.google.mlkit:image-labeling-custom | com.google.android.gms:play-services-mlkit-image-labeling-custom |
การใช้งาน | ไปป์ไลน์จะลิงก์กับแอปของคุณแบบคงที่ในเวลาบิลด์ | ไปป์ไลน์จะดาวน์โหลดแบบไดนามิกผ่านบริการ Google Play |
ขนาดแอป | มีขนาดเพิ่มขึ้นประมาณ 3.8 MB | มีขนาดเพิ่มขึ้นประมาณ 200 KB |
เวลาเริ่มต้น | ไปป์ไลน์พร้อมใช้งานทันที | อาจต้องรอให้มีการดาวน์โหลดไปป์ไลน์ก่อนใช้งานครั้งแรก |
ช่วงอายุการใช้งานของ API | เวอร์ชันสําหรับผู้ใช้ทั่วไป (GA) | เบต้า |
คุณผสานรวมโมเดลที่กําหนดเองได้ 2 วิธี ได้แก่ รวมโมเดลโดยวางไว้ในโฟลเดอร์ชิ้นงานของแอป หรือดาวน์โหลดแบบไดนามิกจาก Firebase ตารางต่อไปนี้จะเปรียบเทียบ 2 ตัวเลือกนี้
รุ่นที่รวมอยู่ในแพ็กเกจ | โมเดลที่โฮสต์ |
---|---|
โมเดลนี้เป็นส่วนหนึ่งของ APK ของแอปซึ่งจะเพิ่มขนาด | โมเดลไม่ได้เป็นส่วนหนึ่งของ APK ซึ่งโฮสต์โดยการอัปโหลดไปยัง Firebase Machine Learning |
โมเดลจะพร้อมใช้งานทันทีแม้อุปกรณ์ Android ออฟไลน์อยู่ | ดาวน์โหลดโมเดลตามคําขอแล้ว |
ไม่จําเป็นต้องมีโปรเจ็กต์ Firebase | ต้องใช้โปรเจ็กต์ Firebase |
คุณต้องเผยแพร่แอปอีกครั้งเพื่ออัปเดตรูปแบบ | ติดตั้งการอัปเดตโมเดลโดยไม่ต้องเผยแพร่แอปอีกครั้ง |
ไม่มีการทดสอบ A/B ในตัว | ทดสอบ A/B ได้ง่ายๆ ด้วยการกําหนดค่าระยะไกลของ Firebase |
ลองใช้งาน
- ดูตัวอย่างการใช้งานโมเดลแบบกลุ่มได้ในแอปคู่มือเริ่มใช้งานฉบับย่อ และแอปคู่มือเริ่มใช้งานฉบับย่ออัตโนมัติสําหรับการใช้งานตัวอย่าง
ข้อควรทราบก่อนที่จะเริ่มต้น
ในไฟล์
build.gradle
ระดับโปรเจ็กต์ อย่าลืมใส่ที่เก็บ Maven ของ Google ทั้งในbuildscript
และallprojects
เพิ่มทรัพยากร Dependency สําหรับไลบรารี Android ของ ML Kit ไปยังไฟล์ Gradle ระดับแอปของโมดูล ซึ่งปกติจะเป็น
app/build.gradle
เลือกทรัพยากร Dependency ต่อไปนี้ 1 รายการตามความต้องการของคุณสําหรับการรวมไปป์ไลน์กับแอป ให้ทําดังนี้
dependencies { // ... // Use this dependency to bundle the pipeline with your app implementation 'com.google.mlkit:image-labeling-custom:17.0.1' }
สําหรับการใช้ไปป์ไลน์ในบริการ Google Play
dependencies { // ... // Use this dependency to use the dynamically downloaded pipeline in Google Play Services implementation 'com.google.android.gms:play-services-mlkit-image-labeling-custom:16.0.0-beta4' }
หากคุณเลือกที่จะใช้ไปป์ไลน์ในบริการ Google Play คุณสามารถกําหนดค่าแอปเพื่อดาวน์โหลดไปป์ไลน์ไปยังอุปกรณ์โดยอัตโนมัติหลังจากที่ติดตั้งแอปจาก Play Store แล้ว โดยเพิ่มประกาศต่อไปนี้ลงในไฟล์
AndroidManifest.xml
ของแอป<application ...> ... <meta-data android:name="com.google.mlkit.vision.DEPENDENCIES" android:value="custom_ica" /> <!-- To use multiple downloads: android:value="custom_ica,download2,download3" --> </application>
นอกจากนี้คุณยังตรวจสอบความพร้อมใช้งานของไปป์ไลน์ได้อย่างชัดเจนและขอดาวน์โหลดผ่าน ModuleInstallClient API ของบริการ Google Play
หากคุณเปิดใช้การดาวน์โหลดไปป์ไลน์เวลาติดตั้งหรือขอการดาวน์โหลดที่ชัดเจน ระบบจะดาวน์โหลดไปป์ไลน์ในครั้งแรกที่คุณเรียกใช้ผู้ติดป้ายกํากับ คําขอที่คุณสร้าง ก่อนที่การดาวน์โหลดจะเสร็จสมบูรณ์ จะไม่พบผลลัพธ์
เพิ่มทรัพยากร Dependency ของ
linkFirebase
หากต้องการดาวน์โหลดโมเดลแบบไดนามิกจาก Firebase ให้ทําดังนี้สําหรับการดาวน์โหลดโมเดลแบบไดนามิกจาก Firebase ให้เพิ่มทรัพยากร Dependency ของ
linkFirebase
ดังนี้dependencies { // ... // Image labeling feature with model downloaded from Firebase implementation 'com.google.mlkit:image-labeling-custom:17.0.1' // Or use the dynamically downloaded pipeline in Google Play Services // implementation 'com.google.android.gms:play-services-mlkit-image-labeling-custom:16.0.0-beta4' implementation 'com.google.mlkit:linkfirebase:17.0.0' }
หากต้องการดาวน์โหลดโมเดล โปรดตรวจสอบว่าได้เพิ่ม Firebase ลงในโปรเจ็กต์ Android หากยังไม่ได้ทํา ซึ่งไม่จําเป็นเมื่อคุณรวมโมเดล
1. โหลดโมเดล
กําหนดค่าแหล่งที่มาของโมเดลในเครื่อง
วิธีรวมโมเดลกับแอป
คัดลอกไฟล์โมเดล (โดยปกติจะลงท้ายด้วย
.tflite
หรือ.lite
) ไปยังโฟลเดอร์assets/
ของแอป (คุณอาจต้องสร้างโฟลเดอร์ก่อนโดยคลิกขวาที่โฟลเดอร์app/
แล้วคลิกใหม่ > โฟลเดอร์ > โฟลเดอร์เนื้อหา)จากนั้นเพิ่มรายการต่อไปนี้ในไฟล์
build.gradle
ของแอปเพื่อให้ Gradle ไม่บีบอัดไฟล์โมเดลเมื่อสร้างแอปandroid { // ... aaptOptions { noCompress "tflite" // or noCompress "lite" } }
ไฟล์โมเดลจะรวมอยู่ในแพ็กเกจแอปและพร้อมใช้งานสําหรับ ML Kit เป็นเนื้อหาดิบ
สร้างออบเจ็กต์
LocalModel
โดยระบุเส้นทางไปยังไฟล์โมเดลKotlin
val localModel = LocalModel.Builder() .setAssetFilePath("model.tflite") // or .setAbsoluteFilePath(absolute file path to model file) // or .setUri(URI to model file) .build()
Java
LocalModel localModel = new LocalModel.Builder() .setAssetFilePath("model.tflite") // or .setAbsoluteFilePath(absolute file path to model file) // or .setUri(URI to model file) .build();
กําหนดค่าแหล่งที่มาของโมเดลที่โฮสต์ใน Firebase
หากต้องการใช้โมเดลที่โฮสต์จากระยะไกล ให้สร้างออบเจ็กต์ RemoteModel
ภายในวันที่ FirebaseModelSource
โดยระบุชื่อที่กําหนดให้กับโมเดลเมื่อคุณเผยแพร่
Kotlin
// Specify the name you assigned in the Firebase console. val remoteModel = CustomRemoteModel .Builder(FirebaseModelSource.Builder("your_model_name").build()) .build()
Java
// Specify the name you assigned in the Firebase console. CustomRemoteModel remoteModel = new CustomRemoteModel .Builder(new FirebaseModelSource.Builder("your_model_name").build()) .build();
จากนั้นให้เริ่มงานการดาวน์โหลดโมเดล โดยระบุเงื่อนไขที่คุณต้องการอนุญาตการดาวน์โหลด หากโมเดลไม่ได้อยู่ในอุปกรณ์หรือหากมีโมเดลเวอร์ชันใหม่กว่า งานจะดาวน์โหลดโมเดลจาก Firebase แบบไม่พร้อมกันโดยทําดังนี้
Kotlin
val downloadConditions = DownloadConditions.Builder() .requireWifi() .build() RemoteModelManager.getInstance().download(remoteModel, downloadConditions) .addOnSuccessListener { // Success. }
Java
DownloadConditions downloadConditions = new DownloadConditions.Builder() .requireWifi() .build(); RemoteModelManager.getInstance().download(remoteModel, downloadConditions) .addOnSuccessListener(new OnSuccessListener() { @Override public void onSuccess(@NonNull Task task) { // Success. } });
แอปจํานวนมากเริ่มงานดาวน์โหลดในโค้ดเริ่มต้น แต่คุณสามารถทําได้ทุกเมื่อก่อนที่จะต้องใช้โมเดล
กําหนดค่าผู้ติดป้ายกํากับรูปภาพ
หลังจากที่กําหนดค่าแหล่งที่มาของโมเดลแล้ว ให้สร้างออบเจ็กต์ ImageLabeler
จากหนึ่งในออบเจ็กต์เหล่านั้น
โดยมีตัวเลือกดังต่อไปนี้
ตัวเลือก | |
---|---|
confidenceThreshold
|
คะแนนความเชื่อมั่นขั้นต่ําสําหรับป้ายกํากับที่ตรวจพบ หากไม่ได้ตั้งค่า ระบบจะใช้เกณฑ์ตัวแยกประเภทที่ระบุโดยข้อมูลเมตาของโมเดล หากโมเดลไม่มีข้อมูลเมตาหรือข้อมูลเมตาไม่ได้ระบุเกณฑ์ของตัวแยกประเภท ระบบจะใช้เกณฑ์เริ่มต้นซึ่งก็คือ 0.0 |
maxResultCount
|
จํานวนป้ายกํากับสูงสุดที่จะแสดง หากไม่ได้ตั้งค่า ระบบจะใช้ค่าเริ่มต้นของ 10 |
หากมีเฉพาะโมเดลที่จัดกลุ่มไว้ในเครื่อง เพียงสร้างผู้ติดป้ายกํากับจากออบเจ็กต์ LocalModel
ดังนี้
Kotlin
val customImageLabelerOptions = CustomImageLabelerOptions.Builder(localModel) .setConfidenceThreshold(0.5f) .setMaxResultCount(5) .build() val labeler = ImageLabeling.getClient(customImageLabelerOptions)
Java
CustomImageLabelerOptions customImageLabelerOptions = new CustomImageLabelerOptions.Builder(localModel) .setConfidenceThreshold(0.5f) .setMaxResultCount(5) .build(); ImageLabeler labeler = ImageLabeling.getClient(customImageLabelerOptions);
หากมีโมเดลที่โฮสต์จากระยะไกล คุณจะต้องตรวจสอบว่าโมเดลนั้นดาวน์โหลดแล้วก่อนที่จะเรียกใช้ คุณตรวจสอบสถานะของงานดาวน์โหลดโมเดลได้โดยใช้เมธอด isModelDownloaded()
ของผู้จัดการโมเดล
แม้ว่าคุณต้องยืนยันเรื่องนี้ก่อนเรียกใช้ผู้ติดป้ายกํากับ แต่หากคุณมีทั้งโมเดลที่โฮสต์จากระยะไกลและโมเดลแบบกลุ่มในเครื่อง คุณก็ควรตรวจสอบเรื่องนี้เมื่อสร้างอินสแตนซ์ผู้ติดป้ายกํากับรูปภาพ: สร้างผู้ติดป้ายกํากับจากโมเดลระยะไกลหากได้ดาวน์โหลดมาจากโมเดลในเครื่อง
Kotlin
RemoteModelManager.getInstance().isModelDownloaded(remoteModel) .addOnSuccessListener { isDownloaded -> val optionsBuilder = if (isDownloaded) { CustomImageLabelerOptions.Builder(remoteModel) } else { CustomImageLabelerOptions.Builder(localModel) } val options = optionsBuilder .setConfidenceThreshold(0.5f) .setMaxResultCount(5) .build() val labeler = ImageLabeling.getClient(options) }
Java
RemoteModelManager.getInstance().isModelDownloaded(remoteModel) .addOnSuccessListener(new OnSuccessListener() { @Override public void onSuccess(Boolean isDownloaded) { CustomImageLabelerOptions.Builder optionsBuilder; if (isDownloaded) { optionsBuilder = new CustomImageLabelerOptions.Builder(remoteModel); } else { optionsBuilder = new CustomImageLabelerOptions.Builder(localModel); } CustomImageLabelerOptions options = optionsBuilder .setConfidenceThreshold(0.5f) .setMaxResultCount(5) .build(); ImageLabeler labeler = ImageLabeling.getClient(options); } });
หากคุณมีเฉพาะโมเดลที่โฮสต์จากระยะไกล คุณควรปิดใช้ฟังก์ชันที่เกี่ยวข้องกับโมเดล เช่น เป็นสีเทาหรือซ่อน UI บางส่วน จนกว่าจะยืนยันว่าดาวน์โหลดโมเดลแล้ว ซึ่งทําได้โดยแนบ Listener กับเมธอด download()
ของผู้จัดการโมเดล
Kotlin
RemoteModelManager.getInstance().download(remoteModel, conditions) .addOnSuccessListener { // Download complete. Depending on your app, you could enable the ML // feature, or switch from the local model to the remote model, etc. }
Java
RemoteModelManager.getInstance().download(remoteModel, conditions) .addOnSuccessListener(new OnSuccessListener() { @Override public void onSuccess(Void v) { // Download complete. Depending on your app, you could enable // the ML feature, or switch from the local model to the remote // model, etc. } });
2. เตรียมรูปภาพอินพุต
จากนั้นสร้างออบเจ็กต์InputImage
จากรูปภาพแต่ละรูปที่ต้องการติดป้ายกํากับ ตัวติดป้ายกํากับรูปภาพจะทํางานเร็วที่สุดเมื่อคุณใช้ Bitmap
หรือหากคุณใช้ Camera2 API ซึ่งเป็น YUV_420_888 media.Image
ซึ่งแนะนําให้ใช้เมื่อทําได้
คุณสามารถสร้างออบเจ็กต์ InputImage
จากแหล่งที่มาต่างๆ ซึ่งอธิบายไว้ด้านล่าง
การใช้ media.Image
หากต้องการสร้างออบเจ็กต์ InputImage
จากออบเจ็กต์ media.Image
เช่น เมื่อคุณจับภาพจากกล้องของอุปกรณ์ ให้ส่งออบเจ็กต์ media.Image
และการหมุนรูปภาพไปที่ InputImage.fromMediaImage()
หากคุณใช้ไลบรารี CameraX คลาส OnImageCapturedListener
และ ImageAnalysis.Analyzer
จะคํานวณค่าการหมุนเวียนสําหรับคุณ
Kotlin
private class YourImageAnalyzer : ImageAnalysis.Analyzer { override fun analyze(imageProxy: ImageProxy) { val mediaImage = imageProxy.image if (mediaImage != null) { val image = InputImage.fromMediaImage(mediaImage, imageProxy.imageInfo.rotationDegrees) // Pass image to an ML Kit Vision API // ... } } }
Java
private class YourAnalyzer implements ImageAnalysis.Analyzer { @Override public void analyze(ImageProxy imageProxy) { Image mediaImage = imageProxy.getImage(); if (mediaImage != null) { InputImage image = InputImage.fromMediaImage(mediaImage, imageProxy.getImageInfo().getRotationDegrees()); // Pass image to an ML Kit Vision API // ... } } }
หากไม่ได้ใช้ไลบรารีกล้องที่ให้ระดับการหมุนของรูปภาพ คุณจะคํานวณได้จากระดับการหมุนของอุปกรณ์และการวางแนวของเซ็นเซอร์กล้องในอุปกรณ์ ดังนี้
Kotlin
private val ORIENTATIONS = SparseIntArray() init { ORIENTATIONS.append(Surface.ROTATION_0, 0) ORIENTATIONS.append(Surface.ROTATION_90, 90) ORIENTATIONS.append(Surface.ROTATION_180, 180) ORIENTATIONS.append(Surface.ROTATION_270, 270) } /** * Get the angle by which an image must be rotated given the device's current * orientation. */ @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) @Throws(CameraAccessException::class) private fun getRotationCompensation(cameraId: String, activity: Activity, isFrontFacing: Boolean): Int { // Get the device's current rotation relative to its "native" orientation. // Then, from the ORIENTATIONS table, look up the angle the image must be // rotated to compensate for the device's rotation. val deviceRotation = activity.windowManager.defaultDisplay.rotation var rotationCompensation = ORIENTATIONS.get(deviceRotation) // Get the device's sensor orientation. val cameraManager = activity.getSystemService(CAMERA_SERVICE) as CameraManager val sensorOrientation = cameraManager .getCameraCharacteristics(cameraId) .get(CameraCharacteristics.SENSOR_ORIENTATION)!! if (isFrontFacing) { rotationCompensation = (sensorOrientation + rotationCompensation) % 360 } else { // back-facing rotationCompensation = (sensorOrientation - rotationCompensation + 360) % 360 } return rotationCompensation }
Java
private static final SparseIntArray ORIENTATIONS = new SparseIntArray(); static { ORIENTATIONS.append(Surface.ROTATION_0, 0); ORIENTATIONS.append(Surface.ROTATION_90, 90); ORIENTATIONS.append(Surface.ROTATION_180, 180); ORIENTATIONS.append(Surface.ROTATION_270, 270); } /** * Get the angle by which an image must be rotated given the device's current * orientation. */ @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) private int getRotationCompensation(String cameraId, Activity activity, boolean isFrontFacing) throws CameraAccessException { // Get the device's current rotation relative to its "native" orientation. // Then, from the ORIENTATIONS table, look up the angle the image must be // rotated to compensate for the device's rotation. int deviceRotation = activity.getWindowManager().getDefaultDisplay().getRotation(); int rotationCompensation = ORIENTATIONS.get(deviceRotation); // Get the device's sensor orientation. CameraManager cameraManager = (CameraManager) activity.getSystemService(CAMERA_SERVICE); int sensorOrientation = cameraManager .getCameraCharacteristics(cameraId) .get(CameraCharacteristics.SENSOR_ORIENTATION); if (isFrontFacing) { rotationCompensation = (sensorOrientation + rotationCompensation) % 360; } else { // back-facing rotationCompensation = (sensorOrientation - rotationCompensation + 360) % 360; } return rotationCompensation; }
จากนั้นส่งออบเจ็กต์ media.Image
และค่าองศาการหมุนเวียนไปยัง InputImage.fromMediaImage()
ดังนี้
Kotlin
val image = InputImage.fromMediaImage(mediaImage, rotation)
Java
InputImage image = InputImage.fromMediaImage(mediaImage, rotation);
การใช้ URI ของไฟล์
หากต้องการสร้างออบเจ็กต์ InputImage
จาก URI ของไฟล์ ให้ส่งบริบทของแอปและ URI ของไฟล์ไปยัง InputImage.fromFilePath()
ซึ่งจะมีประโยชน์เมื่อคุณใช้ Intent ACTION_GET_CONTENT
เพื่อแจ้งให้ผู้ใช้เลือกรูปภาพจากแอปแกลเลอรีของตน
Kotlin
val image: InputImage try { image = InputImage.fromFilePath(context, uri) } catch (e: IOException) { e.printStackTrace() }
Java
InputImage image; try { image = InputImage.fromFilePath(context, uri); } catch (IOException e) { e.printStackTrace(); }
การใช้ ByteBuffer
หรือ ByteArray
หากต้องการสร้างออบเจ็กต์ InputImage
จาก ByteBuffer
หรือ ByteArray
ให้คํานวณระดับการหมุนเวียนรูปภาพตามที่อธิบายไว้ก่อนหน้านี้สําหรับอินพุต media.Image
จากนั้นสร้างออบเจ็กต์ InputImage
ที่มีบัฟเฟอร์หรืออาร์เรย์ พร้อมด้วยความสูง ความกว้าง รูปแบบการเข้ารหัสสี และองศาการหมุนของรูปภาพ ดังนี้
Kotlin
val image = InputImage.fromByteBuffer( byteBuffer, /* image width */ 480, /* image height */ 360, rotationDegrees, InputImage.IMAGE_FORMAT_NV21 // or IMAGE_FORMAT_YV12 ) // Or: val image = InputImage.fromByteArray( byteArray, /* image width */ 480, /* image height */ 360, rotationDegrees, InputImage.IMAGE_FORMAT_NV21 // or IMAGE_FORMAT_YV12 )
Java
InputImage image = InputImage.fromByteBuffer(byteBuffer, /* image width */ 480, /* image height */ 360, rotationDegrees, InputImage.IMAGE_FORMAT_NV21 // or IMAGE_FORMAT_YV12 ); // Or: InputImage image = InputImage.fromByteArray( byteArray, /* image width */480, /* image height */360, rotation, InputImage.IMAGE_FORMAT_NV21 // or IMAGE_FORMAT_YV12 );
การใช้ Bitmap
หากต้องการสร้างออบเจ็กต์ InputImage
จากออบเจ็กต์ Bitmap
โปรดประกาศต่อไปนี้
Kotlin
val image = InputImage.fromBitmap(bitmap, 0)
Java
InputImage image = InputImage.fromBitmap(bitmap, rotationDegree);
รูปภาพแทนออบเจ็กต์ Bitmap
ร่วมกับองศาการหมุน
3. เรียกใช้ผู้ติดป้ายกํากับรูปภาพ
หากต้องการติดป้ายกํากับออบเจ็กต์ในรูปภาพ ให้ส่งออบเจ็กต์ image
ไปยังเมธอด process()
ของ ImageLabeler
Kotlin
labeler.process(image) .addOnSuccessListener { labels -> // Task completed successfully // ... } .addOnFailureListener { e -> // Task failed with an exception // ... }
Java
labeler.process(image) .addOnSuccessListener(new OnSuccessListener<List<ImageLabel>>() { @Override public void onSuccess(List<ImageLabel> labels) { // Task completed successfully // ... } }) .addOnFailureListener(new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { // Task failed with an exception // ... } });
4. ดูข้อมูลเกี่ยวกับเอนทิตีที่ติดป้ายกํากับ
หากการดําเนินการติดป้ายกํากับรูปภาพสําเร็จ ระบบจะส่งรายการออบเจ็กต์ImageLabel
ไปยัง Listener ที่ประสบความสําเร็จ ออบเจ็กต์ ImageLabel
แต่ละรายการแสดงถึงสิ่งที่มีการติดป้ายกํากับในรูปภาพ คุณจะได้รับคําอธิบายข้อความของแต่ละป้ายกํากับ (หากมีในข้อมูลเมตาของไฟล์โมเดล TensorFlow Lite) คะแนนความเชื่อมั่น และดัชนี เช่น
Kotlin
for (label in labels) { val text = label.text val confidence = label.confidence val index = label.index }
Java
for (ImageLabel label : labels) { String text = label.getText(); float confidence = label.getConfidence(); int index = label.getIndex(); }
เคล็ดลับในการปรับปรุงประสิทธิภาพแบบเรียลไทม์
หากต้องการติดป้ายกํากับรูปภาพในแอปพลิเคชันแบบเรียลไทม์ ให้ทําตามหลักเกณฑ์ต่อไปนี้เพื่อให้อัตราเฟรมดีที่สุด
- หากใช้
Camera
หรือcamera2
API คุณจะควบคุมการเรียกผู้ติดป้ายกํากับรูปภาพได้ หากเฟรมวิดีโอใหม่พร้อมใช้งานขณะที่ผู้ติดป้ายกํากับรูปภาพทํางานอยู่ ให้วางเฟรมนั้น ดูตัวอย่างคลาสVisionProcessorBase
ในแอปตัวอย่างคู่มือเริ่มต้นฉบับย่อ - หากคุณใช้ API
CameraX
โปรดตรวจสอบว่าได้ตั้งค่ากลยุทธ์ความกดดันเป็นค่าเริ่มต้นImageAnalysis.STRATEGY_KEEP_ONLY_LATEST
ตัวเลือกนี้จะรับประกันว่าจะมีการส่งรูปภาพสําหรับการวิเคราะห์ข้อมูลเพียงครั้งละ 1 รูป หากมีการสร้างรูปภาพเพิ่มเติมเมื่อเครื่องมือวิเคราะห์ไม่ว่าง รูปภาพเหล่านั้นจะถูกทิ้งโดยอัตโนมัติและไม่อยู่ในคิวเพื่อนําส่ง เมื่อปิดรูปภาพที่จะวิเคราะห์แล้วโดยเรียก ImageProxy.close() ระบบจะส่งรูปภาพล่าสุดถัดไป - หากใช้เอาต์พุตของผู้ติดป้ายกํากับรูปภาพเพื่อวางซ้อนกราฟิกบนรูปภาพอินพุต ก่อนอื่นให้ดูผลลัพธ์จาก ML Kit จากนั้นแสดงภาพและการวางซ้อนในขั้นตอนเดียว วิธีนี้จะแสดงผลบนแพลตฟอร์มจอแสดงผลเพียงครั้งเดียวสําหรับเฟรมอินพุตแต่ละเฟรม ดูตัวอย่างคลาส
CameraSourcePreview
และGraphicOverlay
ในแอปตัวอย่างเริ่มต้นอย่างรวดเร็ว - หากใช้ Camera2 API ให้จับภาพในรูปแบบ
ImageFormat.YUV_420_888
หากคุณใช้ Camera API เวอร์ชันเก่า ให้จับภาพในรูปแบบImageFormat.NV21