মেশিন লার্নিং মডেলের জন্য ইনপুট হিসাবে ARCore ব্যবহার করুন

আপনি একটি বুদ্ধিমান অগমেন্টেড রিয়েলিটি অভিজ্ঞতা তৈরি করতে মেশিন লার্নিং পাইপলাইনে ARCore ক্যাপচার করা ক্যামেরা ফিড ব্যবহার করতে পারেন। ARCore ML কিট নমুনা দেখায় কিভাবে বাস্তব-বিশ্বের বস্তু শনাক্ত করতে ML Kit এবং Google Cloud Vision API ব্যবহার করতে হয়। নমুনা ক্যামেরার দৃশ্যে বস্তুর শ্রেণীবিভাগ করার জন্য একটি মেশিন লার্নিং মডেল ব্যবহার করে এবং ভার্চুয়াল দৃশ্যে বস্তুর সাথে একটি লেবেল সংযুক্ত করে।

ARCore ML কিট নমুনা কোটলিনে লেখা আছে। এটি ARCore SDK GitHub সংগ্রহস্থলে ml_kotlin নমুনা অ্যাপ হিসেবেও উপলব্ধ।

ARCore এর CPU ইমেজ ব্যবহার করুন

ARCore ডিফল্টরূপে ইমেজ স্ট্রিমের অন্তত দুটি সেট ক্যাপচার করে:

  • বৈশিষ্ট্য শনাক্তকরণ এবং চিত্র প্রক্রিয়াকরণের জন্য ব্যবহৃত একটি CPU ইমেজ স্ট্রিম । ডিফল্টরূপে, CPU ইমেজের একটি রেজোলিউশন VGA (640x480) থাকে। ARCore প্রয়োজন হলে একটি অতিরিক্ত উচ্চ রেজোলিউশন ইমেজ স্ট্রিম ব্যবহার করার জন্য কনফিগার করা যেতে পারে।
  • একটি GPU টেক্সচার স্ট্রীম , যাতে একটি উচ্চ-রেজোলিউশন টেক্সচার থাকে, সাধারণত 1080p এর রেজোলিউশনে। এটি সাধারণত ব্যবহারকারী-মুখী ক্যামেরা প্রিভিউ হিসাবে ব্যবহৃত হয়। এটি Session.setCameraTextureName() দ্বারা নির্দিষ্ট OpenGL টেক্সচারে সংরক্ষণ করা হয়।
  • SharedCamera.setAppSurfaces() দ্বারা নির্দিষ্ট করা কোনো অতিরিক্ত স্ট্রীম।

CPU ইমেজ সাইজ বিবেচনা

ডিফল্ট VGA-আকারের CPU স্ট্রীম ব্যবহার করা হলে কোনো অতিরিক্ত খরচ হবে না কারণ ARCore এই স্ট্রীমটি বিশ্ব বোঝার জন্য ব্যবহার করে। একটি ভিন্ন রেজোলিউশন সহ একটি স্ট্রিমের অনুরোধ করা ব্যয়বহুল হতে পারে, কারণ একটি অতিরিক্ত স্ট্রিম ক্যাপচার করতে হবে৷ মনে রাখবেন যে একটি উচ্চতর রেজোলিউশন আপনার মডেলের জন্য দ্রুত ব্যয়বহুল হয়ে উঠতে পারে: চিত্রের প্রস্থ এবং উচ্চতা দ্বিগুণ করলে ছবিতে পিক্সেলের পরিমাণ চারগুণ হয়।

ইমেজ ডাউনস্কেল করা সুবিধাজনক হতে পারে, যদি আপনার মডেল এখনও কম রেজোলিউশনের ছবিতে ভালো পারফর্ম করতে পারে।

একটি অতিরিক্ত উচ্চ রেজোলিউশন CPU ইমেজ স্ট্রিম কনফিগার করুন

আপনার ML মডেলের কর্মক্ষমতা ইনপুট হিসাবে ব্যবহৃত ছবির রেজোলিউশনের উপর নির্ভর করতে পারে। Session.setCameraConfig() ব্যবহার করে বর্তমান CameraConfig পরিবর্তন করে, Session.getSupportedCameraConfigs() থেকে একটি বৈধ কনফিগারেশন নির্বাচন করে এই স্ট্রিমগুলির রেজোলিউশন সামঞ্জস্য করা যেতে পারে।

জাভা

CameraConfigFilter cameraConfigFilter =
    new CameraConfigFilter(session)
        // World-facing cameras only.
        .setFacingDirection(CameraConfig.FacingDirection.BACK);
List<CameraConfig> supportedCameraConfigs =
    session.getSupportedCameraConfigs(cameraConfigFilter);

// Select an acceptable configuration from supportedCameraConfigs.
CameraConfig cameraConfig = selectCameraConfig(supportedCameraConfigs);
session.setCameraConfig(cameraConfig);

কোটলিন

val cameraConfigFilter =
  CameraConfigFilter(session)
    // World-facing cameras only.
    .setFacingDirection(CameraConfig.FacingDirection.BACK)
val supportedCameraConfigs = session.getSupportedCameraConfigs(cameraConfigFilter)

// Select an acceptable configuration from supportedCameraConfigs.
val cameraConfig = selectCameraConfig(supportedCameraConfigs)
session.setCameraConfig(cameraConfig)

CPU ইমেজ পুনরুদ্ধার করুন

Frame.acquireCameraImage() ব্যবহার করে CPU ইমেজ পুনরুদ্ধার করুন। এই ছবিগুলির আর প্রয়োজন না হওয়ার সাথে সাথেই নিষ্পত্তি করা উচিত৷

জাভা

Image cameraImage = null;
try {
  cameraImage = frame.acquireCameraImage();
  // Process `cameraImage` using your ML inference model.
} catch (NotYetAvailableException e) {
  // NotYetAvailableException is an exception that can be expected when the camera is not ready
  // yet. The image may become available on a next frame.
} catch (RuntimeException e) {
  // A different exception occurred, e.g. DeadlineExceededException, ResourceExhaustedException.
  // Handle this error appropriately.
  handleAcquireCameraImageFailure(e);
} finally {
  if (cameraImage != null) {
    cameraImage.close();
  }
}

কোটলিন

// NotYetAvailableException is an exception that can be expected when the camera is not ready yet.
// Map it to `null` instead, but continue to propagate other errors.
fun Frame.tryAcquireCameraImage() =
  try {
    acquireCameraImage()
  } catch (e: NotYetAvailableException) {
    null
  } catch (e: RuntimeException) {
    // A different exception occurred, e.g. DeadlineExceededException, ResourceExhaustedException.
    // Handle this error appropriately.
    handleAcquireCameraImageFailure(e)
  }

// The `use` block ensures the camera image is disposed of after use.
frame.tryAcquireCameraImage()?.use { image ->
  // Process `image` using your ML inference model.
}

CPU ইমেজ প্রসেস করুন

CPU ইমেজ প্রক্রিয়া করার জন্য, বিভিন্ন মেশিন লার্নিং লাইব্রেরি ব্যবহার করা যেতে পারে।

আপনার AR দৃশ্যে ফলাফল প্রদর্শন করুন

চিত্র শনাক্তকরণ মডেলগুলি প্রায়শই একটি কেন্দ্র বিন্দু বা শনাক্ত করা বস্তুর প্রতিনিধিত্বকারী একটি আবদ্ধ বহুভুজ নির্দেশ করে সনাক্ত করা বস্তুগুলিকে আউটপুট করে।

মডেল থেকে আউটপুট করা বাউন্ডিং বাক্সের কেন্দ্র বিন্দু বা কেন্দ্র ব্যবহার করে, সনাক্ত করা বস্তুর সাথে একটি অ্যাঙ্কর সংযুক্ত করা সম্ভব। ভার্চুয়াল দৃশ্যে একটি বস্তুর ভঙ্গি অনুমান করতে Frame.hitTest() ব্যবহার করুন।

IMAGE_PIXELS স্থানাঙ্কগুলিকে VIEW স্থানাঙ্কে রূপান্তর করুন:

জাভা

// Suppose `mlResult` contains an (x, y) of a given point on the CPU image.
float[] cpuCoordinates = new float[] {mlResult.getX(), mlResult.getY()};
float[] viewCoordinates = new float[2];
frame.transformCoordinates2d(
    Coordinates2d.IMAGE_PIXELS, cpuCoordinates, Coordinates2d.VIEW, viewCoordinates);
// `viewCoordinates` now contains coordinates suitable for hit testing.

কোটলিন

// Suppose `mlResult` contains an (x, y) of a given point on the CPU image.
val cpuCoordinates = floatArrayOf(mlResult.x, mlResult.y)
val viewCoordinates = FloatArray(2)
frame.transformCoordinates2d(
  Coordinates2d.IMAGE_PIXELS,
  cpuCoordinates,
  Coordinates2d.VIEW,
  viewCoordinates
)
// `viewCoordinates` now contains coordinates suitable for hit testing.

একটি হিট পরীক্ষা পরিচালনা করতে এবং ফলাফল থেকে একটি অ্যাঙ্কর তৈরি করতে এই VIEW কোঅর্ডিনেটগুলি ব্যবহার করুন:

জাভা

List<HitResult> hits = frame.hitTest(viewCoordinates[0], viewCoordinates[1]);
HitResult depthPointResult = null;
for (HitResult hit : hits) {
  if (hit.getTrackable() instanceof DepthPoint) {
    depthPointResult = hit;
    break;
  }
}
if (depthPointResult != null) {
  Anchor anchor = depthPointResult.getTrackable().createAnchor(depthPointResult.getHitPose());
  // This anchor will be attached to the scene with stable tracking.
  // It can be used as a position for a virtual object, with a rotation prependicular to the
  // estimated surface normal.
}

কোটলিন

val hits = frame.hitTest(viewCoordinates[0], viewCoordinates[1])
val depthPointResult = hits.filter { it.trackable is DepthPoint }.firstOrNull()
if (depthPointResult != null) {
  val anchor = depthPointResult.trackable.createAnchor(depthPointResult.hitPose)
  // This anchor will be attached to the scene with stable tracking.
  // It can be used as a position for a virtual object, with a rotation prependicular to the
  // estimated surface normal.
}

কর্মক্ষমতা বিবেচনা

প্রক্রিয়াকরণ শক্তি বাঁচাতে এবং কম শক্তি খরচ করতে নিম্নলিখিত সুপারিশগুলি অনুসরণ করুন:

  • প্রতিটি ইনকামিং ফ্রেমে আপনার এমএল মডেল চালাবেন না। পরিবর্তে কম ফ্রেমরেটে অবজেক্ট ডিটেকশন চালানোর কথা বিবেচনা করুন।
  • কম্পিউটেশনাল জটিলতা কমাতে একটি অনলাইন এমএল ইনফারেন্স মডেল বিবেচনা করুন।

পরবর্তী পদক্ষেপ