চিত্র বিশ্লেষণ

ইমেজ অ্যানালাইসিস ইউজ কেস আপনার অ্যাপকে একটি CPU- অ্যাক্সেসযোগ্য ইমেজ প্রদান করে যার উপর আপনি ইমেজ প্রসেসিং, কম্পিউটার ভিশন বা মেশিন লার্নিং ইনফারেন্স করতে পারবেন। অ্যাপ্লিকেশনটি একটি analyze() পদ্ধতি প্রয়োগ করে যা প্রতিটি ফ্রেমে চালানো হয়।

কিভাবে আপনার CameraX অ্যাপের সাথে Google-এর ML কিট সংহত করতে হয় তা জানতে, ML Kit Analyzer দেখুন।

অপারেটিং মোড

যখন অ্যাপ্লিকেশানের বিশ্লেষণ পাইপলাইন CameraX এর ফ্রেম হারের প্রয়োজনীয়তাগুলি মেনে চলতে পারে না, তখন CameraX নিম্নলিখিত উপায়গুলির মধ্যে একটিতে ফ্রেম ড্রপ করার জন্য কনফিগার করা যেতে পারে:

  • নন-ব্লকিং (ডিফল্ট): এই মোডে, এক্সিকিউটর সর্বদা লেটেস্ট ইমেজটিকে একটি ইমেজ বাফারে ক্যাশে করে (একটির গভীরতা সহ একটি সারির অনুরূপ) যখন অ্যাপ্লিকেশনটি পূর্ববর্তী চিত্রটি বিশ্লেষণ করে। অ্যাপ্লিকেশান প্রক্রিয়াকরণ শেষ হওয়ার আগে CameraX একটি নতুন চিত্র গ্রহণ করলে, নতুন চিত্রটি একই বাফারে সংরক্ষণ করা হয়, পূর্ববর্তী চিত্রটি ওভাররাইট করে। মনে রাখবেন ImageAnalysis.Builder.setImageQueueDepth() এই পরিস্থিতিতে কোন প্রভাব নেই, এবং বাফার বিষয়বস্তু সবসময় ওভাররাইট করা হয়। আপনি STRATEGY_KEEP_ONLY_LATEST এর সাথে setBackpressureStrategy() এ কল করে এই নন-ব্লকিং মোড সক্ষম করতে পারেন। নির্বাহক প্রভাব সম্পর্কে আরও তথ্যের জন্য, STRATEGY_KEEP_ONLY_LATEST এর রেফারেন্স ডকুমেন্টেশন দেখুন।

  • ব্লক করা : এই মোডে, অভ্যন্তরীণ নির্বাহক অভ্যন্তরীণ চিত্র সারিতে একাধিক ছবি যোগ করতে পারে এবং সারিতে পূর্ণ হলেই ফ্রেম ড্রপ করা শুরু করে। ব্লকিং সম্পূর্ণ ক্যামেরা ডিভাইস স্কোপ জুড়ে ঘটে: ক্যামেরা ডিভাইসের একাধিক বাউন্ড ইউজ কেস থাকলে, ক্যামেরাএক্স এই ইমেজগুলি প্রক্রিয়া করার সময় সেই সমস্ত ব্যবহারের কেসগুলি ব্লক করা হবে। উদাহরণস্বরূপ, যখন পূর্বরূপ এবং চিত্র বিশ্লেষণ উভয়ই একটি ক্যামেরা ডিভাইসের সাথে আবদ্ধ থাকে, তখন ক্যামেরাএক্স চিত্রগুলি প্রক্রিয়া করার সময় পূর্বরূপও ব্লক করা হবে। আপনি STRATEGY_BLOCK_PRODUCER setBackpressureStrategy() এ পাস করে ব্লকিং মোড সক্ষম করতে পারেন। এছাড়াও আপনি ImageAnalysis.Builder.setImageQueueDepth() ব্যবহার করে ছবির সারির গভীরতা কনফিগার করতে পারেন।

একটি কম লেটেন্সি এবং উচ্চ পারফরম্যান্স বিশ্লেষকের সাথে যেখানে একটি ছবি বিশ্লেষণ করার মোট সময় একটি CameraX ফ্রেমের সময়কালের চেয়ে কম (উদাহরণস্বরূপ 60fps এর জন্য 16ms), হয় অপারেটিং মোড একটি মসৃণ সামগ্রিক অভিজ্ঞতা প্রদান করে। ব্লকিং মোড এখনও কিছু পরিস্থিতিতে সহায়ক হতে পারে, যেমন খুব সংক্ষিপ্ত সিস্টেম জিটারগুলির সাথে ডিল করার সময়।

একটি উচ্চ লেটেন্সি এবং উচ্চ কার্যক্ষমতা বিশ্লেষক সহ, দীর্ঘ সারির সাথে ব্লকিং মোডটি বিলম্বের জন্য ক্ষতিপূরণের জন্য প্রয়োজনীয়। নোট করুন, যাইহোক, অ্যাপ্লিকেশনটি এখনও সমস্ত ফ্রেম প্রক্রিয়া করতে পারে।

একটি উচ্চ লেটেন্সি এবং সময়-সাপেক্ষ বিশ্লেষক (বিশ্লেষক সমস্ত ফ্রেম প্রক্রিয়া করতে অক্ষম) সহ, একটি নন-ব্লকিং মোড একটি আরও উপযুক্ত পছন্দ হতে পারে, কারণ বিশ্লেষণের পথের জন্য ফ্রেমগুলি বাদ দিতে হবে, তবে অন্যান্য সমসাময়িক আবদ্ধ ব্যবহারের ক্ষেত্রে এখনও দেখা যেতে পারে। সমস্ত ফ্রেম

বাস্তবায়ন

আপনার অ্যাপ্লিকেশনে চিত্র বিশ্লেষণ ব্যবহার করতে, এই পদক্ষেপগুলি অনুসরণ করুন:

বাঁধাই করার পরপরই, CameraX আপনার নিবন্ধিত বিশ্লেষকের কাছে ছবি পাঠায়। বিশ্লেষণ শেষ করার পর, ImageAnalysis.clearAnalyzer() কল করুন বা বিশ্লেষণ বন্ধ করতে ImageAnalysis ব্যবহারের ক্ষেত্রের আবদ্ধতা মুক্ত করুন।

ইমেজ অ্যানালাইসিস ব্যবহার কেস তৈরি করুন

ImageAnalysis আপনার বিশ্লেষককে (একটি ইমেজ ভোক্তা) CameraX এর সাথে সংযুক্ত করে, যা একটি ইমেজ প্রযোজক। অ্যাপ্লিকেশন একটি ImageAnalysis অবজেক্ট তৈরি করতে ImageAnalysis.Builder ব্যবহার করতে পারে। ImageAnalysis.Builder এর সাথে, অ্যাপ্লিকেশন নিম্নলিখিতগুলি কনফিগার করতে পারে:

অ্যাপ্লিকেশনগুলি রেজোলিউশন বা আকৃতির অনুপাত সেট করতে পারে, তবে উভয়ই নয়। সঠিক আউটপুট রেজোলিউশন অ্যাপ্লিকেশনটির অনুরোধকৃত আকার (বা আকৃতির অনুপাত) এবং হার্ডওয়্যার ক্ষমতার উপর নির্ভর করে এবং অনুরোধকৃত আকার বা অনুপাত থেকে ভিন্ন হতে পারে। রেজোলিউশন ম্যাচিং অ্যালগরিদম সম্পর্কে তথ্যের জন্য, setTargetResolution() এর জন্য ডকুমেন্টেশন দেখুন

একটি অ্যাপ্লিকেশন YUV (ডিফল্ট) বা RGBA কালার স্পেসে আউটপুট ইমেজ পিক্সেল কনফিগার করতে পারে। একটি RGBA আউটপুট বিন্যাস সেট করার সময়, CameraX অভ্যন্তরীণভাবে চিত্রগুলিকে YUV থেকে RGBA কালার স্পেসে রূপান্তর করে এবং ইমেজপ্রক্সির প্রথম প্লেনের ByteBuffer চিত্র বিটগুলি প্যাক করে (অন্য দুটি প্লেন ব্যবহার করা হয় না) নিম্নলিখিত ক্রম অনুসারে:

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 পায়, যা Media.Image- এর জন্য একটি মোড়ক। ইমেজ ফরম্যাটটি ImageProxy.getFormat() দিয়ে জিজ্ঞাসা করা যেতে পারে। বিন্যাসটি নিম্নলিখিত মানগুলির মধ্যে একটি যা অ্যাপ্লিকেশনটি ImageAnalysis.Builder দিয়ে প্রদান করে:

  • ImageFormat.RGBA_8888 যদি অ্যাপটি OUTPUT_IMAGE_FORMAT_RGBA_8888 অনুরোধ করে।
  • ImageFormat.YUV_420_888 যদি অ্যাপটি OUTPUT_IMAGE_FORMAT_YUV_420_888 অনুরোধ করে।

কালার স্পেস কনফিগারেশনের জন্য বিল্ড ইমেজ অ্যানালাইসিস ব্যবহার কেস দেখুন এবং যেখানে পিক্সেল বাইটগুলি পুনরুদ্ধার করা যেতে পারে।

একটি বিশ্লেষকের ভিতরে, অ্যাপ্লিকেশনটি নিম্নলিখিতগুলি করা উচিত:

  1. একটি প্রদত্ত ফ্রেম যত তাড়াতাড়ি সম্ভব বিশ্লেষণ করুন, বিশেষত প্রদত্ত ফ্রেম রেট সময়সীমার মধ্যে (উদাহরণস্বরূপ, 30 fps ক্ষেত্রের জন্য 32ms এর কম)। যদি অ্যাপ্লিকেশনটি একটি ফ্রেমকে যথেষ্ট দ্রুত বিশ্লেষণ করতে না পারে, তাহলে সমর্থিত ফ্রেম ড্রপিং প্রক্রিয়াগুলির একটি বিবেচনা করুন৷
  2. ImageProxy.close() কল করে CameraX-এ ImageProxy ছেড়ে দিন। মনে রাখবেন যে আপনি আবৃত Media.Image এর ক্লোজ ফাংশন ( Media.Image.close() ) কল করবেন না।

অ্যাপ্লিকেশন সরাসরি ImageProxy ভিতরে আবৃত Media.Image ব্যবহার করতে পারে. শুধু আবৃত ছবিতে Media.Image.close() কল করবেন না কারণ এটি CameraX-এর ভিতরে ইমেজ শেয়ারিং মেকানিজম ভেঙে দেবে; পরিবর্তে, CameraX-এ অন্তর্নিহিত Media.Image প্রকাশ করতে ImageProxy.close() ব্যবহার করুন।

ইমেজ অ্যানালাইসিসের জন্য আপনার বিশ্লেষক কনফিগার করুন

একবার আপনি একটি বিশ্লেষক তৈরি করলে, বিশ্লেষণ শুরু করতে এটি নিবন্ধন করতে ImageAnalysis.setAnalyzer() ব্যবহার করুন। একবার আপনার বিশ্লেষণ শেষ হলে, নিবন্ধিত বিশ্লেষকটি সরাতে ImageAnalysis.clearAnalyzer() ব্যবহার করুন।

শুধুমাত্র একটি সক্রিয় বিশ্লেষক ইমেজ বিশ্লেষণের জন্য কনফিগার করা যেতে পারে. ImageAnalysis.setAnalyzer() কল করা নিবন্ধিত বিশ্লেষককে প্রতিস্থাপন করে যদি এটি ইতিমধ্যে বিদ্যমান থাকে। অ্যাপ্লিকেশনগুলি ব্যবহারের ক্ষেত্রে বাঁধাই করার আগে বা পরে যে কোনও সময় একটি নতুন বিশ্লেষক সেট করতে পারে।

একটি জীবনচক্রে চিত্র বিশ্লেষণ আবদ্ধ করুন

ProcessCameraProvider.bindToLifecycle() ফাংশনের সাথে একটি বিদ্যমান AndroidX লাইফসাইকেলে আপনার ImageAnalysis আবদ্ধ করার জন্য এটি অত্যন্ত সুপারিশ করা হয়। মনে রাখবেন bindToLifecycle() ফাংশন নির্বাচিত Camera ডিভাইস ফেরত দেয়, যা এক্সপোজার এবং অন্যান্যের মতো উন্নত সেটিংস ঠিক করতে ব্যবহার করা যেতে পারে। ক্যামেরা আউটপুট নিয়ন্ত্রণ সম্পর্কে আরও তথ্যের জন্য এই নির্দেশিকা দেখুন।

নিম্নলিখিত উদাহরণটি পূর্ববর্তী পদক্ষেপগুলি থেকে সমস্ত কিছুকে একত্রিত করে, ক্যামেরাএক্স 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)

জাভা

ImageAnalysis imageAnalysis =
    new ImageAnalysis.Builder()
        // enable the following line if RGBA output is needed.
        //.setOutputImageFormat(ImageAnalysis.OUTPUT_IMAGE_FORMAT_RGBA_8888)
        .setTargetResolution(new Size(1280, 720))
        .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
        .build();

imageAnalysis.setAnalyzer(executor, new ImageAnalysis.Analyzer() {
    @Override
    public void analyze(@NonNull ImageProxy imageProxy) {
        int rotationDegrees = imageProxy.getImageInfo().getRotationDegrees();
            // insert your code here.
            ...
            // after done, release the ImageProxy object
            imageProxy.close();
        }
    });

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

অতিরিক্ত সম্পদ

CameraX সম্পর্কে আরও জানতে, নিম্নলিখিত অতিরিক্ত সংস্থানগুলি দেখুন৷

কোডল্যাব

  • CameraX দিয়ে শুরু করা
  • কোড নমুনা

  • CameraX নমুনা অ্যাপ