Files
photobooth-app/22_REMOVE_GGML.md
T

112 lines
6.1 KiB
Markdown

Bạn hoàn toàn **có thể** xóa bỏ hoàn toàn mô hình AI cũ (Google ML Kit Selfie Segmentation) và chỉ sử dụng duy nhất mô hình **MiDaS** để vừa bóc tách đối tượng, vừa xử lý xóa phông theo chiều sâu. Việc này sẽ giúp bạn tối ưu hóa dung lượng ứng dụng (vì không phải gánh hai bộ thư viện AI song song) và đồng nhất luồng dữ liệu xử lý ảnh.
Tuy nhiên, trước khi thực hiện, bạn cần hiểu rõ cơ chế thay thế và cách triển khai logic này trong dự án.
---
## 🔍 Phân tích giải pháp: Dùng MiDaS thay thế hoàn toàn ML Kit
Mô hình MiDaS không trả về mặt nạ nhị phân (Đen/Trắng) như ML Kit, mà nó trả về một **Bản đồ chiều sâu (Depth Map)** liên tục dưới dạng các giá trị số thực từ `0.0` đến `1.0`.
* **Vùng tiêu cự (Đối tượng gần nhất):** Có giá trị tiệm cận về `0.0` (hoặc ngược lại tùy cấu hình mô hình).
* **Vùng hậu cảnh (Xa dần):** Giá trị tăng dần tuyến tính lên `1.0`.
Để vừa bóc tách người/vật (tính năng Thay nền), vừa tính toán độ mờ tăng tiến (tính năng Xóa nền), ta chỉ cần áp dụng một kỹ thuật toán học gọi là **Ngưỡng chiều sâu động (Dynamic Depth Thresholding)**.
---
## 🛠️ Kế hoạch Markdown triển khai luồng xử lý độc lập với MiDaS
### 📦 1. Gỡ bỏ ML Kit khỏi cấu hình (`app/build.gradle`)
Bạn xóa bỏ hoàn toàn dependency của Google ML Kit để giải phóng dung lượng bộ nhớ cài đặt:
```groovy
dependencies {
// ❌ XÓA HOÀN TOÀN dòng này:
// implementation 'com.google.mlkit:segmentation-selfie:16.0.0-beta4'
// 🟢 CHỈ GIỮ LẠI hoặc thêm thư viện chạy mô hình TFLite siêu nhẹ:
implementation 'org.tensorflow:tensorflow-lite:2.14.0'
}
```
---
## 💻 2. Thuật Toán Lõi: Tách Nền và Xóa Phông Đồng Thời Bằng MiDaS (`MainActivity.kt`)
Khi chỉ dùng MiDaS, luồng xử lý pixel tại hàm `processAdvancedBackgroundAi()` sẽ thay đổi để phục vụ cả hai mục đích: **Xác định biên vật thể để chèn nền****Tính độ xa để áp các lớp Blur**.
```kotlin
fun processAdvancedDepthAi(
capturedBitmap: Bitmap,
depthMap: Array<FloatArray>, // Ma trận 256x256 chứa khoảng cách thực tế từ MiDaS
bgBitmap: Bitmap?, // Hình nền mới nếu người dùng chọn thay nền
blurIntensity: Float
): Bitmap {
val w = capturedBitmap.width
val h = capturedBitmap.height
val outputBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888)
// 1. Tạo sẵn các tầng phông nền mờ phân cấp từ ảnh gốc (hoặc từ ảnh nền mới chèn vào)
val baseBg = bgBitmap ?: capturedBitmap
val blurStage1 = boxBlur(baseBg, (5 * blurIntensity).toInt().coerceAtLeast(1))
val blurStage2 = boxBlur(baseBg, (13 * blurIntensity).toInt().coerceAtLeast(1))
val blurStage3 = boxBlur(baseBg, (25 * blurIntensity).toInt().coerceAtLeast(1))
// 2. Vòng lặp duyệt pixel đồng bộ kích thước
for (y in 0 until h) {
for (x in 0 until w) {
// Ánh xạ tọa độ ảnh gốc sang ma trận 256x256 của AI MiDaS
val maskX = (x * 256 / w).coerceIn(0, 255)
val maskY = (y * 256 / h).coerceIn(0, 255)
// Lấy khoảng cách thực tế của pixel này (0.0 = Cực gần/Đối tượng, 1.0 = Cực xa)
val distance = depthMap[maskY][maskX]
val finalPixel = when {
// --- VÙNG TIÊU CỰ: ĐỐI TƯỢNG CHÍNH ---
distance < 0.25f -> {
// Nếu người dùng chọn THAY NỀN, giữ nguyên người nét.
// Nếu KHÔNG thay nền, vẫn giữ nguyên người nét trên nền gốc.
capturedBitmap.getPixel(x, y)
}
// --- VÙNG HẬU CẢNH: CHỌN LỚP BLUR THEO KHOẢNG CÁCH ---
distance >= 0.25f && distance < 0.5f -> blurStage1.getPixel(x, y)
distance >= 0.5f && distance < 0.75f -> blurStage2.getPixel(x, y)
else -> blurStage3.getPixel(x, y) // Xa vô cực, hiệu ứng Bokeh mịn màng
}
outputBitmap.setPixel(x, y, finalPixel)
}
}
// Thu hồi bộ nhớ các bitmap trung gian
blurStage1.recycle()
blurStage2.recycle()
blurStage3.recycle()
return outputBitmap
}
```
---
## 📊 3. Bảng so sánh dung lượng và hiệu năng sau khi tối ưu
| Chỉ số | Khi dùng Cả Hai (ML Kit + MiDaS giả lập) | Khi dùng Độc Lập (Chỉ dùng MiDaS thật) |
| --- | --- | --- |
| **Dung lượng App tăng thêm** | ~0 MB (Tận dụng thư viện Google Play Services có sẵn trên máy) | **+15 MB** (Dung lượng cố định của file `midas.tflite` trong assets) |
| **Độ chính xác vùng biên tóc/tai** | Trung bình khá (Dễ bị lẹm nếu ánh sáng yếu) | **Cao** (Biên độ mờ chuyển tiếp mịn màng theo khối chiều sâu 3D) |
| **Hiệu ứng xóa phông quang học** | Phẳng (Toàn bộ nền mờ như nhau) | **Thực tế** (Vật ở càng xa ống kính càng mờ rõ rệt) |
---
## 📅 4. Checklist Xác Minh Triển Khai (Verification Checklist)
* [ ] **Xóa sạch Cache cũ:** Chạy lệnh `./gradlew clean` trước khi build lại để đảm bảo các lớp thư viện cũ của ML Kit được gỡ bỏ hoàn toàn khỏi file APK/AAB đầu ra.
* [ ] **Kiểm thử tính năng Thay nền:** Chọn một ảnh nền mới, chụp thử xem đối tượng người có được bóc tách sạch sẽ và đặt lên phông nền mới dựa vào ngưỡng `distance < 0.25f` hay không.
* [ ] **Kiểm thử tăng giảm vuốt màn hình (Swipe):** Vuốt sang phải để tăng `blurIntensity` xem các vùng có khoảng cách xa (`distance > 0.75f`) có đạt độ nhòe sâu hơn các vùng cận hay không.