ML Kit یک SDK بهینهسازی شده برای تقسیمبندی سلفی فراهم میکند. دارایی های Selfie Segmenter به صورت ایستا به برنامه شما در زمان ساخت مرتبط هستند. این اندازه برنامه شما را تا 24 مگابایت افزایش میدهد و تأخیر API میتواند بسته به اندازه تصویر ورودی، همانطور که در iPhone X اندازهگیری میشود، از 7 میلیثانیه تا 12 میلیثانیه متغیر باشد.
آن را امتحان کنید
- با برنامه نمونه بازی کنید تا نمونه استفاده از این API را ببینید.
قبل از شروع
کتابخانه های ML Kit زیر را در فایل پادفایل خود قرار دهید:
pod 'GoogleMLKit/SegmentationSelfie', '15.5.0'
پس از نصب یا به روز رسانی Pods پروژه خود، پروژه Xcode خود را با استفاده از آن باز کنید.
xcworkspace
. ML Kit در Xcode نسخه 13.2.1 یا بالاتر پشتیبانی می شود.
1. یک نمونه از Segmenter ایجاد کنید
برای انجام بخش بندی روی یک تصویر سلفی، ابتدا یک نمونه از Segmenter
با SelfieSegmenterOptions
ایجاد کنید و به صورت اختیاری تنظیمات تقسیم بندی را مشخص کنید.
گزینه های بخش بندی
حالت بخش بندی
Segmenter
در دو حالت عمل می کند. مطمئن شوید که موردی را انتخاب می کنید که با مورد استفاده شما مطابقت دارد.
STREAM_MODE (default)
این حالت برای پخش فریم ها از فیلم یا دوربین طراحی شده است. در این حالت، قطعهساز از نتایج فریمهای قبلی استفاده میکند تا نتایج تقسیمبندی نرمتر را برگرداند.
SINGLE_IMAGE_MODE (default)
این حالت برای تصاویر تکی طراحی شده است که مرتبط نیستند. در این حالت، قطعهساز هر تصویر را بهطور مستقل پردازش میکند، بدون هموارسازی فریمها.
ماسک اندازه خام را فعال کنید
از قطعهساز میخواهد تا ماسک اندازه خام را که با اندازه خروجی مدل مطابقت دارد، برگرداند.
اندازه ماسک خام (به عنوان مثال 256x256) معمولاً کوچکتر از اندازه تصویر ورودی است.
بدون تعیین این گزینه، قطعهساز ماسک خام را تغییر مقیاس میدهد تا با اندازه تصویر ورودی مطابقت داشته باشد. اگر می خواهید منطق تغییر مقیاس سفارشی شده را اعمال کنید یا برای مورد استفاده شما نیازی به تغییر مقیاس نیست، از این گزینه استفاده کنید.
گزینه های قطعه ساز را مشخص کنید:
سویفت
let options = SelfieSegmenterOptions() options.segmenterMode = .singleImage options.shouldEnableRawSizeMask = true
هدف-C
MLKSelfieSegmenterOptions *options = [[MLKSelfieSegmenterOptions alloc] init]; options.segmenterMode = MLKSegmenterModeSingleImage; options.shouldEnableRawSizeMask = YES;
در نهایت، یک نمونه از Segmenter
را دریافت کنید. گزینه هایی که مشخص کردید را پاس کنید:
سویفت
let segmenter = Segmenter.segmenter(options: options)
هدف-C
MLKSegmenter *segmenter = [MLKSegmenter segmenterWithOptions:options];
2. تصویر ورودی را آماده کنید
برای تقسیمبندی سلفیها، موارد زیر را برای هر تصویر یا فریم ویدیو انجام دهید. اگر حالت استریم را فعال کرده اید، باید اشیاء VisionImage
را از CMSampleBuffer
s ایجاد کنید.
با استفاده از UIImage
یا CMSampleBuffer
یک شی VisionImage
ایجاد کنید.
اگر از UIImage
استفاده می کنید، این مراحل را دنبال کنید:
- با
UIImage
یک شیVisionImage
ایجاد کنید. مطمئن شوید که جهت.orientation
را مشخص کرده اید.سویفت
let image = VisionImage(image: UIImage) visionImage.orientation = image.imageOrientation
هدف-C
MLKVisionImage *visionImage = [[MLKVisionImage alloc] initWithImage:image]; visionImage.orientation = image.imageOrientation;
اگر از
CMSampleBuffer
استفاده می کنید، این مراحل را دنبال کنید:جهت داده های تصویر موجود در
CMSampleBuffer
را مشخص کنید.برای دریافت جهت تصویر:
سویفت
func imageOrientation( deviceOrientation: UIDeviceOrientation, cameraPosition: AVCaptureDevice.Position ) -> UIImage.Orientation { switch deviceOrientation { case .portrait: return cameraPosition == .front ? .leftMirrored : .right case .landscapeLeft: return cameraPosition == .front ? .downMirrored : .up case .portraitUpsideDown: return cameraPosition == .front ? .rightMirrored : .left case .landscapeRight: return cameraPosition == .front ? .upMirrored : .down case .faceDown, .faceUp, .unknown: return .up } }
هدف-C
- (UIImageOrientation) imageOrientationFromDeviceOrientation:(UIDeviceOrientation)deviceOrientation cameraPosition:(AVCaptureDevicePosition)cameraPosition { switch (deviceOrientation) { case UIDeviceOrientationPortrait: return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationLeftMirrored : UIImageOrientationRight; case UIDeviceOrientationLandscapeLeft: return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationDownMirrored : UIImageOrientationUp; case UIDeviceOrientationPortraitUpsideDown: return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationRightMirrored : UIImageOrientationLeft; case UIDeviceOrientationLandscapeRight: return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationUpMirrored : UIImageOrientationDown; case UIDeviceOrientationUnknown: case UIDeviceOrientationFaceUp: case UIDeviceOrientationFaceDown: return UIImageOrientationUp; } }
- یک شی
VisionImage
با استفاده از شیCMSampleBuffer
و جهت گیری ایجاد کنید:سویفت
let image = VisionImage(buffer: sampleBuffer) image.orientation = imageOrientation( deviceOrientation: UIDevice.current.orientation, cameraPosition: cameraPosition)
هدف-C
MLKVisionImage *image = [[MLKVisionImage alloc] initWithBuffer:sampleBuffer]; image.orientation = [self imageOrientationFromDeviceOrientation:UIDevice.currentDevice.orientation cameraPosition:cameraPosition];
3. تصویر را پردازش کنید
شی
VisionImage
را به یکی از روش های پردازش تصویرSegmenter
ارسال کنید. می توانید از روشprocess(image:)
یا روشresults(in:)
استفاده کنید.برای انجام بخش بندی روی یک تصویر سلفی به طور همزمان:
سویفت
var mask: [SegmentationMask] do { mask = try segmenter.results(in: image) } catch let error { print("Failed to perform segmentation with error: \(error.localizedDescription).") return } // Success. Get a segmentation mask here.
هدف-C
NSError *error; MLKSegmentationMask *mask = [segmenter resultsInImage:image error:&error]; if (error != nil) { // Error. return; } // Success. Get a segmentation mask here.
برای انجام بخش بندی روی یک تصویر سلفی به صورت ناهمزمان:
سویفت
segmenter.process(image) { mask, error in guard error == nil else { // Error. return } // Success. Get a segmentation mask here.
هدف-C
[segmenter processImage:image completion:^(MLKSegmentationMask * _Nullable mask, NSError * _Nullable error) { if (error != nil) { // Error. return; } // Success. Get a segmentation mask here. }];
4. ماسک تقسیم بندی را دریافت کنید
شما می توانید نتیجه تقسیم بندی را به صورت زیر بدست آورید:
سویفت
let maskWidth = CVPixelBufferGetWidth(mask.buffer) let maskHeight = CVPixelBufferGetHeight(mask.buffer) CVPixelBufferLockBaseAddress(mask.buffer, CVPixelBufferLockFlags.readOnly) let maskBytesPerRow = CVPixelBufferGetBytesPerRow(mask.buffer) var maskAddress = CVPixelBufferGetBaseAddress(mask.buffer)!.bindMemory( to: Float32.self, capacity: maskBytesPerRow * maskHeight) for _ in 0...(maskHeight - 1) { for col in 0...(maskWidth - 1) { // Gets the confidence of the pixel in the mask being in the foreground. let foregroundConfidence: Float32 = maskAddress[col] } maskAddress += maskBytesPerRow / MemoryLayout<Float32>.size }
هدف-C
size_t width = CVPixelBufferGetWidth(mask.buffer); size_t height = CVPixelBufferGetHeight(mask.buffer); CVPixelBufferLockBaseAddress(mask.buffer, kCVPixelBufferLock_ReadOnly); size_t maskBytesPerRow = CVPixelBufferGetBytesPerRow(mask.buffer); float *maskAddress = (float *)CVPixelBufferGetBaseAddress(mask.buffer); for (int row = 0; row < height; ++row) { for (int col = 0; col < width; ++col) { // Gets the confidence of the pixel in the mask being in the foreground. float foregroundConfidence = maskAddress[col]; } maskAddress += maskBytesPerRow / sizeof(float); }
برای مثال کاملی از نحوه استفاده از نتایج تقسیمبندی، لطفاً نمونه راهاندازی سریع کیت ML را ببینید.
نکاتی برای بهبود عملکرد
کیفیت نتایج شما به کیفیت تصویر ورودی بستگی دارد:
- برای اینکه ML Kit به یک نتیجه تقسیم بندی دقیق دست یابد، تصویر باید حداقل 256x256 پیکسل باشد.
- اگر قطعهبندی سلفی را در یک برنامه بلادرنگ انجام میدهید، ممکن است بخواهید ابعاد کلی تصاویر ورودی را نیز در نظر بگیرید. تصاویر کوچکتر را میتوان سریعتر پردازش کرد، بنابراین برای کاهش تأخیر، تصاویر را با رزولوشن پایینتر ثبت کنید، اما الزامات وضوح بالا را در نظر داشته باشید و اطمینان حاصل کنید که سوژه تا حد امکان تصویر را اشغال میکند.
- فوکوس ضعیف تصویر نیز می تواند بر دقت تأثیر بگذارد. اگر نتایج قابل قبولی دریافت نکردید، از کاربر بخواهید که تصویر را دوباره بگیرد.
اگر میخواهید از بخشبندی در یک برنامه بلادرنگ استفاده کنید، این دستورالعملها را برای دستیابی به بهترین نرخ فریم دنبال کنید:
- از حالت قطعهساز
stream
استفاده کنید. - گرفتن تصاویر با وضوح کمتر را در نظر بگیرید. با این حال، الزامات ابعاد تصویر این API را نیز در نظر داشته باشید.
- برای پردازش فریمهای ویدیویی، از API همگام
results(in:)
قطعهساز استفاده کنید. این روش را از تابع captureOutput(_, didOutput:from:) AVCaptureVideoDataOutputSampleBufferDelegate فراخوانی کنید تا به طور همزمان نتایج را از فریم ویدیوی داده شده دریافت کنید. همیشه DiscardsLateVideoFrames های AVCaptureVideoDataOutput را برای کاهش تماس ها با قطعه ساز درست نگه دارید. اگر یک قاب ویدیویی جدید در حین اجرای قطعهساز در دسترس باشد، حذف میشود. - اگر از خروجی قطعهساز برای همپوشانی گرافیک روی تصویر ورودی استفاده میکنید، ابتدا نتیجه را از ML Kit دریافت کنید، سپس تصویر را رندر کنید و در یک مرحله همپوشانی کنید. با انجام این کار، برای هر فریم ورودی پردازش شده فقط یک بار به سطح نمایشگر رندر می دهید. برای مثال، کلاسهای previewOverlayView و CameraViewController را در نمونه راهاندازی سریع ML Kit ببینید.
جز در مواردی که غیر از این ذکر شده باشد،محتوای این صفحه تحت مجوز Creative Commons Attribution 4.0 License است. نمونه کدها نیز دارای مجوز Apache 2.0 License است. برای اطلاع از جزئیات، به خطمشیهای سایت Google Developers مراجعه کنید. جاوا علامت تجاری ثبتشده Oracle و/یا شرکتهای وابسته به آن است.
تاریخ آخرین بهروزرسانی 2024-11-12 بهوقت ساعت هماهنگ جهانی.
[null,null,["تاریخ آخرین بهروزرسانی 2024-11-12 بهوقت ساعت هماهنگ جهانی."],[],[]]