การวิเคราะห์รูปภาพ

กรณีการใช้งานการวิเคราะห์รูปภาพจะช่วยให้แอปของคุณมีรูปภาพที่ CPU เข้าถึงได้ ซึ่งคุณสามารถประมวลผลรูปภาพ คอมพิวเตอร์วิทัศน์ หรือการอนุมานแมชชีนเลิร์นนิงได้ แอปพลิเคชันจะใช้เมธอด analyze() ที่ทำงานในแต่ละเฟรม

ดูวิธีผสานรวม ML Kit ของ Google กับแอป CameraX ได้ที่เครื่องมือวิเคราะห์ ML Kit

โหมดการทำงาน

เมื่อไปป์ไลน์การวิเคราะห์ของแอปพลิเคชันไม่สามารถทำงานตามข้อกำหนดอัตราเฟรมของ CameraX ได้ คุณสามารถกำหนดค่า CameraX ให้ข้ามเฟรมได้ด้วยวิธีใดวิธีหนึ่งต่อไปนี้

  • ไม่บล็อก (ค่าเริ่มต้น): ในโหมดนี้ ผู้ดำเนินการจะแคชรูปภาพล่าสุดลงในบัฟเฟอร์รูปภาพเสมอ (คล้ายกับคิวที่มีความลึก 1) ขณะที่แอปพลิเคชันวิเคราะห์รูปภาพก่อนหน้า หาก CameraX ได้รับรูปภาพใหม่ก่อนที่แอปพลิเคชันจะประมวลผลเสร็จ ระบบจะบันทึกรูปภาพใหม่ลงในบัฟเฟอร์เดียวกัน โดยเขียนทับรูปภาพก่อนหน้า โปรดทราบว่า ImageAnalysis.Builder.setImageQueueDepth() ไม่มีผลในสถานการณ์นี้ และเนื้อหาบัฟเฟอร์จะถูกเขียนทับเสมอ คุณเปิดใช้โหมดไม่บล็อกนี้ได้โดยเรียกใช้ setBackpressureStrategy() ด้วย STRATEGY_KEEP_ONLY_LATEST ดูข้อมูลเพิ่มเติมเกี่ยวกับผลกระทบของ Executor ได้ที่เอกสารอ้างอิงสำหรับ STRATEGY_KEEP_ONLY_LATEST

  • blocking: ในโหมดนี้ Executor ภายในสามารถเพิ่มรูปภาพหลายรูปไปยังคิวรูปภาพภายใน และจะเริ่มทิ้งเฟรมเมื่อคิวเต็มเท่านั้น การบล็อกจะเกิดขึ้นในขอบเขตอุปกรณ์กล้องทั้งหมด กล่าวคือ หากอุปกรณ์กล้องมี Use Case ที่เชื่อมโยงหลายรายการ ระบบจะบล็อก Use Case เหล่านั้นทั้งหมดขณะที่ CameraX กำลังประมวลผลรูปภาพเหล่านี้ ตัวอย่างเช่น เมื่อทั้งตัวอย่างและการวิเคราะห์รูปภาพเชื่อมโยงกับอุปกรณ์กล้อง ตัวอย่างก็จะถูกบล็อกด้วยขณะที่ CameraX กำลังประมวลผลรูปภาพ คุณเปิดใช้โหมดการบล็อกได้โดยส่ง STRATEGY_BLOCK_PRODUCER ไปยัง setBackpressureStrategy() นอกจากนี้ คุณยังกำหนดค่าความลึกของคิวรูปภาพได้โดยใช้ ImageAnalysis.Builder.setImageQueueDepth()

ด้วยเครื่องมือวิเคราะห์ที่มีเวลาในการตอบสนองต่ำและประสิทธิภาพสูง ซึ่งเวลาทั้งหมดในการวิเคราะห์รูปภาพน้อยกว่าระยะเวลาของเฟรม CameraX (เช่น 16 มิลลิวินาทีสำหรับ 60 FPS) โหมดการทำงานทั้ง 2 โหมดจะมอบประสบการณ์การใช้งานโดยรวมที่ราบรื่น โหมดการบล็อกยังคงมีประโยชน์ในบางสถานการณ์ เช่น เมื่อต้องรับมือกับความผันผวนของระบบที่เกิดขึ้นเป็นระยะเวลาสั้นๆ

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

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

การใช้งาน

หากต้องการใช้การวิเคราะห์รูปภาพในแอปพลิเคชัน ให้ทำตามขั้นตอนต่อไปนี้

ทันทีหลังจากเชื่อมโยง CameraX จะส่งรูปภาพไปยังเครื่องมือวิเคราะห์ที่ลงทะเบียนไว้ หลังจากวิเคราะห์เสร็จแล้ว ให้เรียกใช้ ImageAnalysis.clearAnalyzer() หรือเลิกเชื่อมโยงกรณีการใช้งาน ImageAnalysis เพื่อหยุดการวิเคราะห์

สร้าง Use Case ของ ImageAnalysis

ImageAnalysis จะเชื่อมต่อเครื่องมือวิเคราะห์ (ผู้ใช้รูปภาพ) กับ CameraX ซึ่งเป็นผู้สร้างรูปภาพ แอปพลิเคชันสามารถใช้ ImageAnalysis.Builder เพื่อสร้างออบเจ็กต์ ImageAnalysis เมื่อใช้ ImageAnalysis.Builder แอปพลิเคชันจะกำหนดค่าต่อไปนี้ได้

แอปพลิเคชันสามารถตั้งค่าความละเอียดหรือสัดส่วนภาพได้ แต่จะตั้งค่าทั้ง 2 อย่างไม่ได้ ความละเอียดเอาต์พุตที่แน่นอนจะขึ้นอยู่กับขนาด (หรือสัดส่วนภาพ) ที่แอปพลิเคชันขอและความสามารถของฮาร์ดแวร์ และอาจแตกต่างจากขนาดหรือสัดส่วนที่ขอ ดูข้อมูลเกี่ยวกับอัลกอริทึมการจับคู่ความละเอียดได้ในเอกสารประกอบของ setTargetResolution()

แอปพลิเคชันสามารถกำหนดค่าพิกเซลภาพของรูปภาพเอาต์พุตให้อยู่ในขอบเขตสี YUV (ค่าเริ่มต้น) หรือ RGBA ได้ เมื่อตั้งค่ารูปแบบเอาต์พุต RGBA แล้ว CameraX จะแปลงรูปภาพจากขอบเขตสี YUV เป็น RGBA ภายใน และรวมบิตรูปภาพไว้ใน ByteBuffer ของระนาบแรกของ ImageProxy (ไม่ได้ใช้ระนาบอีก 2 ระนาบ) โดยมีลำดับดังนี้

ImageProxy.getPlanes()[0].buffer[0]: alpha
ImageProxy.getPlanes()[0].buffer[1]: red
ImageProxy.getPlanes()[0].buffer[2]: green
ImageProxy.getPlanes()[0].buffer[3]: blue
...

เมื่อทำการวิเคราะห์รูปภาพที่ซับซ้อนซึ่งอุปกรณ์ไม่สามารถรักษาอัตราเฟรมไว้ได้ คุณสามารถกำหนดค่า CameraX ให้ข้ามเฟรมได้ด้วยกลยุทธ์ที่อธิบายไว้ในส่วนโหมดการทำงานของหัวข้อนี้

สร้างเครื่องมือวิเคราะห์

แอปพลิเคชันสามารถสร้างเครื่องมือวิเคราะห์ได้โดยการติดตั้งใช้งานอินเทอร์เฟซ ImageAnalysis.Analyzer และลบล้าง analyze(ImageProxy image) ในเครื่องมือวิเคราะห์แต่ละรายการ แอปพลิเคชันจะได้รับ ImageProxy ซึ่งเป็น Wrapper สำหรับ Media.Image คุณค้นหารูปแบบรูปภาพได้ด้วย ImageProxy.getFormat() รูปแบบคือค่าใดค่าหนึ่งต่อไปนี้ที่แอปพลิเคชันระบุไว้ใน ImageAnalysis.Builder

  • ImageFormat.RGBA_8888 หากแอปขอ OUTPUT_IMAGE_FORMAT_RGBA_8888
  • ImageFormat.YUV_420_888 หากแอปขอ OUTPUT_IMAGE_FORMAT_YUV_420_888

ดูสร้างกรณีการใช้งาน ImageAnalysis สำหรับการกำหนดค่าขอบเขตสีและตำแหน่งที่สามารถดึงข้อมูลไบต์พิกเซลได้

ภายในเครื่องมือวิเคราะห์ แอปพลิเคชันควรทำสิ่งต่อไปนี้

  1. วิเคราะห์เฟรมที่กำหนดโดยเร็วที่สุด โดยควรอยู่ภายในขีดจำกัดเวลาของอัตราเฟรมที่กำหนด (เช่น น้อยกว่า 32 มิลลิวินาทีสำหรับกรณี 30 FPS) หากแอปพลิเคชันวิเคราะห์เฟรมได้ไม่เร็วพอ ให้พิจารณาใช้กลไกการข้ามเฟรมที่รองรับอย่างใดอย่างหนึ่ง
  2. ปล่อย ImageProxy ไปยัง CameraX โดยเรียกใช้ ImageProxy.close() โปรดทราบว่าคุณไม่ควรเรียกใช้ฟังก์ชันปิดของ Media.Image ที่รวมไว้ (Media.Image.close())

แอปพลิเคชันสามารถใช้ Media.Image ที่รวมไว้ภายใน ImageProxy ได้โดยตรง แต่อย่าเรียกใช้ Media.Image.close() ในรูปภาพที่รวมไว้ เนื่องจากจะทำให้กลไกการแชร์รูปภาพภายใน CameraX เสียหาย ให้ใช้ ImageProxy.close() เพื่อปล่อย Media.Image ที่เกี่ยวข้องไปยัง CameraX แทน

กำหนดค่าเครื่องมือวิเคราะห์สำหรับ ImageAnalysis

เมื่อสร้างเครื่องมือวิเคราะห์แล้ว ให้ใช้ ImageAnalysis.setAnalyzer() เพื่อลงทะเบียนเพื่อเริ่มการวิเคราะห์ เมื่อวิเคราะห์เสร็จแล้ว ให้ใช้ ImageAnalysis.clearAnalyzer() เพื่อนำเครื่องมือวิเคราะห์ที่ลงทะเบียนไว้ออก

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

เชื่อมโยง ImageAnalysis กับวงจร

เราขอแนะนำอย่างยิ่งให้เชื่อมโยง ImageAnalysis กับวงจร AndroidX ที่มีอยู่ด้วยฟังก์ชัน ProcessCameraProvider.bindToLifecycle() โปรดทราบว่าฟังก์ชัน bindToLifecycle() จะแสดงผลอุปกรณ์ Camera ที่เลือก ซึ่งสามารถใช้เพื่อปรับแต่งการตั้งค่าขั้นสูง เช่น การเปิดรับแสงและอื่นๆ ดูข้อมูลเพิ่มเติมเกี่ยวกับการควบคุมเอาต์พุตของกล้องได้ที่คู่มือนี้

ตัวอย่างต่อไปนี้รวมทุกอย่างจากขั้นตอนก่อนหน้า โดยเชื่อมโยง Use Case ของ CameraX ImageAnalysis และ Preview กับเจ้าของ lifeCycle

val imageAnalysis = ImageAnalysis.Builder()
    // enable the following line if RGBA output is needed.
    // .setOutputImageFormat(ImageAnalysis.OUTPUT_IMAGE_FORMAT_RGBA_8888)
    .setTargetResolution(Size(1280, 720))
    .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
    .build()
imageAnalysis.setAnalyzer(executor, ImageAnalysis.Analyzer { imageProxy ->
    val rotationDegrees = imageProxy.imageInfo.rotationDegrees
    // insert your code here.
    ...
    // after done, release the ImageProxy object
    imageProxy.close()
})

cameraProvider.bindToLifecycle(this as LifecycleOwner, cameraSelector, imageAnalysis, preview)

แหล่งข้อมูลเพิ่มเติม

ดูข้อมูลเพิ่มเติมเกี่ยวกับ CameraX ได้ที่แหล่งข้อมูลเพิ่มเติมต่อไปนี้

Codelab

  • เริ่มต้นใช้งาน CameraX
  • ตัวอย่างโค้ด

  • แอปตัวอย่าง CameraX