ML Kit menyediakan SDK yang dioptimalkan untuk segmentasi selfie. Aset Selfie Segmenter ditautkan secara statis ke aplikasi Anda pada waktu build. Ini akan meningkatkan ukuran aplikasi Anda hingga 24 MB dan latensi API dapat bervariasi dari ~7 md hingga ~12 md bergantung pada ukuran gambar input, seperti yang diukur di iPhone X.
Cobalah
- Cobalah aplikasi contoh untuk melihat contoh penggunaan API ini.
Sebelum memulai
Sertakan library ML Kit berikut di Podfile Anda:
pod 'GoogleMLKit/SegmentationSelfie', '3.2.0'
Setelah Anda menginstal atau mengupdate Pod project, buka project Xcode menggunakan file .
xcworkspace
. ML Kit didukung dalam Xcode versi 13.2.1 atau yang lebih tinggi.
1. Membuat instance Segmenter
Untuk melakukan segmentasi pada gambar selfie, pertama-tama buat instance Segmenter
dengan SelfieSegmenterOptions
dan tentukan setelan segmentasi secara opsional.
Opsi segmentasi
Mode Segmentasi
Segmenter
beroperasi dalam dua mode. Pastikan Anda memilih salah satu yang cocok dengan kasus penggunaan Anda.
STREAM_MODE (default)
Mode ini dirancang untuk streaming frame dari video atau kamera. Dalam mode ini, Segmenter akan memanfaatkan hasil dari frame sebelumnya untuk menampilkan hasil segmentasi yang lebih lancar.
SINGLE_IMAGE_MODE (default)
Mode ini didesain untuk gambar tunggal yang tidak terkait. Dalam mode ini, Segmenter akan memproses setiap gambar secara independen, tanpa ada penyesuaian pada frame.
Aktifkan mask ukuran mentah
Meminta pengklasifikasi untuk menampilkan mask ukuran mentah yang sesuai dengan ukuran output model.
Ukuran mask mentah (misalnya, 256x256) biasanya lebih kecil dari ukuran gambar input.
Tanpa menentukan opsi ini, pengelompok akan menskalakan ulang mask mentah agar sesuai dengan ukuran gambar input. Pertimbangkan untuk menggunakan opsi ini jika Anda ingin menerapkan logika penskalaan ulang yang disesuaikan atau penskalaan ulang tidak diperlukan untuk kasus penggunaan Anda.
Tentukan opsi pembagi segmen:
Swift
let options = SelfieSegmenterOptions() options.segmenterMode = .singleImage options.shouldEnableRawSizeMask = true
Objective-C
MLKSelfieSegmenterOptions *options = [[MLKSelfieSegmenterOptions alloc] init]; options.segmenterMode = MLKSegmenterModeSingleImage; options.shouldEnableRawSizeMask = YES;
Terakhir, dapatkan instance Segmenter
. Teruskan opsi yang Anda tentukan:
Swift
let segmenter = Segmenter.segmenter(options: options)
Objective-C
MLKSegmenter *segmenter = [MLKSegmenter segmenterWithOptions:options];
2. Menyiapkan gambar input
Untuk menyegmentasi selfie, lakukan tindakan berikut untuk setiap gambar atau frame video.
Jika mengaktifkan mode streaming, Anda harus membuat objek VisionImage
dari
CMSampleBuffer
dtk.
Buat objek VisionImage
menggunakan UIImage
atau objek
CMSampleBuffer
.
Jika Anda menggunakan UIImage
, ikuti langkah-langkah berikut:
- Buat objek
VisionImage
denganUIImage
. Pastikan untuk menentukan.orientation
yang benar.Swift
let image = VisionImage(image: UIImage) visionImage.orientation = image.imageOrientation
Objective-C
MLKVisionImage *visionImage = [[MLKVisionImage alloc] initWithImage:image]; visionImage.orientation = image.imageOrientation;
Jika Anda menggunakan CMSampleBuffer
, ikuti langkah-langkah berikut:
-
Tentukan orientasi data gambar yang terdapat dalam
CMSampleBuffer
.Untuk mendapatkan orientasi gambar:
Swift
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 } }
Objective-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; } }
- Buat objek
VisionImage
menggunakan Objek dan orientasiCMSampleBuffer
:Swift
let image = VisionImage(buffer: sampleBuffer) image.orientation = imageOrientation( deviceOrientation: UIDevice.current.orientation, cameraPosition: cameraPosition)
Objective-C
MLKVisionImage *image = [[MLKVisionImage alloc] initWithBuffer:sampleBuffer]; image.orientation = [self imageOrientationFromDeviceOrientation:UIDevice.currentDevice.orientation cameraPosition:cameraPosition];
3. Memproses gambar
Teruskan objek VisionImage
ke salah satu metode pemrosesan gambar Segmenter
. Anda dapat menggunakan metode process(image:)
asinkron atau metode results(in:)
sinkron.
Untuk melakukan segmentasi pada gambar selfie secara sinkron:
Swift
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.
Objective-C
NSError *error; MLKSegmentationMask *mask = [segmenter resultsInImage:image error:&error]; if (error != nil) { // Error. return; } // Success. Get a segmentation mask here.
Untuk melakukan segmentasi pada gambar selfie secara asinkron:
Swift
segmenter.process(image) { mask, error in guard error == nil else { // Error. return } // Success. Get a segmentation mask here.
Objective-C
[segmenter processImage:image completion:^(MLKSegmentationMask * _Nullable mask, NSError * _Nullable error) { if (error != nil) { // Error. return; } // Success. Get a segmentation mask here. }];
4. Dapatkan penyamaran segmentasi
Anda bisa mendapatkan hasil segmentasi sebagai berikut:
Swift
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 }
Objective-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); }
Untuk contoh lengkap tentang cara menggunakan hasil segmentasi, silakan lihat Contoh panduan memulai ML Kit.
Tips untuk meningkatkan performa
Kualitas hasil bergantung pada kualitas gambar input:
- Agar ML Kit mendapatkan hasil segmentasi yang akurat, gambar harus berukuran minimal 256x256 piksel.
- Jika Anda melakukan segmentasi selfie dalam aplikasi real-time, Anda mungkin juga ingin mempertimbangkan dimensi keseluruhan gambar input. Gambar yang lebih kecil dapat diproses lebih cepat, jadi untuk mengurangi latensi, ambil gambar dengan resolusi lebih rendah. Namun, perhatikan persyaratan resolusi di atas dan pastikan subjek menempati gambar sebanyak mungkin.
- Fokus gambar yang buruk juga dapat memengaruhi akurasi. Jika Anda tidak mendapatkan hasil yang dapat diterima, minta pengguna untuk mengambil ulang gambar.
Jika Anda ingin menggunakan segmentasi dalam aplikasi real-time, ikuti panduan berikut untuk mencapai kecepatan frame terbaik:
- Gunakan mode pengelompok
stream
. - Sebaiknya ambil gambar dengan resolusi yang lebih rendah. Namun, perhatikan juga persyaratan dimensi gambar API ini.
- Untuk memproses frame video, gunakan API sinkron
results(in:)
dari pembagi. Panggil metode ini dari fungsi captureOutput(_, didOutput:from:) dari AVCaptureVideoDataOutputSampleBufferDelegate untuk mendapatkan hasil dari frame video yang diberikan secara sinkron. Pertahankan setelan alwaysDiscardsLateVideoFrames dari AVCaptureVideoDataOutput sebagai benar untuk membatasi panggilan ke pemroses iklan. Jika frame video baru tersedia saat pemroses segmen sedang berjalan, frame tersebut akan dihapus. - Jika Anda menggunakan output dari segmener untuk menempatkan grafis pada gambar input, pertama-tama dapatkan hasilnya dari ML Kit, lalu render gambar dan tempatkan grafis dalam satu langkah. Dengan demikian, Anda hanya merender ke permukaan tampilan sekali untuk setiap frame input yang diproses. Lihat class previewOverlayView dan CameraViewController dalam contoh panduan memulai ML Kit untuk mengetahui contohnya.