logo
hero image

Mengubah Background Foto dengan Vision Framework

Tutorial Person Segmentation pada Vision Framework.
20 May 2023 · 6 Minutes

Apa itu Vision?

Vision merupakan salah satu Framework dari Apple yang dapat kita gunakan untuk melakukan berbagai task terkait dengan Computer Vision, misalnya seperti mendeteksi wajah, mendeteksi teks dalam gambar, membaca barcode, dll.

Pada iOS 15 Apple menambahkan fitur baru dalam Framework Vision untuk melakukan Person Segmentation.

Apa itu Image Segmentation?

Person / Image Segmentation itu hampir sama seperti Object Detection, bedanya jika Object Detection akan mengembalikan hasil berupa bounding box suatu object, sedangkan Image Segmentation akan mengembalikan hasil pixel mask suatu object.

Object Detection vs Image SegmentationObject Detection vs Image Segmentation

Ada 2 macam Image Segmentation, yaitu:

1. Semantic Segmentation

Semantic Segmentation adalah proses untuk mendeteksi dan mengelompokkan objects berdasarkan kelas yang sama.

2. Instance Segmentation

Instance Segmentation adalah proses untuk mendeteksi suatu object tanpa mengelompokkannya.

Jadi jika kita melakukan Semantic Segmentation pada foto hewan di atas, maka hasilnya adalah 1 pixel mask yang berisi beberapa hewan. Sedangkan jika Instance Segmentation hasilnya adalah 4 pixel mask dari masing-masing hewan (seperti foto di atas).

Fitur Person Segmentation yang ada pada Framework Vision itu menggunakan Semantic Segmentation. Jadi, hasil yang dikembalikan adalah 1 pixel mask saja meskipun ada beberapa orang dalam satu foto.

Nah, pada artikel kali ini kita akan belajar bagaimana cara mengubah background foto menggunakan pada Framework Vision.


Download Starter Project

Pertama, Silakan download dulu starter project-nya di sini: https://github.com/alfinsyahruddin/BGChanger

Projectnya cukup sederhana, terdiri dari 2 halaman:

  1. Home Page: halaman utama untuk mengubah background foto.

  2. Output Page: halaman untuk menampilkan hasil dari Person Segmentation.

BGChangerBGChanger

Untuk mengikuti tutorial ini silakan siapkan iPhone fisik dengan versi iOS >= 15.0

Person Segmentation

Berikut adalah langkah-langkah untuk melakukan Person Segmentation:

  1. Membuat Request Person Segmentation

  2. Membuat Request Handler untuk Request tersebut

  3. Menjalankan Request

  4. Memproses hasil dari Request tersebut

1. Membuat Request

Silakan buka file "HomeViewModel.swift" kemudian import framework Vision.

HomeViewModel.swift
icon
1import SwiftUI
2import Combine
4import Vision

Kemudian tambahkan kode berikut pada class HomeViewModel :

HomeViewModel.swift
icon
1private let request = VNGeneratePersonSegmentationRequest()

di atas adalah kode untuk membuat instance dari Image Segmentation request. Request ini bisa digunakan berulang kali, jadi bisa kita gunakan untuk melakukan Image Segmentation dari frame-frame suatu video / live camera.

2. Membuat Request Handler

Sekarang, kita akan membuat Request Handler untuk Request yang telah kita buat.

Silakan tambahkan kode berikut di dalam method changeBackground :

HomeViewModel.swift
icon
1func changeBackground() {
3 guard let backgroundImage = backgroundImage.cgImage,
4 let foregroundImage = foregroundImage.cgImage
5 else {
6 print("Missing required images")
7 return
8 }
10
12 let requestHandler = VNImageRequestHandler(
13 cgImage: foregroundImage,
14 options: [:]
15 )
17}

Penjelasan kode:

  1. Pertama, kita ubah dulu tipe gambar kita dari UIImage ke CGImage, karena tipe gambar yang didukung oleh Vision adalah CGImage.

  2. Kemudian, kita buat Request Handler-nya yang berisi gambar yang ingin kita ubah background-nya.

3. Menjalankan Request

Kita akan menjalankan Request menggunakan Request Handler yang telah kita buat.

Tambahkan kode berikut di dalam method changeBackground :

HomeViewModel.swift
icon
1 do {
3 try requestHandler.perform([request])
4
6 guard let mask = request.results?.first else {
7 print("Error generating person segmentation mask.")
8 return
9 }
11
13 let foreground = CIImage(cgImage: foregroundImage)
14 let maskImage = CIImage(cvPixelBuffer: mask.pixelBuffer)
15 let background = CIImage(cgImage: backgroundImage)
17
18 // TODO: Blend Images
19 } catch {
20 print("Error processing person segmentation request")
21 }

Penjelasan kode:

  1. Method perform(_:) digunakan untuk menjalankan / memproses Request yang telah kita buat.

  2. Lalu kita dapatkan hasil dari proses Image Segmentation menggunakan request.results?.first

4. Memproses Hasil

Terakhir, kita akan memproses hasil dari Image Segmentation. Kita akan memasking gambar foreground agar backgroundnya menjadi transparan, kemudian kita gabungkan gambar yang telah di-masking tersebut dengan gambar background yang kita inginkan.

Tambahkan kode berikut di dalam method changeBackground :

HomeViewModel.swift
icon
1guard let output = blendImages(
2 background: CIImage(cgImage: backgroundImage),
3 foreground: CIImage(cgImage: foregroundImage),
4 mask: CIImage(cvPixelBuffer: mask.pixelBuffer)
5) else {
6 print("Error blending images")
7 return
8}
9
10if let result = convertImage(output) {
11 self.output = result
12 self.showOutput = true
13}

Penjelasan kode:

  1. Kita gabungkan antara foreground dan background menggunakan method blendImages, namun kita perlu ubah dulu tipe gambarnya menjadi CIImage karena kita akan menggunakan framework Core Image untuk blending-nya.

  2. Setelah kita dapat hasil dari proses blending, kita convert tipe gambarnya menjadi UIImage agar bisa ditampilkan di SwiftUI.

Berikut adalah implementasi dari method blendImages dan convertImage :

HomeViewModel.swift
icon
1private let context = CIContext()
2
3private func blendImages(
4 background: CIImage,
5 foreground: CIImage,
6 mask: CIImage
7) -> CIImage? {
8 let maskScaleX = foreground.extent.width / mask.extent.width
9 let maskScaleY = foreground.extent.height / mask.extent.height
10 let maskScaled = mask.transformed(
11 by: __CGAffineTransformMake(maskScaleX, 0, 0, maskScaleY, 0, 0)
12 )
13
14 let backgroundScaleX = (foreground.extent.width / background.extent.width)
15 let backgroundScaleY = (foreground.extent.height / background.extent.height)
16 let backgroundScaled = background.transformed(
17 by: __CGAffineTransformMake(backgroundScaleX, 0, 0, backgroundScaleY, 0, 0)
18 )
19
20 let blendFilter = CIFilter.blendWithMask()
21 blendFilter.inputImage = foreground
22 blendFilter.maskImage = maskScaled
23 blendFilter.backgroundImage = backgroundScaled
24
25 return blendFilter.outputImage
26}
27
28private func convertImage(_ image: CIImage) -> UIImage? {
29 guard let cgImage = context.createCGImage(image, from: image.extent) else {
30 return nil
31 }
32 return UIImage(cgImage: cgImage)
33}

dan jangan lupa import CIFilterBuiltins dari framework Core Image:

HomeViewModel.swift
icon
1import SwiftUI
2import Combine
3import Vision
5import CoreImage.CIFilterBuiltins

Lalu jalankan project kita menggunakan iPhone fisik (tidak bisa di Simulator), maka hasilnya akan seperti ini:

OutputOutput

Memilih Quality Level

Secara default, Segmentation Request yang kita buat itu menggunakan Quality Level accurate, berikut adalah beberapa Quality Level yang bisa kita gunakan:

  1. accurate: Jika kita ingin kualitas yang paling tinggi, Cocok untuk foto.

  2. balanced: Cocok untuk memproses video.

  3. fast: Cocok untuk memproses video streaming.

Jika kamu ingin mengatur Quality Level, caranya seperti ini:

icon
1request.qualityLevel = .accurate

Quality LevelQuality Level

Namun perlu diketahui bahwa semakin tinggi Quality Level-nya maka memory, frame size dan waktu yang dibutuhkan untuk memprosesnya juga akan semakin meningkat!

Quality Level Tarde-OffQuality Level Tarde-Off

What's Next?

Sekarang kita telah mengetahui bagaimana cara mengubah background foto menggunakan framework Vision, selanjutnya mungkin kamu bisa tambahkan fitur di project ini untuk mengubah background pada video secara real time, dll 😄

Selain Vision, kita juga bisa melakukan Person Segmentation menggunakan beberapa framework berikut:

  1. AVFoundation, melalui properti portraitEffectsMatte pada AVCapturePhoto

  2. ARKit, melalui properti segmentationBuffer pada ARFrame

  3. Core Image, menggunakan CIFilter.personSegmentation()

Oke mungkin itu saja yang bisa saya bagikan kali ini, kalau kamu merasa artikel ini bermanfaat silakan Like & Share artikel ini ke teman-teman kamu atau jika kamu punya pertanyaan, tulis aja di kolom komentar, Thank you! 😁 🙏


Referensi:

iOS Development
Swift
Vision
Artificial Intelligence

Written by :
Alfin Syahruddin
Developer · Stock Trader · Libertarian · Freethinker

Always open to new ideas 🕊️

Loading...

Related articles

Articles that you might want to read.

hero image
Object Detection pada iOS

Tutorial Object Detection menggunakan Create ML dan Vision Framework.

22 June 2023 · 10 Minutes
iOS Development
Swift
Vision
Create ML
Artificial Intelligence
hero image
Image Classification pada iOS

Tutorial Image Classification menggunakan Create ML dan Vision Framework.

18 June 2023 · 7 Minutes
iOS Development
Swift
Vision
Create ML
Artificial Intelligence
hero image
3 Pilar Framework Combine

Sebuah Reactive Framework dari Apple.

1 May 2022 · 8 Minutes
iOS Development
Swift
Combine
All rights reserved © Alfin Syahruddin · 2019
RSS Feed