সেলফির মতো ছবি এবং ভিডিওতে মুখ শনাক্ত করতে আপনি এমএল কিট ব্যবহার করতে পারেন।
ফেস মেশ ডিটেকশন API | |
---|---|
SDK নাম | face-mesh-detection |
বাস্তবায়ন | কোড এবং সম্পদগুলি বিল্ড টাইমে আপনার অ্যাপের সাথে স্ট্যাটিকভাবে লিঙ্ক করা হয়। |
অ্যাপের আকারের প্রভাব | ~6.4MB |
কর্মক্ষমতা | বেশিরভাগ ডিভাইসে রিয়েল-টাইম। |
চেষ্টা করে দেখুন
- এই API এর একটি উদাহরণ ব্যবহার দেখতে নমুনা অ্যাপের সাথে খেলুন।
আপনি শুরু করার আগে
আপনার প্রকল্প-স্তরের
build.gradle
ফাইলে, আপনার বিল্ডস্ক্রিপ্ট এবং সমস্ত প্রকল্প উভয় বিভাগেই Google-এর Maven সংগ্রহস্থল অন্তর্ভুক্ত করা নিশ্চিত করুন৷আপনার মডিউলের অ্যাপ-লেভেল গ্রেডল ফাইলে এমএল কিট ফেস মেশ ডিটেকশন লাইব্রেরির জন্য নির্ভরতা যোগ করুন, যা সাধারণত
app/build.gradle
হয় :dependencies { // ... implementation 'com.google.mlkit:face-mesh-detection:16.0.0-beta1' }
ইনপুট ইমেজ নির্দেশিকা
ডিভাইস ক্যামেরা থেকে ~2 মিটার (~7 ফুট) মধ্যে ছবি তোলা উচিত, যাতে মুখগুলি সর্বোত্তম ফেস মেশ সনাক্তকরণের জন্য যথেষ্ট বড় হয়। সাধারণভাবে, মুখ যত বড় হবে, ফেস মেশ রিকগনিশন তত ভালো হবে।
মুখটি ক্যামেরার মুখোমুখি হওয়া উচিত যাতে মুখের অন্তত অর্ধেক দৃশ্যমান হয়। মুখ এবং ক্যামেরার মধ্যে যেকোন বড় বস্তুর নির্ভুলতা কম হতে পারে।
আপনি যদি একটি রিয়েল-টাইম অ্যাপ্লিকেশনে মুখগুলি সনাক্ত করতে চান তবে আপনার ইনপুট চিত্রের সামগ্রিক মাত্রাগুলিও বিবেচনা করা উচিত৷ ছোট ছবিগুলি দ্রুত প্রক্রিয়া করা যেতে পারে, তাই কম রেজোলিউশনে ছবিগুলি ক্যাপচার করা লেটেন্সি হ্রাস করে৷ যাইহোক, উপরের নির্ভুলতার প্রয়োজনীয়তাগুলি মনে রাখবেন এবং নিশ্চিত করুন যে সাবজেক্টের মুখ যতটা সম্ভব ছবিটি দখল করে।
ফেস মেশ ডিটেক্টর কনফিগার করুন
আপনি যদি ফেস মেশ ডিটেক্টরের ডিফল্ট সেটিংস পরিবর্তন করতে চান তবে একটি FaceMeshDetectorOptions অবজেক্টের সাথে সেই সেটিংস নির্দিষ্ট করুন। আপনি নিম্নলিখিত সেটিংস পরিবর্তন করতে পারেন:
setUseCase
BOUNDING_BOX_ONLY
: সনাক্ত করা ফেস মেশের জন্য শুধুমাত্র একটি বাউন্ডিং বক্স প্রদান করে। এটি দ্রুততম ফেস ডিটেক্টর, তবে এর পরিসীমা সীমাবদ্ধতা রয়েছে (মুখগুলি অবশ্যই ক্যামেরার ~2 মিটার বা ~7 ফুটের মধ্যে হতে হবে)।FACE_MESH
(ডিফল্ট বিকল্প): একটি বাউন্ডিং বক্স এবং অতিরিক্ত ফেস মেশ তথ্য (468 3D পয়েন্ট এবং ত্রিভুজ তথ্য) প্রদান করে।BOUNDING_BOX_ONLY
ব্যবহারের ক্ষেত্রে তুলনা করলে, Pixel 3-এ পরিমাপ করা লেটেন্সি ~15% বৃদ্ধি পায়।
যেমন:
কোটলিন
val defaultDetector = FaceMeshDetection.getClient( FaceMeshDetectorOptions.DEFAULT_OPTIONS) val boundingBoxDetector = FaceMeshDetection.getClient( FaceMeshDetectorOptions.Builder() .setUseCase(UseCase.BOUNDING_BOX_ONLY) .build() )
জাভা
FaceMeshDetector defaultDetector = FaceMeshDetection.getClient( FaceMeshDetectorOptions.DEFAULT_OPTIONS); FaceMeshDetector boundingBoxDetector = FaceMeshDetection.getClient( new FaceMeshDetectorOptions.Builder() .setUseCase(UseCase.BOUNDING_BOX_ONLY) .build() );
ইনপুট ইমেজ প্রস্তুত করুন
একটি ছবিতে মুখ সনাক্ত করতে, একটি Bitmap
, media.Image
ইমেজ , ByteBuffer
, বাইট অ্যারে বা ডিভাইসে একটি ফাইল থেকে একটি InputImage
অবজেক্ট তৈরি করুন৷ তারপর, FaceDetector
এর process
পদ্ধতিতে InputImage
অবজেক্টটি পাস করুন।
ফেস মেশ সনাক্তকরণের জন্য, আপনার কমপক্ষে 480x360 পিক্সেলের মাত্রা সহ একটি চিত্র ব্যবহার করা উচিত। আপনি যদি রিয়েল টাইমে মুখগুলি সনাক্ত করে থাকেন, তাহলে এই ন্যূনতম রেজোলিউশনে ফ্রেমগুলি ক্যাপচার করা লেটেন্সি কমাতে সাহায্য করতে পারে৷
আপনি বিভিন্ন উত্স থেকে একটি InputImage
অবজেক্ট তৈরি করতে পারেন, প্রতিটি নীচে ব্যাখ্যা করা হয়েছে৷
একটি media.Image
ব্যবহার করে. ইমেজ
একটি media.Image
থেকে একটি InputImage
অবজেক্ট তৈরি করতে। ইমেজ অবজেক্ট, যেমন আপনি যখন একটি ডিভাইসের ক্যামেরা থেকে একটি ইমেজ ক্যাপচার করেন, তখন media.Image
পাস করুন। ইমেজ অবজেক্ট এবং ইমেজের রোটেশন InputImage.fromMediaImage()
এ।
আপনি যদি CameraX লাইব্রেরি ব্যবহার করেন, OnImageCapturedListener
এবং ImageAnalysis.Analyzer
ক্লাসগুলি আপনার জন্য ঘূর্ণন মান গণনা করে৷
কোটলিন
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 // ... } } }
জাভা
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 // ... } } }
আপনি যদি এমন একটি ক্যামেরা লাইব্রেরি ব্যবহার না করেন যা আপনাকে চিত্রের ঘূর্ণন ডিগ্রী দেয়, আপনি ডিভাইসের ঘূর্ণন ডিগ্রী এবং ডিভাইসে ক্যামেরা সেন্সরের অভিযোজন থেকে এটি গণনা করতে পারেন:
কোটলিন
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 }
জাভা
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()
এ পাস করুন :
কোটলিন
val image = InputImage.fromMediaImage(mediaImage, rotation)
Java
InputImage image = InputImage.fromMediaImage(mediaImage, rotation);
একটি ফাইল ইউআরআই ব্যবহার করে
একটি ফাইল URI থেকে একটি InputImage
অবজেক্ট তৈরি করতে, অ্যাপের প্রসঙ্গ এবং ফাইল URIকে InputImage.fromFilePath()
এ পাস করুন। এটি উপযোগী যখন আপনি একটি ACTION_GET_CONTENT
উদ্দেশ্য ব্যবহার করে ব্যবহারকারীকে তাদের গ্যালারি অ্যাপ থেকে একটি ছবি নির্বাচন করতে অনুরোধ করেন৷
কোটলিন
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
ব্যবহার করে
একটি ByteBuffer
বা একটি ByteArray
থেকে একটি InputImage
অবজেক্ট তৈরি করতে, প্রথমে media.Image
ইনপুটের জন্য পূর্বে বর্ণিত চিত্রের ঘূর্ণন ডিগ্রি গণনা করুন৷ তারপরে, ছবির উচ্চতা, প্রস্থ, রঙ এনকোডিং বিন্যাস এবং ঘূর্ণন ডিগ্রী সহ বাফার বা অ্যারে সহ InputImage
অবজেক্ট তৈরি করুন:
কোটলিন
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 )
জাভা
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
ব্যবহার করে
একটি Bitmap
বস্তু থেকে একটি InputImage
অবজেক্ট তৈরি করতে, নিম্নলিখিত ঘোষণা করুন:
কোটলিন
val image = InputImage.fromBitmap(bitmap, 0)
Java
InputImage image = InputImage.fromBitmap(bitmap, rotationDegree);
চিত্রটি ঘূর্ণন ডিগ্রী সহ একটি Bitmap
বস্তু দ্বারা উপস্থাপিত হয়।
চিত্রটি প্রক্রিয়া করুন
process
পদ্ধতিতে চিত্রটি পাস করুন:
কোটলিন
val result = detector.process(image) .addOnSuccessListener { result -> // Task completed successfully // … } .addOnFailureListener { e -> // Task failed with an exception // … }
জাভা
Task<List<FaceMesh>> result = detector.process(image) .addOnSuccessListener( new OnSuccessListener<List<FaceMesh>>() { @Override public void onSuccess(List<FaceMesh> result) { // Task completed successfully // … } }) .addOnFailureListener( new OnFailureListener() { @Override Public void onFailure(Exception e) { // Task failed with an exception // … } });
সনাক্ত করা ফেস মেশ সম্পর্কে তথ্য পান
ছবিতে কোনো মুখ শনাক্ত করা হলে, FaceMesh
বস্তুর একটি তালিকা সফল শ্রোতার কাছে পাঠানো হয়। প্রতিটি FaceMesh
একটি মুখের প্রতিনিধিত্ব করে যা ছবিতে সনাক্ত করা হয়েছিল। প্রতিটি ফেস মেশের জন্য, আপনি ইনপুট ইমেজে এর বাউন্ডিং কোঅর্ডিনেট পেতে পারেন, সেইসাথে আপনি ফেস মেশ ডিটেক্টরকে খুঁজে বের করার জন্য কনফিগার করেছেন এমন অন্য কোনো তথ্য।
কোটলিন
for (faceMesh in faceMeshs) { val bounds: Rect = faceMesh.boundingBox() // Gets all points val faceMeshpoints = faceMesh.allPoints for (faceMeshpoint in faceMeshpoints) { val index: Int = faceMeshpoints.index() val position = faceMeshpoint.position } // Gets triangle info val triangles: List<Triangle<FaceMeshPoint>> = faceMesh.allTriangles for (triangle in triangles) { // 3 Points connecting to each other and representing a triangle area. val connectedPoints = triangle.allPoints() } }
জাভা
for (FaceMesh faceMesh : faceMeshs) { Rect bounds = faceMesh.getBoundingBox(); // Gets all points List<FaceMeshPoint> faceMeshpoints = faceMesh.getAllPoints(); for (FaceMeshPoint faceMeshpoint : faceMeshpoints) { int index = faceMeshpoints.getIndex(); PointF3D position = faceMeshpoint.getPosition(); } // Gets triangle info List<Triangle<FaceMeshPoint>> triangles = faceMesh.getAllTriangles(); for (Triangle<FaceMeshPoint> triangle : triangles) { // 3 Points connecting to each other and representing a triangle area. List<FaceMeshPoint> connectedPoints = triangle.getAllPoints(); } }
অন্য কিছু উল্লেখ না করা থাকলে, এই পৃষ্ঠার কন্টেন্ট Creative Commons Attribution 4.0 License-এর অধীনে এবং কোডের নমুনাগুলি Apache 2.0 License-এর অধীনে লাইসেন্স প্রাপ্ত। আরও জানতে, Google Developers সাইট নীতি দেখুন। Java হল Oracle এবং/অথবা তার অ্যাফিলিয়েট সংস্থার রেজিস্টার্ড ট্রেডমার্ক।
2024-11-13 UTC-তে শেষবার আপডেট করা হয়েছে।